Bug 570195 - Object.prototype.hasOwnProperty doesn't set the JSRESOLVE_DETECTING flag. r=jorendorff, test by jorendorff.
authorTaras Glek <tglek@mozilla.com>
Fri, 04 Jun 2010 14:20:53 -0700
changeset 43285 545a4745c09bf3241c1bc8474e9a333945c3450f
parent 43284 52be13ea048813852b8c6e466d9d762433ce14c6
child 43286 51f83963d7f969254a3618b960d8643aad4d9abf
push idunknown
push userunknown
push dateunknown
reviewersjorendorff, test
bugs570195
milestone1.9.3a5pre
Bug 570195 - Object.prototype.hasOwnProperty doesn't set the JSRESOLVE_DETECTING flag. r=jorendorff, test by jorendorff.
js/src/jsapi-tests/testLookup.cpp
js/src/jsobj.cpp
--- a/js/src/jsapi-tests/testLookup.cpp
+++ b/js/src/jsapi-tests/testLookup.cpp
@@ -22,8 +22,49 @@ BEGIN_TEST(testLookup_bug522590)
     JSObject *funobj = JSVAL_TO_OBJECT(r);
     CHECK(funobj->isFunction());
     CHECK(!js::IsInternalFunctionObject(funobj));
     CHECK(GET_FUNCTION_PRIVATE(cx, funobj) != (JSFunction *) funobj);
 
     return true;
 }
 END_TEST(testLookup_bug522590)
+
+JSBool
+document_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp)
+{
+    // If id is "all", and we're not detecting, resolve document.all=true.
+    jsvalRoot v(cx);
+    if (!JS_IdToValue(cx, id, v.addr()))
+        return false;
+    if (JSVAL_IS_STRING(v.value())) {
+        JSString *str = JSVAL_TO_STRING(v.value());
+        const char *p = JS_GetStringBytes(str);
+        if (strcmp(p, "all") == 0 && !(flags & JSRESOLVE_DETECTING)) {
+            JSBool ok = JS_DefinePropertyById(cx, obj, id, JSVAL_TRUE, NULL, NULL, 0);
+            *objp = ok ? obj : NULL;
+            return ok;
+        }
+    }
+    *objp = NULL;
+    return true;
+}
+
+static JSClass document_class = {
+    "document", JSCLASS_NEW_RESOLVE,
+    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+    JS_EnumerateStub, (JSResolveOp) document_resolve, JS_ConvertStub, JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+BEGIN_TEST(testLookup_bug570195)
+{
+    JSObject *obj = JS_NewObject(cx, &document_class, NULL, NULL);
+    CHECK(obj);
+    CHECK(JS_DefineProperty(cx, global, "document", OBJECT_TO_JSVAL(obj), NULL, NULL, 0));
+    jsvalRoot v(cx);
+    EVAL("document.all ? true : false", v.addr());
+    CHECK_SAME(v.value(), JSVAL_FALSE);
+    EVAL("document.hasOwnProperty('all')", v.addr());
+    CHECK_SAME(v.value(), JSVAL_FALSE);
+    return true;
+}
+END_TEST(testLookup_bug570195)
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1507,16 +1507,17 @@ js_HasOwnPropertyHelper(JSContext *cx, J
     }
     return JS_TRUE;
 }
 
 JSBool
 js_HasOwnProperty(JSContext *cx, JSLookupPropOp lookup, JSObject *obj, jsid id,
                   JSObject **objp, JSProperty **propp)
 {
+    JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DETECTING);
     if (!lookup(cx, obj, id, objp, propp))
         return false;
     if (!*propp)
         return true;
 
     if (*objp == obj)
         return true;