From 5cea8929e8a89ee3055cf68a3a8634b8b006b350 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Wed, 30 May 2012 15:05:59 -0500 Subject: [PATCH] Bug 753885 - Part 3: Expose XML global constructors only if JSOPTION_ALLOW_XML is set. r=Waldo. --- js/src/jit-test/tests/basic/bug753885-2.js | 24 ++++++++++ js/src/jsapi.cpp | 56 ++++++++++++++-------- js/src/jsapi.h | 5 +- js/src/vm/GlobalObject.cpp | 2 +- 4 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 js/src/jit-test/tests/basic/bug753885-2.js diff --git a/js/src/jit-test/tests/basic/bug753885-2.js b/js/src/jit-test/tests/basic/bug753885-2.js new file mode 100644 index 000000000000..1907029875c4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug753885-2.js @@ -0,0 +1,24 @@ +// XML-specific classes do not resolve unless JSOPTION_ALLOW_XML is enabled. + +assertEq(options().split(",").indexOf("allow_xml") >= 0, true); +options("allow_xml"); + +var xmlnames = ["XML", "XMLList", "isXMLName", "QName", "Namespace"]; +for (var name of xmlnames) + assertEq(name in this, false); + +var globals = Object.getOwnPropertyNames(this); +for (var name of xmlnames) + assertEq(globals.indexOf(name), -1); + +var g = newGlobal('new-compartment'); +for (var name of xmlnames) + assertEq(name in g, false); + +// Turn it back on and check that the XML classes magically appear. +options("allow_xml"); +assertEq("QName" in this, true); + +globals = Object.getOwnPropertyNames(this); +for (var name of xmlnames) + assertEq(globals.indexOf(name) >= 0, true); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index d3ae9a8e75f9..9d842d1b1213 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1929,18 +1929,18 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj_, jsid id, JSBool *resolved AssertNoGC(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj, id); - *resolved = JS_FALSE; + *resolved = false; rt = cx->runtime; if (!rt->hasContexts() || !JSID_IS_ATOM(id)) - return JS_TRUE; + return true; idstr = JSID_TO_STRING(id); /* Check whether we're resolving 'undefined', and define it if so. */ atom = rt->atomState.typeAtoms[JSTYPE_VOID]; if (idstr == atom) { - *resolved = JS_TRUE; + *resolved = true; return obj->defineProperty(cx, atom->asPropertyName(), UndefinedValue(), JS_PropertyStub, JS_StrictPropertyStub, JSPROP_PERMANENT | JSPROP_READONLY); @@ -1963,7 +1963,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj_, jsid id, JSBool *resolved JS_ASSERT(standard_class_names[i].clasp); atom = StdNameToPropertyName(cx, &standard_class_names[i]); if (!atom) - return JS_FALSE; + return false; if (idstr == atom) { stdnm = &standard_class_names[i]; break; @@ -1980,7 +1980,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj_, jsid id, JSBool *resolved JS_ASSERT(object_prototype_names[i].clasp); atom = StdNameToPropertyName(cx, &object_prototype_names[i]); if (!atom) - return JS_FALSE; + return false; if (idstr == atom) { stdnm = &object_prototype_names[i]; break; @@ -1996,28 +1996,34 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj_, jsid id, JSBool *resolved */ JS_ASSERT(obj->isGlobal()); if (stdnm->clasp->flags & JSCLASS_IS_ANONYMOUS) - return JS_TRUE; + return true; if (IsStandardClassResolved(obj, stdnm->clasp)) - return JS_TRUE; + return true; + +#if JS_HAS_XML_SUPPORT + if ((stdnm->init == js_InitXMLClass || + stdnm->init == js_InitNamespaceClass || + stdnm->init == js_InitQNameClass) && + !VersionHasAllowXML(cx->findVersion())) + { + return true; + } +#endif if (!stdnm->init(cx, obj)) - return JS_FALSE; - *resolved = JS_TRUE; + return false; + *resolved = true; } - return JS_TRUE; + return true; } JS_PUBLIC_API(JSBool) JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj_) { - JSRuntime *rt; - unsigned i; - AssertNoGC(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj_); - rt = cx->runtime; RootedObject obj(cx, obj_); @@ -2025,24 +2031,32 @@ JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj_) * Check whether we need to bind 'undefined' and define it if so. * Since ES5 15.1.1.3 undefined can't be deleted. */ - PropertyName *name = rt->atomState.typeAtoms[JSTYPE_VOID]; + PropertyName *name = cx->runtime->atomState.typeAtoms[JSTYPE_VOID]; if (!obj->nativeContains(cx, NameToId(name)) && !obj->defineProperty(cx, name, UndefinedValue(), JS_PropertyStub, JS_StrictPropertyStub, JSPROP_PERMANENT | JSPROP_READONLY)) { - return JS_FALSE; + return false; } /* Initialize any classes that have not been initialized yet. */ - for (i = 0; standard_class_atoms[i].init; i++) { - if (!js::IsStandardClassResolved(obj, standard_class_atoms[i].clasp) && - !standard_class_atoms[i].init(cx, obj)) + for (unsigned i = 0; standard_class_atoms[i].init; i++) { + const JSStdName &stdnm = standard_class_atoms[i]; + if (!js::IsStandardClassResolved(obj, stdnm.clasp) && +#if JS_HAS_XML_SUPPORT + ((stdnm.init != js_InitXMLClass && + stdnm.init != js_InitNamespaceClass && + stdnm.init != js_InitQNameClass) || + VersionHasAllowXML(cx->findVersion())) +#endif + ) { - return JS_FALSE; + if (!stdnm.init(cx, obj)) + return false; } } - return JS_TRUE; + return true; } static JSIdArray * diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 769520d20551..5e83f235aa06 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2730,7 +2730,10 @@ JS_StringToVersion(const char *string); option supported for the XUL preprocessor and kindred beasts. */ -#define JSOPTION_ALLOW_XML JS_BIT(6) /* enable E4X syntax (deprecated) */ +#define JSOPTION_ALLOW_XML JS_BIT(6) /* enable E4X syntax (deprecated) + and define the E4X-related + globals: XML, XMLList, + Namespace, etc. */ #define JSOPTION_MOAR_XML JS_BIT(7) /* enable E4X even in versions that don't normally get it; parse as a token, diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 14a9d25c5f5f..184e6e442b6a 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -282,7 +282,7 @@ GlobalObject::initStandardClasses(JSContext *cx, Handle global) js_InitStringClass(cx, global) && js_InitTypedArrayClasses(cx, global) && #if JS_HAS_XML_SUPPORT - js_InitXMLClasses(cx, global) && + (!VersionHasAllowXML(cx->findVersion()) || js_InitXMLClasses(cx, global)) && #endif #if JS_HAS_GENERATORS js_InitIteratorClasses(cx, global) &&