Bug 658909 - Use JS_{,Strict}PropertyOp instead of null when defining value props in nsDOMClassInfo. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Sat, 16 Mar 2013 22:58:14 -0700
changeset 125055 682ad22f239f7771fdb5f9fe713d8a99c960a158
parent 125054 d4253db9e56065538c084b95ab87405172af85a6
child 125056 94014e4d1ab51a92c39f58fb6899c5f55900eb8f
push id24762
push userbobbyholley@gmail.com
push dateSun, 17 Mar 2013 05:58:40 +0000
treeherdermozilla-inbound@3a5f73a4f816 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs658909
milestone22.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 658909 - Use JS_{,Strict}PropertyOp instead of null when defining value props in nsDOMClassInfo. r=mrbkap Using JSPropertyOp means a null shape getter, whereas null means that the shape uses the class getter. This means that stuff like window.top, which is defined as a non-configurable |own| property in nsDOMClassInfo, was getting set up with XPC_WN_Helper_GetProperty as its get operation. But this confused SandboxProxyHandler, which explicitly avoids rebinding class getters/setters, which in turn meant that our sandboxPrototype feature was relying on the crazy prototype-climbing behavior of GetWrappedNativeOfJSObject to make stuff like |this.top| work. We're removing this behavior, so we need to fix nsDOMClassInfo here. Here are some DefineProperty cases that I left with null getters/setters: * nsDOMClassInfo::ResolveConstructor * The child window stuff at the bottom of nsWindowSH::NewResolve * Named item resolution in nsNamedArraySH::NewResolve * document.all stuff (scary!) * nsHTMLDocumentSH::NewResolve * nsHTMLFormElementSH::NewResolve * nsStorage2SH::NewResolve
dom/base/nsDOMClassInfo.cpp
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -3191,18 +3191,18 @@ nsDOMClassInfo::ResolveConstructor(JSCon
   }
 
   if (!JSVAL_IS_PRIMITIVE(val)) {
     // If val is not an (non-null) object there either is no
     // constructor for this class, or someone messed with
     // window.classname, just fall through and let the JS engine
     // return the Object constructor.
 
-    if (!::JS_DefinePropertyById(cx, obj, sConstructor_id, val, nullptr, nullptr,
-                                 JSPROP_ENUMERATE)) {
+    if (!::JS_DefinePropertyById(cx, obj, sConstructor_id, val, JS_PropertyStub,
+                                 JS_StrictPropertyStub, JSPROP_ENUMERATE)) {
       return NS_ERROR_UNEXPECTED;
     }
 
     *objp = obj;
   }
 
   return NS_OK;
 }
@@ -3752,17 +3752,17 @@ nsWindowSH::GlobalScopePolluterNewResolv
   if (result) {
     jsval v;
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     nsresult rv = WrapNative(cx, obj, result, cache, true, &v,
                              getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, JS_FALSE);
 
     if (!JS_WrapValue(cx, &v) ||
-        !JS_DefinePropertyById(cx, obj, id, v, nullptr, nullptr, 0)) {
+        !JS_DefinePropertyById(cx, obj, id, v, JS_PropertyStub, JS_StrictPropertyStub, 0)) {
       return JS_FALSE;
     }
 
     objp.set(obj);
   }
 
   return JS_TRUE;
 }
@@ -4094,17 +4094,18 @@ DefineInterfaceConstants(JSContext *cx, 
       {
 #ifdef DEBUG
         NS_ERROR("Non-numeric constant found in interface.");
 #endif
         continue;
       }
     }
 
-    if (!::JS_DefineProperty(cx, obj, c->GetName(), v, nullptr, nullptr,
+    if (!::JS_DefineProperty(cx, obj, c->GetName(), v,
+                             JS_PropertyStub, JS_StrictPropertyStub,
                              JSPROP_ENUMERATE | JSPROP_READONLY |
                              JSPROP_PERMANENT)) {
       return NS_ERROR_UNEXPECTED;
     }
   }
 
   return NS_OK;
 }
@@ -4203,17 +4204,18 @@ IDBConstantGetter(JSContext *cx, JSHandl
   }
 
   // Redefine property to remove getter
   NS_ConvertASCIItoUTF16 valStr(c.value);
   jsval value;
   if (!xpc::StringToJsval(cx, valStr, &value)) {
     return JS_FALSE;
   }
-  if (!::JS_DefineProperty(cx, obj, c.name, value, nullptr, nullptr,
+  if (!::JS_DefineProperty(cx, obj, c.name, value,
+                           JS_PropertyStub, JS_StrictPropertyStub,
                            JSPROP_ENUMERATE)) {
     return JS_FALSE;
   }
 
   // Return value
   vp.set(value);
   return JS_TRUE;
 }
@@ -4237,17 +4239,17 @@ DefineIDBInterfaceConstants(JSContext *c
 
   for (int8_t i = 0; i < (int8_t)mozilla::ArrayLength(sIDBConstants); ++i) {
     const IDBConstant& c = sIDBConstants[i];
     if (c.interface != interface) {
       continue;
     }
 
     if (!JS_DefineProperty(cx, obj, c.name, JSVAL_VOID,
-                           IDBConstantGetter, nullptr,
+                           IDBConstantGetter, JS_StrictPropertyStub,
                            JSPROP_ENUMERATE)) {
       return NS_ERROR_UNEXPECTED;
     }
   }
 
   return NS_OK;
 }
 
@@ -4285,18 +4287,18 @@ public:
                        bool *_retval);
 
   nsresult Install(JSContext *cx, JSObject *target, jsval thisAsVal)
   {
     // The 'attrs' argument used to be JSPROP_PERMANENT. See bug 628612.
     JSBool ok = JS_WrapValue(cx, &thisAsVal) &&
       ::JS_DefineUCProperty(cx, target,
                             reinterpret_cast<const jschar *>(mClassName),
-                            NS_strlen(mClassName), thisAsVal, nullptr,
-                            nullptr, 0);
+                            NS_strlen(mClassName), thisAsVal, JS_PropertyStub,
+                            JS_StrictPropertyStub, 0);
 
     return ok ? NS_OK : NS_ERROR_UNEXPECTED;
   }
 
   nsresult ResolveInterfaceConstants(JSContext *cx, JSObject *obj);
 
 private:
   const nsGlobalNameStruct *GetNameStruct()
@@ -4894,17 +4896,18 @@ ResolvePrototype(nsIXPConnect *aXPConnec
   }
 
   v = OBJECT_TO_JSVAL(dot_prototype);
 
   JSAutoCompartment ac(cx, class_obj);
 
   // Per ECMA, the prototype property is {DontEnum, DontDelete, ReadOnly}
   if (!JS_WrapValue(cx, &v) ||
-      !JS_DefineProperty(cx, class_obj, "prototype", v, nullptr, nullptr,
+      !JS_DefineProperty(cx, class_obj, "prototype", v,
+                         JS_PropertyStub, JS_StrictPropertyStub,
                          JSPROP_PERMANENT | JSPROP_READONLY)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   *did_resolve = true;
 
   return NS_OK;
 }
@@ -5008,18 +5011,18 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
           return NS_ERROR_FAILURE;
         }
 
         if (defineOnXray) {
           // This really should be handled by the Xray for the window.
           ac.destroy();
           if (!JS_WrapObject(cx, &interfaceObject) ||
               !JS_DefinePropertyById(cx, obj, id,
-                                     JS::ObjectValue(*interfaceObject), nullptr,
-                                     nullptr, 0)) {
+                                     JS::ObjectValue(*interfaceObject), JS_PropertyStub,
+                                     JS_StrictPropertyStub, 0)) {
             return NS_ERROR_FAILURE;
           }
         }
 
         *did_resolve = true;
 
         return NS_OK;
       }
@@ -5193,17 +5196,18 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
     }
 
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (!JS_WrapValue(cx, &prop_val)) {
       return NS_ERROR_UNEXPECTED;
     }
 
-    JSBool ok = ::JS_DefinePropertyById(cx, obj, id, prop_val, nullptr, nullptr,
+    JSBool ok = ::JS_DefinePropertyById(cx, obj, id, prop_val,
+                                        JS_PropertyStub, JS_StrictPropertyStub,
                                         JSPROP_ENUMERATE);
 
     *did_resolve = true;
 
     return ok ? NS_OK : NS_ERROR_FAILURE;
   }
 
   if (name_struct->mType == nsGlobalNameStruct::eTypeDynamicNameSet) {
@@ -5415,17 +5419,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     jsval v;
     rv = WrapNative(cx, scope, location, &NS_GET_IID(nsIDOMLocation), true,
                     &v, getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSBool ok = JS_WrapValue(cx, &v) &&
-                JS_DefinePropertyById(cx, obj, id, v, nullptr,
+                JS_DefinePropertyById(cx, obj, id, v, JS_PropertyStub,
                                       LocationSetterUnwrapper,
                                       JSPROP_PERMANENT | JSPROP_ENUMERATE);
 
     if (!ok) {
       return NS_ERROR_FAILURE;
     }
 
     *objp = obj;
@@ -5441,17 +5445,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     jsval v;
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = WrapNative(cx, obj, top, &NS_GET_IID(nsIDOMWindow), true,
                     &v, getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Hold on to the top window object as a global property so we
     // don't need to worry about losing expando properties etc.
-    if (!JS_DefinePropertyById(cx, obj, id, v, nullptr, nullptr,
+    if (!JS_DefinePropertyById(cx, obj, id, v, JS_PropertyStub, JS_StrictPropertyStub,
                                JSPROP_READONLY | JSPROP_PERMANENT |
                                JSPROP_ENUMERATE)) {
       return NS_ERROR_FAILURE;
     }
     *objp = obj;
 
     return NS_OK;
   }
@@ -5495,17 +5499,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     if (!fun) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     JSObject *funObj = ::JS_GetFunctionObject(fun);
 
     if (!::JS_DefinePropertyById(cx, windowObj, id, JSVAL_VOID,
                                  JS_DATA_TO_FUNC_PTR(JSPropertyOp, funObj),
-                                 nullptr,
+                                 JS_StrictPropertyStub,
                                  JSPROP_ENUMERATE | JSPROP_GETTER |
                                  JSPROP_SHARED)) {
       return NS_ERROR_FAILURE;
     }
 
     *objp = obj;
 
     return NS_OK;
@@ -5536,17 +5540,18 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       jsval v;
       nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
       rv = WrapNative(cx, obj, navigator, &NS_GET_IID(nsIDOMNavigator), true,
                       &v, getter_AddRefs(holder));
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Hold on to the navigator object as a global property so we
       // don't need to worry about losing expando properties etc.
-      if (!::JS_DefinePropertyById(cx, obj, id, v, nullptr, nullptr,
+      if (!::JS_DefinePropertyById(cx, obj, id, v,
+                                   JS_PropertyStub, JS_StrictPropertyStub,
                                    JSPROP_READONLY | JSPROP_PERMANENT |
                                    JSPROP_ENUMERATE)) {
         return NS_ERROR_FAILURE;
       }
       *objp = obj;
 
       return NS_OK;
     }
@@ -5565,17 +5570,18 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       *objp = obj;
 
       // NB: We need to do this for any Xray wrapper.
       if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
         // Unless our object is a native wrapper, in which case we have to
         // define it ourselves.
 
         *_retval = JS_WrapValue(cx, &v) &&
-                   JS_DefineProperty(cx, obj, "document", v, NULL, NULL,
+                   JS_DefineProperty(cx, obj, "document", v,
+                                     JS_PropertyStub, JS_StrictPropertyStub,
                                      JSPROP_READONLY | JSPROP_ENUMERATE);
         if (!*_retval) {
           return NS_ERROR_UNEXPECTED;
         }
       }
 
       return NS_OK;
     }
@@ -5833,17 +5839,18 @@ nsNavigatorSH::NewResolve(nsIXPConnectWr
 
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (!JS_WrapValue(cx, &prop_val)) {
     return NS_ERROR_UNEXPECTED;
   }
 
-  JSBool ok = ::JS_DefinePropertyById(cx, obj, id, prop_val, nullptr, nullptr,
+  JSBool ok = ::JS_DefinePropertyById(cx, obj, id, prop_val,
+                                      JS_PropertyStub, JS_StrictPropertyStub,
                                       JSPROP_ENUMERATE);
 
   *_retval = true;
   *objp = obj;
 
   return ok ? NS_OK : NS_ERROR_FAILURE;
 }
 
@@ -6643,17 +6650,17 @@ nsDocumentSH::NewResolve(nsIXPConnectWra
     jsval v;
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = WrapNative(cx, JS_GetGlobalForScopeChain(cx), location,
                     &NS_GET_IID(nsIDOMLocation), true, &v,
                     getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    JSBool ok = ::JS_DefinePropertyById(cx, obj, id, v, nullptr,
+    JSBool ok = ::JS_DefinePropertyById(cx, obj, id, v, JS_PropertyStub,
                                         LocationSetter<nsIDOMDocument>,
                                         JSPROP_PERMANENT | JSPROP_ENUMERATE);
 
     if (!ok) {
       return NS_ERROR_FAILURE;
     }
 
     *objp = obj;