Bug 753542 - Add prefs to enable/disable E4X (javascript.options.xml.content and .chrome). r=bsmedberg, sr=jst.
authorJason Orendorff <jorendorff@mozilla.com>
Wed, 06 Jun 2012 21:52:14 -0500
changeset 96028 ce0c716baefdd91fa93d4c3b5b36b2d9f81f0440
parent 96027 0ac60eea3e4a40f18142fa2636bc1c9c0e3c74ef
child 96029 34476c720f8fa8624cf2100d1e6fa5aae16d301e
push id22869
push useremorley@mozilla.com
push dateThu, 07 Jun 2012 09:35:19 +0000
treeherdermozilla-central@3933384d8315 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, jst
bugs753542
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 753542 - Add prefs to enable/disable E4X (javascript.options.xml.content and .chrome). r=bsmedberg, sr=jst.
content/base/src/nsFrameMessageManager.cpp
dom/base/nsJSEnvironment.cpp
dom/workers/RuntimeService.cpp
js/jsd/jsd_high.c
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/src/XPCComponents.cpp
modules/libpref/src/init/all.js
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -16,21 +16,24 @@
 #include "nsIJSContextStack.h"
 #include "nsIXULRuntime.h"
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 #include "nsIProtocolHandler.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIJSRuntimeService.h"
 #include "xpcpublic.h"
+#include "mozilla/Preferences.h"
 
 #ifdef ANDROID
 #include <android/log.h>
 #endif
 
+using namespace mozilla;
+
 static bool
 IsChromeProcess()
 {
   nsCOMPtr<nsIXULRuntime> rt = do_GetService("@mozilla.org/xre/runtime;1");
   if (!rt)
     return true;
 
   PRUint32 type;
@@ -826,19 +829,20 @@ nsFrameScriptExecutor::InitTabChildGloba
 
   JSContext* cx = JS_NewContext(rt, 8192);
   NS_ENSURE_TRUE(cx, false);
 
   mCx = cx;
 
   nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
 
+  bool allowXML = Preferences::GetBool("javascript.options.xml.chrome");
   JS_SetOptions(cx, JS_GetOptions(cx) |
                     JSOPTION_PRIVATE_IS_NSISUPPORTS |
-                    JSOPTION_ALLOW_XML);
+                    (allowXML ? JSOPTION_ALLOW_XML : 0));
   JS_SetVersion(cx, JSVERSION_LATEST);
   JS_SetErrorReporter(cx, ContentScriptErrorReporter);
 
   xpc_LocalizeContext(cx);
 
   JSAutoRequest ar(cx);
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
   const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -937,26 +937,30 @@ nsJSContext::JSOptionChangedCallback(con
   bool useMethodJIT = Preferences::GetBool(chromeWindow || !contentWindow ?
                                                js_methodjit_chrome_str :
                                                js_methodjit_content_str);
   bool usePCCounts = Preferences::GetBool(chromeWindow || !contentWindow ?
                                             js_pccounts_chrome_str :
                                             js_pccounts_content_str);
   bool useMethodJITAlways = Preferences::GetBool(js_methodjit_always_str);
   bool useTypeInference = !chromeWindow && contentWindow && Preferences::GetBool(js_typeinfer_str);
+  bool useXML = Preferences::GetBool(chromeWindow || !contentWindow ?
+                                     "javascript.options.xml.chrome" :
+                                     "javascript.options.xml.content");
   bool useHardening = Preferences::GetBool(js_jit_hardening_str);
   nsCOMPtr<nsIXULRuntime> xr = do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
   if (xr) {
     bool safeMode = false;
     xr->GetInSafeMode(&safeMode);
     if (safeMode) {
       useMethodJIT = false;
       usePCCounts = false;
       useTypeInference = false;
       useMethodJITAlways = true;
+      useXML = false;
       useHardening = false;
     }
   }
 
   if (useMethodJIT)
     newDefaultJSOptions |= JSOPTION_METHODJIT;
   else
     newDefaultJSOptions &= ~JSOPTION_METHODJIT;
@@ -971,16 +975,21 @@ nsJSContext::JSOptionChangedCallback(con
   else
     newDefaultJSOptions &= ~JSOPTION_METHODJIT_ALWAYS;
 
   if (useTypeInference)
     newDefaultJSOptions |= JSOPTION_TYPE_INFERENCE;
   else
     newDefaultJSOptions &= ~JSOPTION_TYPE_INFERENCE;
 
+  if (useXML)
+    newDefaultJSOptions |= JSOPTION_ALLOW_XML;
+  else
+    newDefaultJSOptions &= ~JSOPTION_ALLOW_XML;
+
 #ifdef DEBUG
   // In debug builds, warnings are enabled in chrome context if
   // javascript.options.strict.debug is true
   bool strictDebug = Preferences::GetBool(js_strict_debug_option_str);
   if (strictDebug && (newDefaultJSOptions & JSOPTION_STRICT) == 0) {
     if (chromeWindow || !contentWindow)
       newDefaultJSOptions |= JSOPTION_STRICT;
   }
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -142,16 +142,17 @@ PR_STATIC_ASSERT(NS_ARRAY_LENGTH(gString
 
 enum {
   PREF_strict = 0,
   PREF_werror,
   PREF_relimit,
   PREF_methodjit,
   PREF_methodjit_always,
   PREF_typeinference,
+  PREF_allow_xml,
   PREF_jit_hardening,
   PREF_mem_max,
 
 #ifdef JS_GC_ZEAL
   PREF_gczeal,
 #endif
 
   PREF_COUNT
@@ -161,16 +162,17 @@ enum {
 
 const char* gPrefsToWatch[] = {
   JS_OPTIONS_DOT_STR "strict",
   JS_OPTIONS_DOT_STR "werror",
   JS_OPTIONS_DOT_STR "relimit",
   JS_OPTIONS_DOT_STR "methodjit.content",
   JS_OPTIONS_DOT_STR "methodjit_always",
   JS_OPTIONS_DOT_STR "typeinference",
+  JS_OPTIONS_DOT_STR "allow_xml",
   JS_OPTIONS_DOT_STR "jit_hardening",
   JS_OPTIONS_DOT_STR "mem.max"
 
 #ifdef JS_GC_ZEAL
   , PREF_WORKERS_GCZEAL
 #endif
 };
 
@@ -209,17 +211,19 @@ PrefCallback(const char* aPrefName, void
       newOptions |= JSOPTION_METHODJIT;
     }
     if (Preferences::GetBool(gPrefsToWatch[PREF_methodjit_always])) {
       newOptions |= JSOPTION_METHODJIT_ALWAYS;
     }
     if (Preferences::GetBool(gPrefsToWatch[PREF_typeinference])) {
       newOptions |= JSOPTION_TYPE_INFERENCE;
     }
-    newOptions |= JSOPTION_ALLOW_XML;
+    if (Preferences::GetBool(gPrefsToWatch[PREF_allow_xml])) {
+      newOptions |= JSOPTION_ALLOW_XML;
+    }
 
     RuntimeService::SetDefaultJSContextOptions(newOptions);
     rts->UpdateAllWorkerJSContextOptions();
   }
 #ifdef JS_GC_ZEAL
   else if (!strcmp(aPrefName, gPrefsToWatch[PREF_gczeal])) {
     PRInt32 gczeal = Preferences::GetInt(gPrefsToWatch[PREF_gczeal]);
     RuntimeService::SetDefaultGCZeal(PRUint8(clamped(gczeal, 0, 3)));
--- a/js/jsd/jsd_high.c
+++ b/js/jsd/jsd_high.c
@@ -101,17 +101,17 @@ static JSDContext*
     if( ! jsd_InitScriptManager(jsdc) )
         goto label_newJSDContext_failure;
 
     jsdc->dumbContext = JS_NewContext(jsdc->jsrt, 256);
     if( ! jsdc->dumbContext )
         goto label_newJSDContext_failure;
 
     JS_BeginRequest(jsdc->dumbContext);
-    JS_SetOptions(jsdc->dumbContext, JS_GetOptions(jsdc->dumbContext) | JSOPTION_ALLOW_XML);
+    JS_SetOptions(jsdc->dumbContext, JS_GetOptions(jsdc->dumbContext));
 
     jsdc->glob = JS_NewCompartmentAndGlobalObject(jsdc->dumbContext, &global_class, NULL);
 
     if( ! jsdc->glob )
         goto label_newJSDContext_failure;
 
     call = JS_EnterCrossCompartmentCall(jsdc->dumbContext, jsdc->glob);
     if( ! call )
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -54,16 +54,17 @@
 #endif
 #include "xpcprivate.h"
 #include "xpcpublic.h"
 #include "nsIResProtocolHandler.h"
 
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/scache/StartupCacheUtils.h"
 #include "mozilla/Omnijar.h"
+#include "mozilla/Preferences.h"
 
 #include "jsdbgapi.h"
 
 #include "mozilla/FunctionTimer.h"
 
 using namespace mozilla;
 using namespace mozilla::scache;
 
@@ -397,18 +398,20 @@ mozJSComponentLoader::ReallyInit()
     if (NS_FAILED(rv))
         return rv;
 
     // Create our compilation context.
     mContext = JS_NewContext(mRuntime, 256);
     if (!mContext)
         return NS_ERROR_OUT_OF_MEMORY;
 
-    uint32_t options = JS_GetOptions(mContext);
-    JS_SetOptions(mContext, options | JSOPTION_ALLOW_XML | JSOPTION_MOAR_XML);
+    if (Preferences::GetBool("javascript.options.xml.chrome")) {
+        uint32_t options = JS_GetOptions(mContext);
+        JS_SetOptions(mContext, options | JSOPTION_ALLOW_XML | JSOPTION_MOAR_XML);
+    }
 
     // Always use the latest js version
     JS_SetVersion(mContext, JSVERSION_LATEST);
 
     nsCOMPtr<nsIScriptSecurityManager> secman =
         do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
     if (!secman)
         return NS_ERROR_FAILURE;
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -23,16 +23,17 @@
 #include "nsNullPrincipal.h"
 #include "nsJSUtils.h"
 #include "mozJSComponentLoader.h"
 #include "nsContentUtils.h"
 #include "jsgc.h"
 #include "jsfriendapi.h"
 #include "AccessCheck.h"
 #include "mozilla/dom/BindingUtils.h"
+#include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace js;
 using namespace xpc;
 
 using mozilla::dom::DestroyProtoOrIfaceCache;
 
 /***************************************************************************/
@@ -3463,17 +3464,17 @@ nsXPCComponents_utils_Sandbox::CallOrCon
     *_retval = true;
 
     return rv;
 }
 
 class ContextHolder : public nsISupports
 {
 public:
-    ContextHolder(JSContext *aOuterCx, JSObject *aSandbox);
+    ContextHolder(JSContext *aOuterCx, JSObject *aSandbox, bool isChrome);
     virtual ~ContextHolder();
 
     JSContext * GetJSContext()
     {
         return mJSContext;
     }
 
     NS_DECL_ISUPPORTS
@@ -3482,27 +3483,33 @@ private:
     static JSBool ContextHolderOperationCallback(JSContext *cx);
 
     JSContext* mJSContext;
     JSContext* mOrigCx;
 };
 
 NS_IMPL_ISUPPORTS0(ContextHolder)
 
-ContextHolder::ContextHolder(JSContext *aOuterCx, JSObject *aSandbox)
+ContextHolder::ContextHolder(JSContext *aOuterCx,
+                             JSObject *aSandbox,
+                             bool isChrome)
     : mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024)),
       mOrigCx(aOuterCx)
 {
     if (mJSContext) {
+        bool allowXML = Preferences::GetBool(isChrome ?
+                                             "javascript.options.xml.chrome" :
+                                             "javascript.options.xml.content");
+
         JSAutoRequest ar(mJSContext);
         JS_SetOptions(mJSContext,
                       JS_GetOptions(mJSContext) |
                       JSOPTION_DONT_REPORT_UNCAUGHT |
                       JSOPTION_PRIVATE_IS_NSISUPPORTS |
-                      JSOPTION_ALLOW_XML);
+                      (allowXML ? JSOPTION_ALLOW_XML : 0));
         JS_SetGlobalObject(mJSContext, aSandbox);
         JS_SetContextPrivate(mJSContext, this);
         JS_SetOperationCallback(mJSContext, ContextHolderOperationCallback);
     }
 }
 
 ContextHolder::~ContextHolder()
 {
@@ -3640,17 +3647,20 @@ xpc_EvalInSandbox(JSContext *cx, JSObjec
         JSAutoRequest req(cx);
 
         callingScope = JS_GetGlobalForScopeChain(cx);
         if (!callingScope) {
             return NS_ERROR_FAILURE;
         }
     }
 
-    nsRefPtr<ContextHolder> sandcx = new ContextHolder(cx, sandbox);
+    bool isChrome;
+    nsresult rv = XPCWrapper::GetSecurityManager()->IsSystemPrincipal(prin, &isChrome);
+    NS_ENSURE_SUCCESS(rv, rv);
+    nsRefPtr<ContextHolder> sandcx = new ContextHolder(cx, sandbox, isChrome);
     if (!sandcx || !sandcx->GetJSContext()) {
         JS_ReportError(cx, "Can't prepare context for evalInSandbox");
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     if (jsVersion != JSVERSION_DEFAULT)
         JS_SetVersion(sandcx->GetJSContext(), jsVersion);
 
@@ -3659,17 +3669,17 @@ xpc_EvalInSandbox(JSContext *cx, JSObjec
     if (data && (stack = data->GetJSContextStack())) {
         if (!stack->Push(sandcx->GetJSContext())) {
             JS_ReportError(cx,
                            "Unable to initialize XPConnect with the sandbox context");
             return NS_ERROR_FAILURE;
         }
     }
 
-    nsresult rv = NS_OK;
+    rv = NS_OK;
 
     {
         JSAutoRequest req(sandcx->GetJSContext());
         JSAutoEnterCompartment ac;
 
         if (!ac.enter(sandcx->GetJSContext(), sandbox)) {
             if (stack)
                 unused << stack->Pop();
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -653,16 +653,18 @@ pref("javascript.options.strict",       
 pref("javascript.options.strict.debug",     true);
 #endif
 pref("javascript.options.relimit",          true);
 pref("javascript.options.methodjit.content", true);
 pref("javascript.options.methodjit.chrome",  true);
 pref("javascript.options.pccounts.content", false);
 pref("javascript.options.pccounts.chrome",  false);
 pref("javascript.options.methodjit_always", false);
+pref("javascript.options.xml.content", true);
+pref("javascript.options.xml.chrome", true);
 pref("javascript.options.jit_hardening", true);
 pref("javascript.options.typeinference", true);
 // This preference limits the memory usage of javascript.
 // If you want to change these values for your device,
 // please find Bug 417052 comment 17 and Bug 456721
 // Comment 32 and Bug 613551.
 pref("javascript.options.mem.high_water_mark", 128);
 pref("javascript.options.mem.max", -1);