Bug 376957 - Prevent data leaks from cross-site JSON loads (JavaScript literals), by making the global name bindings ReadOnly/DontDelete and making [] and {} use the global bindings. Still more that can be done here, but this covers a lot of the fix. r+a=brendan
git-svn-id: svn://10.0.0.236/trunk@240378 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
97e3ce1112
commit
680af8da29
@ -2672,7 +2672,9 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
named = OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
|
||||
OBJECT_TO_JSVAL(proto),
|
||||
NULL, NULL,
|
||||
(clasp->flags & JSCLASS_IS_ANONYMOUS)
|
||||
(clasp->flags &
|
||||
(JSCLASS_IS_ANONYMOUS |
|
||||
JSCLASS_FIXED_BINDING))
|
||||
? JSPROP_READONLY | JSPROP_PERMANENT
|
||||
: 0,
|
||||
NULL);
|
||||
@ -2683,7 +2685,10 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
ctor = proto;
|
||||
} else {
|
||||
/* Define the constructor function in obj's scope. */
|
||||
fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0);
|
||||
fun = js_DefineFunction(cx, obj, atom, constructor, nargs,
|
||||
(clasp->flags & JSCLASS_FIXED_BINDING)
|
||||
? JSPROP_READONLY | JSPROP_PERMANENT
|
||||
: 0);
|
||||
named = (fun != NULL);
|
||||
if (!fun)
|
||||
goto bad;
|
||||
|
||||
@ -1256,6 +1256,12 @@ struct JSExtendedClass {
|
||||
/* Indicates that JSClass.mark is a tracer with JSTraceOp type. */
|
||||
#define JSCLASS_MARK_IS_TRACE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3))
|
||||
|
||||
/*
|
||||
* Indicates that the class object defined on the object provided to
|
||||
* JS_InitClass should be readonly and permanent.
|
||||
*/
|
||||
#define JSCLASS_FIXED_BINDING (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4))
|
||||
|
||||
/*
|
||||
* ECMA-262 requires that most constructors used internally create objects
|
||||
* with "the original Foo.prototype value" as their [[Prototype]] (__proto__)
|
||||
|
||||
@ -494,7 +494,8 @@ array_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
|
||||
JSClass js_ArrayClass = {
|
||||
"Array",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Array) |
|
||||
JSCLASS_FIXED_BINDING,
|
||||
array_addProperty, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, array_convert, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
|
||||
@ -56,7 +56,8 @@
|
||||
|
||||
JSClass js_BooleanClass = {
|
||||
"Boolean",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean),
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean) |
|
||||
JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
|
||||
@ -483,7 +483,8 @@ msFromTime(jsdouble t)
|
||||
|
||||
JSClass js_DateClass = {
|
||||
js_Date_str,
|
||||
JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
|
||||
JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_HAS_CACHED_PROTO(JSProto_Date) |
|
||||
JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
|
||||
@ -6035,11 +6035,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
* but use a stack slot for t and avoid dup'ing and popping it via
|
||||
* the JSOP_NEWINIT and JSOP_INITELEM bytecodes.
|
||||
*/
|
||||
ale = js_IndexAtom(cx, CLASS_ATOM(cx, Array), &cg->atomList);
|
||||
if (!ale)
|
||||
return JS_FALSE;
|
||||
EMIT_INDEX_OP(JSOP_CALLNAME, ALE_INDEX(ale));
|
||||
if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0)
|
||||
if (js_Emit2(cx, cg, JSOP_NEWINIT, (jsbytecode) JSProto_Array) < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
pn2 = pn->pn_head;
|
||||
@ -6108,11 +6104,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
* but use a stack slot for t and avoid dup'ing and popping it via
|
||||
* the JSOP_NEWINIT and JSOP_INITELEM bytecodes.
|
||||
*/
|
||||
ale = js_IndexAtom(cx, CLASS_ATOM(cx, Object), &cg->atomList);
|
||||
if (!ale)
|
||||
return JS_FALSE;
|
||||
EMIT_INDEX_OP(JSOP_CALLNAME, ALE_INDEX(ale));
|
||||
if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0)
|
||||
if (js_Emit2(cx, cg, JSOP_NEWINIT, (jsbytecode) JSProto_Object) < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
pn2 = pn->pn_head;
|
||||
|
||||
@ -1409,7 +1409,8 @@ fun_reserveSlots(JSContext *cx, JSObject *obj)
|
||||
JS_FRIEND_DATA(JSClass) js_FunctionClass = {
|
||||
js_Function_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(2) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Function),
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Function) |
|
||||
JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
fun_getProperty, JS_PropertyStub,
|
||||
fun_enumerate, (JSResolveOp)fun_resolve,
|
||||
|
||||
@ -3478,8 +3478,6 @@ interrupt:
|
||||
BEGIN_CASE(JSOP_NEW)
|
||||
/* Get immediate argc and find the constructor function. */
|
||||
argc = GET_ARGC(pc);
|
||||
|
||||
do_new:
|
||||
SAVE_SP_AND_PC(fp);
|
||||
vp = sp - (2 + argc);
|
||||
JS_ASSERT(vp >= fp->spbase);
|
||||
@ -3547,7 +3545,7 @@ interrupt:
|
||||
BEGIN_CASE(JSOP_ELEMDEC)
|
||||
/*
|
||||
* Delay fetching of id until we have the object to ensure
|
||||
* the proper evaluation oder. See bug 372331.
|
||||
* the proper evaluation order. See bug 372331.
|
||||
*/
|
||||
id = 0;
|
||||
i = -2;
|
||||
@ -4690,6 +4688,7 @@ interrupt:
|
||||
ok = ComputeGlobalThis(cx, sp); \
|
||||
if (!ok) \
|
||||
goto out; \
|
||||
JS_ASSERT(!JSVAL_IS_NULL(sp[-1]) && !JSVAL_IS_VOID(sp[-1])); \
|
||||
JS_END_MACRO
|
||||
|
||||
BEGIN_CASE(JSOP_GLOBALTHIS)
|
||||
@ -5292,9 +5291,16 @@ interrupt:
|
||||
#endif /* JS_HAS_GETTER_SETTER */
|
||||
|
||||
BEGIN_CASE(JSOP_NEWINIT)
|
||||
argc = 0;
|
||||
i = GET_INT8(pc);
|
||||
JS_ASSERT(i == JSProto_Array || i == JSProto_Object);
|
||||
obj = (i == JSProto_Array)
|
||||
? js_NewArrayObject(cx, 0, NULL)
|
||||
: js_NewObject(cx, &js_ObjectClass, NULL, NULL);
|
||||
if (!obj)
|
||||
goto out;
|
||||
PUSH_OPND(OBJECT_TO_JSVAL(obj));
|
||||
fp->sharpDepth++;
|
||||
goto do_new;
|
||||
END_CASE(JSOP_NEWINIT)
|
||||
|
||||
BEGIN_CASE(JSOP_ENDINIT)
|
||||
if (--fp->sharpDepth == 0)
|
||||
|
||||
@ -119,7 +119,7 @@ js_CloseNativeIterator(JSContext *cx, JSObject *iterobj)
|
||||
JSClass js_IteratorClass = {
|
||||
"Iterator",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(2) | /* slots for state and flags */
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator),
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) | JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
|
||||
@ -506,7 +506,8 @@ js_InitMathClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObject *Math;
|
||||
|
||||
Math = JS_DefineObject(cx, obj, js_Math_str, &js_MathClass, NULL, 0);
|
||||
Math = JS_DefineObject(cx, obj, js_Math_str, &js_MathClass, NULL,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
if (!Math)
|
||||
return NULL;
|
||||
if (!JS_DefineFunctions(cx, Math, math_static_methods))
|
||||
|
||||
@ -157,7 +157,8 @@ static JSFunctionSpec number_functions[] = {
|
||||
|
||||
JSClass js_NumberClass = {
|
||||
js_Number_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Number),
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Number) |
|
||||
JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
|
||||
@ -114,7 +114,7 @@ JS_FRIEND_DATA(JSObjectOps) js_ObjectOps = {
|
||||
|
||||
JSClass js_ObjectClass = {
|
||||
js_Object_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Object) | JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
|
||||
@ -368,7 +368,6 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
goto print_int;
|
||||
|
||||
case JOF_INT8:
|
||||
JS_ASSERT(op == JSOP_INT8);
|
||||
i = GET_INT8(pc);
|
||||
goto print_int;
|
||||
|
||||
@ -4239,12 +4238,9 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
|
||||
case JSOP_NEWINIT:
|
||||
{
|
||||
JSBool isArray;
|
||||
i = GET_INT8(pc);
|
||||
JS_ASSERT(i == JSProto_Array || i == JSProto_Object);
|
||||
|
||||
LOCAL_ASSERT(ss->top >= 2);
|
||||
(void) PopOff(ss, op);
|
||||
lval = POP_STR();
|
||||
isArray = (*lval == 'A');
|
||||
todo = ss->sprinter.offset;
|
||||
#if JS_HAS_SHARP_VARS
|
||||
op = (JSOp)pc[len];
|
||||
@ -4252,12 +4248,12 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
pc += len;
|
||||
cs = &js_CodeSpec[op];
|
||||
len = cs->length;
|
||||
i = (jsint) GET_UINT16(pc);
|
||||
if (Sprint(&ss->sprinter, "#%u=", (unsigned) i) < 0)
|
||||
if (Sprint(&ss->sprinter, "#%u=",
|
||||
(unsigned) (jsint) GET_UINT16(pc)) < 0)
|
||||
return NULL;
|
||||
}
|
||||
#endif /* JS_HAS_SHARP_VARS */
|
||||
if (isArray) {
|
||||
if (i == JSProto_Array) {
|
||||
++ss->inArrayInit;
|
||||
if (SprintCString(&ss->sprinter, "[") < 0)
|
||||
return NULL;
|
||||
@ -4269,6 +4265,9 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
}
|
||||
|
||||
case JSOP_ENDINIT:
|
||||
{
|
||||
JSBool inArray;
|
||||
|
||||
op = JSOP_NOP; /* turn off parens */
|
||||
rval = POP_STR();
|
||||
sn = js_GetSrcNote(jp->script, pc);
|
||||
@ -4276,35 +4275,53 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
/* Skip any #n= prefix to find the opening bracket. */
|
||||
for (xval = rval; *xval != '[' && *xval != '{'; xval++)
|
||||
continue;
|
||||
if (*xval == '[')
|
||||
inArray = (*xval == '[');
|
||||
if (inArray)
|
||||
--ss->inArrayInit;
|
||||
todo = Sprint(&ss->sprinter, "%s%s%c",
|
||||
rval,
|
||||
(sn && SN_TYPE(sn) == SRC_CONTINUE) ? ", " : "",
|
||||
(*xval == '[') ? ']' : '}');
|
||||
inArray ? ']' : '}');
|
||||
break;
|
||||
}
|
||||
|
||||
case JSOP_INITPROP:
|
||||
{
|
||||
JSBool isFirst;
|
||||
|
||||
LOAD_ATOM(0);
|
||||
xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
|
||||
(jschar)
|
||||
(ATOM_IS_IDENTIFIER(atom) ? 0 : '\''));
|
||||
if (!xval)
|
||||
return NULL;
|
||||
isFirst = (ss->opcodes[ss->top - 2] == JSOP_NEWINIT);
|
||||
rval = POP_STR();
|
||||
lval = POP_STR();
|
||||
do_initprop:
|
||||
#ifdef OLD_GETTER_SETTER
|
||||
todo = Sprint(&ss->sprinter, "%s%s%s%s%s:%s",
|
||||
todo = Sprint(&ss->sprinter, "%s%s",
|
||||
lval,
|
||||
(lval[1] != '\0') ? ", " : "",
|
||||
xval,
|
||||
(lastop == JSOP_GETTER || lastop == JSOP_SETTER)
|
||||
? " " : "",
|
||||
(lastop == JSOP_GETTER) ? js_getter_str :
|
||||
(lastop == JSOP_SETTER) ? js_setter_str :
|
||||
"",
|
||||
rval);
|
||||
isFirst ? "" : ", ");
|
||||
}
|
||||
|
||||
do_initprop:
|
||||
/*
|
||||
* NB: From here onward we must not overwrite todo, which must
|
||||
* be the offset just before we print the [ or { which starts
|
||||
* this literal. This is important both for JSOP_INITPROP and
|
||||
* for JSOP_INITELEM (whose control flow can extend through
|
||||
* here via a goto).
|
||||
*/
|
||||
#ifdef OLD_GETTER_SETTER
|
||||
if (Sprint(&ss->sprinter, "%s%s%s%s%s:%s",
|
||||
xval,
|
||||
(lastop == JSOP_GETTER || lastop == JSOP_SETTER)
|
||||
? " " : "",
|
||||
(lastop == JSOP_GETTER) ? js_getter_str :
|
||||
(lastop == JSOP_SETTER) ? js_setter_str :
|
||||
"",
|
||||
rval) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (lastop == JSOP_GETTER || lastop == JSOP_SETTER) {
|
||||
if (!atom ||
|
||||
@ -4313,12 +4330,13 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
ATOM_IS_KEYWORD(atom) ||
|
||||
(ss->opcodes[ss->top+1] != JSOP_ANONFUNOBJ &&
|
||||
ss->opcodes[ss->top+1] != JSOP_NAMEDFUNOBJ)) {
|
||||
todo = Sprint(&ss->sprinter, "%s%s%s %s: %s", lval,
|
||||
(lval[1] != '\0') ? ", " : "", xval,
|
||||
(lastop == JSOP_GETTER) ? js_getter_str :
|
||||
(lastop == JSOP_SETTER) ? js_setter_str :
|
||||
"",
|
||||
rval);
|
||||
if (Sprint(&ss->sprinter, "%s %s: %s", xval,
|
||||
(lastop == JSOP_GETTER) ? js_getter_str :
|
||||
(lastop == JSOP_SETTER) ? js_setter_str :
|
||||
"",
|
||||
rval) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
const char *end = rval + strlen(rval);
|
||||
|
||||
@ -4328,29 +4346,30 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
LOCAL_ASSERT(rval[8] == ' ');
|
||||
rval += 8 + 1;
|
||||
LOCAL_ASSERT(*end ? *end == ')' : end[-1] == '}');
|
||||
todo = Sprint(&ss->sprinter, "%s%s%s %s%s%.*s",
|
||||
lval,
|
||||
(lval[1] != '\0') ? ", " : "",
|
||||
(lastop == JSOP_GETTER)
|
||||
? js_get_str : js_set_str,
|
||||
xval,
|
||||
(rval[0] != '(') ? " " : "",
|
||||
end - rval, rval);
|
||||
if (Sprint(&ss->sprinter, "%s %s%s%.*s",
|
||||
(lastop == JSOP_GETTER)
|
||||
? js_get_str : js_set_str,
|
||||
xval,
|
||||
(rval[0] != '(') ? " " : "",
|
||||
end - rval, rval) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
todo = Sprint(&ss->sprinter, "%s%s%s: %s",
|
||||
lval,
|
||||
(lval[1] != '\0') ? ", " : "",
|
||||
xval,
|
||||
rval);
|
||||
if (Sprint(&ss->sprinter, "%s: %s", xval, rval) < 0)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case JSOP_INITELEM:
|
||||
{
|
||||
JSBool isFirst;
|
||||
|
||||
/* Turn off most parens (all if there's only one initialiser). */
|
||||
LOCAL_ASSERT(pc + len < endpc);
|
||||
op = (GetStr(ss, ss->top - 3)[1] == '\0' &&
|
||||
isFirst = (ss->opcodes[ss->top - 3] == JSOP_NEWINIT);
|
||||
op = (isFirst &&
|
||||
GetStr(ss, ss->top - 2)[0] == '0' &&
|
||||
(JSOp) pc[len] == JSOP_ENDINIT)
|
||||
? JSOP_NOP
|
||||
@ -4362,15 +4381,21 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
xval = POP_STR();
|
||||
lval = POP_STR();
|
||||
sn = js_GetSrcNote(jp->script, pc);
|
||||
|
||||
/* NB: must not overwrite todo after this! */
|
||||
todo = Sprint(&ss->sprinter, "%s%s",
|
||||
lval,
|
||||
isFirst ? "" : ", ");
|
||||
if (todo < 0)
|
||||
break;
|
||||
if (sn && SN_TYPE(sn) == SRC_INITPROP) {
|
||||
atom = NULL;
|
||||
goto do_initprop;
|
||||
}
|
||||
todo = Sprint(&ss->sprinter, "%s%s%s",
|
||||
lval,
|
||||
(lval[1] != '\0' || *xval != '0') ? ", " : "",
|
||||
rval);
|
||||
if (SprintCString(&ss->sprinter, rval) < 0)
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
#if JS_HAS_SHARP_VARS
|
||||
case JSOP_DEFSHARP:
|
||||
|
||||
@ -120,7 +120,7 @@ typedef enum JSOpLength {
|
||||
#define JOF_PARENHEAD (1U<<21) /* opcode consumes value of expression in
|
||||
parenthesized statement head */
|
||||
#define JOF_INVOKE (1U<<22) /* JSOP_CALL, JSOP_NEW, JSOP_EVAL */
|
||||
#define JOF_TMPSLOT (1U<<23) /* interpreter uses extra temporray slot
|
||||
#define JOF_TMPSLOT (1U<<23) /* interpreter uses extra temporary slot
|
||||
to root intermediate objects */
|
||||
#define JOF_TMPSLOT_SHIFT 23
|
||||
|
||||
|
||||
@ -214,7 +214,7 @@ OPDEF(JSOP_SETVAR, 87, "setvar", NULL, 3, 1, 1, 3, JOF_QVAR |
|
||||
OPDEF(JSOP_UINT16, 88, "uint16", NULL, 3, 0, 1, 16, JOF_UINT16)
|
||||
|
||||
/* Object and array literal support. */
|
||||
OPDEF(JSOP_NEWINIT, 89, "newinit", NULL, 1, 2, 1, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_NEWINIT, 89, "newinit", NULL, 2, 0, 1, 19, JOF_INT8)
|
||||
OPDEF(JSOP_ENDINIT, 90, "endinit", NULL, 1, 0, 0, 19, JOF_BYTE)
|
||||
OPDEF(JSOP_INITPROP, 91, "initprop", NULL, 3, 1, 0, 3, JOF_ATOM|JOF_PROP|JOF_DETECTING)
|
||||
OPDEF(JSOP_INITELEM, 92, "initelem", NULL, 1, 2, 0, 3, JOF_BYTE |JOF_ELEM|JOF_DETECTING)
|
||||
|
||||
@ -3866,7 +3866,8 @@ regexp_trace(JSTracer *trc, JSObject *obj)
|
||||
JSClass js_RegExpClass = {
|
||||
js_RegExp_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1) |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_RegExp),
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_RegExp) |
|
||||
JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
regexp_getProperty, regexp_setProperty,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
|
||||
@ -597,7 +597,7 @@ str_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
||||
JSClass js_StringClass = {
|
||||
js_String_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_String),
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_String) | JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub, str_getProperty, JS_PropertyStub,
|
||||
str_enumerate, (JSResolveOp)str_resolve, JS_ConvertStub, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
|
||||
@ -202,7 +202,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
|
||||
* before deserialization of bytecode. If the saved version does not match
|
||||
* the current version, abort deserialization and invalidate the file.
|
||||
*/
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 16)
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 17)
|
||||
|
||||
/*
|
||||
* Library-private functions.
|
||||
|
||||
@ -237,7 +237,8 @@ namespace_equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
||||
JS_FRIEND_DATA(JSExtendedClass) js_NamespaceClass = {
|
||||
{ "Namespace",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Namespace),
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Namespace) |
|
||||
JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub, namespace_getProperty, NULL,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, namespace_finalize,
|
||||
NULL, NULL, NULL, NULL,
|
||||
@ -445,7 +446,8 @@ qname_equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
||||
JS_FRIEND_DATA(JSExtendedClass) js_QNameClass = {
|
||||
{ "QName",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_QName),
|
||||
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_QName) |
|
||||
JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub, qname_getProperty, NULL,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, qname_finalize,
|
||||
NULL, NULL, NULL, NULL,
|
||||
@ -5559,7 +5561,7 @@ xml_getObjectOps(JSContext *cx, JSClass *clasp)
|
||||
JS_FRIEND_DATA(JSClass) js_XMLClass = {
|
||||
js_XML_str,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_MARK_IS_TRACE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_XML),
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_XML) | JSCLASS_FIXED_BINDING,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, xml_finalize,
|
||||
xml_getObjectOps, NULL, NULL, NULL,
|
||||
@ -7676,7 +7678,8 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
|
||||
return NULL;
|
||||
|
||||
/* Define the XMLList function and give it the same prototype as XML. */
|
||||
fun = JS_DefineFunction(cx, obj, js_XMLList_str, XMLList, 1, 0);
|
||||
fun = JS_DefineFunction(cx, obj, js_XMLList_str, XMLList, 1,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
if (!js_SetClassPrototype(cx, fun->object, proto,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user