Bug 808608 - Implement shadowing protection in nsDOMClassInfo. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Wed, 21 Nov 2012 13:20:05 -0800
changeset 113926 58b5ab3331665ffddf56e641c8b4d1c834494830
parent 113925 3a0c93f1b34c9ceaa9aaddb3763b8c6feba649b6
child 113927 f630faad853a3c8d5eb25be027c2abaeeac725fc
push id18459
push userbobbyholley@gmail.com
push dateWed, 21 Nov 2012 21:21:06 +0000
treeherdermozilla-inbound@030c89e22e3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs808608
milestone20.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 808608 - Implement shadowing protection in nsDOMClassInfo. r=mrbkap This allows us to remove the same-compartment Location wrappers. This can go away when we move Location to the new bindings and get access to [Unforgeable].
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
js/xpconnect/idl/nsIXPConnect.idl
js/xpconnect/src/XPCWrappedNative.cpp
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -752,17 +752,18 @@ static nsDOMClassInfoData sClassInfoData
   // to JS.
 
 
   NS_DEFINE_CLASSINFO_DATA(Window, nsWindowSH,
                            DEFAULT_SCRIPTABLE_FLAGS |
                            WINDOW_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(Location, nsLocationSH,
-                           (DOM_DEFAULT_SCRIPTABLE_FLAGS &
+                           ((DOM_DEFAULT_SCRIPTABLE_FLAGS |
+                             nsIXPCScriptable::WANT_ADDPROPERTY) &
                             ~nsIXPCScriptable::ALLOW_PROP_MODS_TO_PROTOTYPE))
 
   NS_DEFINE_CLASSINFO_DATA(Navigator, nsNavigatorSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_PRECREATE |
                            nsIXPCScriptable::WANT_NEWRESOLVE)
   NS_DEFINE_CLASSINFO_DATA(Plugin, nsPluginSH,
                            ARRAY_SCRIPTABLE_FLAGS)
@@ -7605,16 +7606,30 @@ nsLocationSH::PreCreate(nsISupports *nat
                "docshell is being destroyed");
     return NS_ERROR_UNEXPECTED;
   }
 
   *parentObj = sgo->GetGlobalJSObject();
   return *parentObj ? NS_OK : NS_ERROR_FAILURE;
 }
 
+NS_IMETHODIMP
+nsLocationSH::AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
+                          JSObject *obj, jsid id, jsval *vp, bool *_retval)
+{
+  // Shadowing protection. This will go away when nsLocation moves to the new
+  // bindings.
+  if (wrapper->HasNativeMember(id)) {
+    JS_ReportError(cx, "Permission denied to shadow native property");
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
 // DOM Navigator helper
 
 NS_IMETHODIMP
 nsNavigatorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                           JSObject *obj, jsid id, uint32_t flags,
                           JSObject **objp, bool *_retval)
 {
   if (!JSID_IS_STRING(id) || (flags & JSRESOLVE_ASSIGNING)) {
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -449,16 +449,18 @@ protected:
 
 public:
   NS_IMETHOD CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                          JSObject *obj, jsid id, uint32_t mode,
                          jsval *vp, bool *_retval);
 
   NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
                        JSObject *globalObj, JSObject **parentObj);
+  NS_IMETHODIMP AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
+                            JSObject *obj, jsid id, jsval *vp, bool *_retval);
 
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsLocationSH(aData);
   }
 };
 
 
--- a/js/xpconnect/idl/nsIXPConnect.idl
+++ b/js/xpconnect/idl/nsIXPConnect.idl
@@ -62,30 +62,31 @@ class nsScriptObjectTracer;
 
 /***************************************************************************/
 [uuid(8916a320-d118-11d3-8f3a-0010a4e73d9a)]
 interface nsIXPConnectJSObjectHolder : nsISupports
 {
     readonly attribute JSObjectPtr      JSObject;
 };
 
-[uuid(f819a95a-6ab5-4a02-bda6-32861e859581)]
+[uuid(92e98688-0154-4b65-971b-0d4afe8fd7cb)]
 interface nsIXPConnectWrappedNative : nsIXPConnectJSObjectHolder
 {
     /* attribute 'JSObject' inherited from nsIXPConnectJSObjectHolder */
     readonly attribute nsISupports      Native;
     readonly attribute JSObjectPtr      JSObjectPrototype;
 
     /**
      * These are here as an aid to nsIXPCScriptable implementors
      */
 
     readonly attribute nsIXPConnect XPConnect;
     nsIInterfaceInfo FindInterfaceWithMember(in jsid nameID);
     nsIInterfaceInfo FindInterfaceWithName(in jsid nameID);
+    [notxpcom] bool HasNativeMember(in jsid name);
 
     void debugDump(in short depth);
 
     /*
      * This finishes initializing a wrapped global, doing the parts that we
      * couldn't do while the global and window were being simultaneously
      * bootstrapped. This should be called exactly once, and only for wrapped
      * globals.
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -3184,16 +3184,25 @@ NS_IMETHODIMP XPCWrappedNative::FindInte
         nsIInterfaceInfo* temp = iface->GetInterfaceInfo();
         NS_IF_ADDREF(temp);
         *_retval = temp;
     } else
         *_retval = nullptr;
     return NS_OK;
 }
 
+/* [notxpcom] bool HasNativeMember (in jsval name); */
+NS_IMETHODIMP_(bool)
+XPCWrappedNative::HasNativeMember(jsid name)
+{
+    XPCNativeMember *member = nullptr;
+    uint16_t ignored;
+    return GetSet()->FindMember(name, &member, &ignored) && !!member;
+}
+
 inline nsresult UnexpectedFailure(nsresult rv)
 {
     NS_ERROR("This is not supposed to fail!");
     return rv;
 }
 
 /* void finishInitForWrappedGlobal (); */
 NS_IMETHODIMP XPCWrappedNative::FinishInitForWrappedGlobal()