Do not innerize an object assigned to __proto__ or used as the target of a with statement. Bug 719841, r=mrbkap.
☠☠ backed out by 117f2280bd37 ☠ ☠
authorBobby Holley <bobbyholley@gmail.com>, Jason Orendorff <jorendorff@mozilla.com>
Fri, 27 Jan 2012 14:16:27 -0600
changeset 86840 88145df4191a6b4d29f552c2f0e5f05c21545cc2
parent 86839 42408569a696aebdfeb742bca0b035553de3b25c
child 86841 4df33078d5d08d308e71e4457370c5a332876cb5
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs719841
milestone12.0a1
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
@@ -5664,16 +5664,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
@@ -1009,20 +1009,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 */