Do not innerize an object assigned to __proto__ or used as the target of a with statement. Bug 719841, r=mrbkap.
authorBobby Holley <bobbyholley@gmail.com>, Jason Orendorff <jorendorff@mozilla.com>
Fri, 27 Jan 2012 14:16:27 -0600
changeset 88945 8e8303c3a060ba4dbf4b8faa2f522a15a7bd7955
parent 88944 ee98e4d7199508aa3b24b69ec1caa64db1e7a427
child 88946 429c84c4b66a441b7b398ee6bad3d56db0197a4c
push id783
push userlsblakk@mozilla.com
push dateTue, 24 Apr 2012 17:33:42 +0000
treeherdermozilla-beta@11faed19f136 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs719841
milestone13.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
Do not innerize an object assigned to __proto__ or used as the target of a with statement. Bug 719841, r=mrbkap.
js/src/jsinfer.cpp
js/src/jsinferinlines.h
js/src/jsinterp.cpp
js/src/jsobj.cpp
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -5657,16 +5657,19 @@ JSObject::splicePrototype(JSContext *cx,
     /*
      * For singleton types representing only a single JSObject, the proto
      * can be rearranged as needed without destroying type information for
      * the old or new types. Note that type constraints propagating properties
      * from the old prototype are not removed.
      */
     JS_ASSERT_IF(cx->typeInferenceEnabled(), hasSingletonType());
 
+    /* Inner objects may not appear on prototype chains. */
+    JS_ASSERT_IF(proto, !proto->getClass()->ext.outerObject);
+
     /*
      * Force type instantiation when splicing lazy types. This may fail,
      * in which case inference will be disabled for the compartment.
      */
     TypeObject *type = getType(cx);
     TypeObject *protoType = NULL;
     if (proto) {
         protoType = proto->getType(cx);
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -1154,16 +1154,19 @@ TypeCallsite::TypeCallsite(JSContext *cx
 /////////////////////////////////////////////////////////////////////
 // TypeObject
 /////////////////////////////////////////////////////////////////////
 
 inline TypeObject::TypeObject(JSObject *proto, bool function, bool unknown)
 {
     PodZero(this);
 
+    /* Inner objects may not appear on prototype chains. */
+    JS_ASSERT_IF(proto, !proto->getClass()->ext.outerObject);
+
     this->proto = proto;
 
     if (function)
         flags |= OBJECT_FLAG_FUNCTION;
     if (unknown)
         flags |= OBJECT_FLAG_UNKNOWN_MASK;
 
     InferSpew(ISpewOps, "newObject: %s", TypeObjectString(this));
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -989,20 +989,16 @@ EnterWith(JSContext *cx, jsint stackInde
             return JS_FALSE;
         sp[-1].setObject(*obj);
     }
 
     JSObject *parent = GetScopeChain(cx, fp);
     if (!parent)
         return JS_FALSE;
 
-    OBJ_TO_INNER_OBJECT(cx, obj);
-    if (!obj)
-        return JS_FALSE;
-
     JSObject *withobj = WithObject::create(cx, fp, *obj, *parent,
                                            sp + stackIndex - fp->base());
     if (!withobj)
         return JS_FALSE;
 
     fp->setScopeChainNoCallObj(*withobj);
     return JS_TRUE;
 }
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -181,36 +181,25 @@ obj_setProto(JSContext *cx, JSObject *ob
 
     /* ECMAScript 5 8.6.2 forbids changing [[Prototype]] if not [[Extensible]]. */
     if (!obj->isExtensible()) {
         obj->reportNotExtensible(cx);
         return false;
     }
 
     if (!vp->isObjectOrNull())
-        return JS_TRUE;
+        return true;
 
     JSObject *pobj = vp->toObjectOrNull();
-    if (pobj) {
-        /*
-         * Innerize pobj here to avoid sticking unwanted properties on the
-         * outer object. This ensures that any with statements only grant
-         * access to the inner object.
-         */
-        OBJ_TO_INNER_OBJECT(cx, pobj);
-        if (!pobj)
-            return JS_FALSE;
-    }
-
     uintN attrs;
     id = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
     if (!CheckAccess(cx, obj, id, JSAccessMode(JSACC_PROTO|JSACC_WRITE), vp, &attrs))
-        return JS_FALSE;
-
-    return SetProto(cx, obj, pobj, JS_TRUE);
+        return false;
+
+    return SetProto(cx, obj, pobj, true);
 }
 
 #else  /* !JS_HAS_OBJ_PROTO_PROP */
 
 #define object_props NULL
 
 #endif /* !JS_HAS_OBJ_PROTO_PROP */