From 8af95989b49e958524466b45c7de0b60c651f88b Mon Sep 17 00:00:00 2001 From: Igor Bukanov Date: Wed, 15 Apr 2009 16:09:58 +0200 Subject: [PATCH] bug 488285 - fixing strict mode warnings with DOm window object. r=brendan --- dom/base/nsDOMClassInfo.cpp | 9 +++++--- js/src/jsinterp.cpp | 6 ++---- js/src/jsobj.cpp | 42 +++++++++++++++++++++++-------------- js/src/jsobj.h | 11 ++++++++-- 4 files changed, 43 insertions(+), 25 deletions(-) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 3f5603fe75b..e9848056bee 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -6527,10 +6527,8 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // binding a name) a new undefined property that's not already // defined on our prototype chain. This way we can access this // expando w/o ever getting back into XPConnect. - JSStackFrame *fp = NULL; if ((flags & JSRESOLVE_ASSIGNING) && !(flags & JSRESOLVE_WITH) && - !(JS_FrameIterator(cx, &fp) && fp->regs && (JSOp)*fp->regs->pc == JSOP_BINDNAME) && win->IsInnerWindow()) { JSObject *realObj; wrapper->GetJSObject(&realObj); @@ -6564,9 +6562,14 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // We don't need to worry about property attributes here as we // know here we're dealing with an undefined property set, so // we're not declaring readonly or permanent properties. + // + // Since we always create the undeclared property here without given a + // chance for the interpreter to report applicable strict mode warnings, + // we must take care to check those warnings here. JSString *str = JSVAL_TO_STRING(id); - if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), + if (!::js_CheckUndeclaredVarAssignment(cx) || + !::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), ::JS_GetStringLength(str), JSVAL_VOID, JS_PropertyStub, JS_PropertyStub, JSPROP_ENUMERATE)) { diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 404f5dba4c4..84d7b615bec 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -4776,10 +4776,8 @@ js_Interpret(JSContext *cx) LOAD_ATOM(0); id = ATOM_TO_JSID(atom); if (entry) { - if (!js_SetPropertyHelper(cx, obj, id, op == JSOP_SETNAME, - &rval, &entry)) { + if (!js_SetPropertyHelper(cx, obj, id, &rval, &entry)) goto error; - } #ifdef JS_TRACER if (entry) TRACE_1(SetPropMiss, entry); @@ -6433,7 +6431,7 @@ js_Interpret(JSContext *cx) goto error; } if (JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom) - ? !js_SetPropertyHelper(cx, obj, id, false, &rval, &entry) + ? !js_SetPropertyHelper(cx, obj, id, &rval, &entry) : !js_DefineNativeProperty(cx, obj, id, rval, NULL, NULL, JSPROP_ENUMERATE, 0, 0, NULL, &entry)) { diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index bdd208d8a9f..7b554d7c084 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -4379,9 +4379,30 @@ js_GetMethod(JSContext *cx, JSObject *obj, jsid id, jsval *vp, return OBJ_GET_PROPERTY(cx, obj, id, vp); } +JS_FRIEND_API(JSBool) +js_CheckUndeclaredVarAssignment(JSContext *cx) +{ + JSStackFrame *fp; + if (!JS_HAS_STRICT_OPTION(cx) || + !(fp = js_GetTopStackFrame(cx)) || + !fp->regs || + js_GetOpcode(cx, fp->script, fp->regs->pc) != JSOP_SETNAME) { + return JS_TRUE; + } + + JSAtom *atom; + GET_ATOM_FROM_BYTECODE(fp->script, fp->regs->pc, 0, atom); + + const char *bytes = js_AtomToPrintableString(cx, atom); + return bytes && + JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING | JSREPORT_STRICT, + js_GetErrorMessage, NULL, + JSMSG_UNDECLARED_VAR, bytes); +} + JSBool -js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, - JSBool unqualified, jsval *vp, JSPropCacheEntry **entryp) +js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp, + JSPropCacheEntry **entryp) { uint32 shape; int protoIndex; @@ -4420,19 +4441,8 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, /* We should never add properties to lexical blocks. */ JS_ASSERT(OBJ_GET_CLASS(cx, obj) != &js_BlockClass); - if (unqualified && !OBJ_GET_PARENT(cx, obj) && - JS_HAS_STRICT_OPTION(cx)) { - JSString *str = JSVAL_TO_STRING(ID_TO_VALUE(id)); - const char *bytes = js_GetStringBytes(cx, str); - if (!bytes || - !JS_ReportErrorFlagsAndNumber(cx, - JSREPORT_WARNING | - JSREPORT_STRICT, - js_GetErrorMessage, NULL, - JSMSG_UNDECLARED_VAR, bytes)) { - return NULL; - } - } + if (!OBJ_GET_PARENT(cx, obj) && !js_CheckUndeclaredVarAssignment(cx)) + return NULL; } sprop = (JSScopeProperty *) prop; @@ -4607,7 +4617,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, JSBool js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { - return js_SetPropertyHelper(cx, obj, id, false, vp, NULL); + return js_SetPropertyHelper(cx, obj, id, vp, NULL); } JSBool diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 2d221915383..30449d0f14c 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -711,9 +711,16 @@ extern JSBool js_GetMethod(JSContext *cx, JSObject *obj, jsid id, jsval *vp, JSPropCacheEntry **entryp); +/* + * Check whether it is OK to assign an undeclared property of the global + * object at the current script PC. + */ +extern JS_FRIEND_API(JSBool) +js_CheckUndeclaredVarAssignment(JSContext *cx); + extern JSBool -js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, - JSBool unqualified, jsval *vp, JSPropCacheEntry **entryp); +js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp, + JSPropCacheEntry **entryp); extern JSBool js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);