From e8c803bd1e2400bfde962020ae81987840acb644 Mon Sep 17 00:00:00 2001 From: "mrbkap%gmail.com" Date: Fri, 5 May 2006 23:29:37 +0000 Subject: [PATCH] Expand the checks to more cases. bug 336601, r+a181=brendan a=dveditz --- js/src/jsinterp.c | 66 +++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 48 deletions(-) diff --git a/js/src/jsinterp.c b/js/src/jsinterp.c index f1dfb3c3108e..8ff1617f7e9e 100644 --- a/js/src/jsinterp.c +++ b/js/src/jsinterp.c @@ -490,8 +490,6 @@ js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp) JSObject * js_ComputeThis(JSContext *cx, JSObject *thisp, jsval *argv) { - JSObject *parent; - if (thisp && OBJ_GET_CLASS(cx, thisp) != &js_CallClass) { /* Some objects (e.g., With) delegate 'this' to another object. */ thisp = OBJ_THIS_OBJECT(cx, thisp); @@ -515,60 +513,32 @@ js_ComputeThis(JSContext *cx, JSObject *thisp, jsval *argv) * The alert should display "true". */ if (JSVAL_IS_PRIMITIVE(argv[-2]) || - !(parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2])))) { + !OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2]))) { thisp = cx->globalObject; } else { - /* walk up to find the top-level object */ - thisp = parent; - while ((parent = OBJ_GET_PARENT(cx, thisp)) != NULL) - thisp = parent; + jsid id; + jsval v; + uintN attrs; + + /* Walk up the parent chain. */ + thisp = JSVAL_TO_OBJECT(argv[-2]); + id = ATOM_TO_JSID(cx->runtime->atomState.parentAtom); + for (;;) { + if (!OBJ_CHECK_ACCESS(cx, thisp, id, JSACC_PARENT, &v, &attrs)) + return NULL; + if (JSVAL_IS_VOID(v)) + v = OBJ_GET_SLOT(cx, thisp, JSSLOT_PARENT); + JS_ASSERT(JSVAL_TO_OBJECT(v) == OBJ_GET_PARENT(cx, thisp)); + if (JSVAL_IS_NULL(v)) + break; + thisp = JSVAL_TO_OBJECT(v); + } } } argv[-1] = OBJECT_TO_JSVAL(thisp); return thisp; } -/* Like js_ComputeThis, but with security checks. */ -JSObject * -js_SafeComputeThis(JSContext *cx, JSObject *thisp, jsval *argv) -{ - jsid id; - jsval v; - uintN attrs; - - /* N.B. This function closely mirrors the logic in js_ComputeThis. */ - JS_ASSERT(thisp == JSVAL_TO_OBJECT(argv[-1])); - - /* - * In this case, it is safe to simply return thisp and skip the - * OBJ_THIS_OBJECT, since all callers of js_SafeComputeThis call - * us first, and will always call js_ComputeThis afterwards. - */ - if (thisp && OBJ_GET_CLASS(cx, thisp) != &js_CallClass) - return thisp; - - JS_ASSERT(!JSVAL_IS_PRIMITIVE(argv[-2])); - thisp = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2])); - if (!thisp) { - thisp = cx->globalObject; - } else { - id = ATOM_TO_JSID(cx->runtime->atomState.parentAtom); - for (;;) { - if (!OBJ_CHECK_ACCESS(cx, thisp, id, JSACC_PARENT, &v, &attrs)) - return NULL; - if (JSVAL_IS_NULL(v)) - break; - if (JSVAL_IS_VOID(v)) - v = OBJ_GET_SLOT(cx, thisp, JSSLOT_PARENT); - JS_ASSERT(JSVAL_IS_OBJECT(v)); - thisp = JSVAL_TO_OBJECT(v);; - } - } - - argv[-1] = OBJECT_TO_JSVAL(thisp); - return thisp; -} - #if JS_HAS_NO_SUCH_METHOD static JSBool