Bug 446026 - restore utility of eval(s, o). r=mrbkap
authorBrian Crowder <crowder@fiverocks.com>.
Fri, 12 Dec 2008 23:47:23 -0800
changeset 23064 e905fe64c1b279d2089e4238e8bdb9c58cb122bf
parent 23063 a5c631abee1f4056232044e9b4365c9ab870ea04
child 23065 3c3921f30981f8e780d669688b72ea768a5524ba
push id4346
push userrsayre@mozilla.com
push dateFri, 26 Dec 2008 01:26:36 +0000
treeherdermozilla-central@8eb5a5b83a93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs446026
milestone1.9.2a1pre
Bug 446026 - restore utility of eval(s, o). r=mrbkap
js/src/jsobj.cpp
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1228,22 +1228,21 @@ obj_eval(JSContext *cx, JSObject *obj, u
     /*
      * If the caller is a lightweight function and doesn't have a variables
      * object, then we need to provide one for the compiler to stick any
      * declared (var) variables into.
      */
     if (caller && !caller->varobj && !js_GetCallObject(cx, caller, NULL))
         return JS_FALSE;
 
-    /* eval no longer takes an optional trailing argument. */
-    if (argc >= 2 &&
-        !JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING | JSREPORT_STRICT,
-                                      js_GetErrorMessage, NULL,
-                                      JSMSG_EVAL_ARITY)) {
-        return JS_FALSE;
+    /* Accept an optional trailing argument that overrides the scope object. */
+    if (argc >= 2) {
+        if (!js_ValueToObject(cx, argv[1], &scopeobj))
+            return JS_FALSE;
+        argv[1] = OBJECT_TO_JSVAL(scopeobj);
     }
 
     /* From here on, control must exit through label out with ok set. */
     MUST_FLOW_THROUGH("out");
     if (!scopeobj) {
 #if JS_HAS_EVAL_THIS_SCOPE
         /* If obj.eval(str), emulate 'with (obj) eval(str)' in the caller. */
         if (indirectCall) {
@@ -1294,16 +1293,29 @@ obj_eval(JSContext *cx, JSObject *obj, u
          */
         if (caller) {
             scopeobj = js_GetScopeChain(cx, caller);
             if (!scopeobj) {
                 ok = JS_FALSE;
                 goto out;
             }
         }
+    } else {
+        ok = js_CheckPrincipalsAccess(cx, scopeobj,
+                                      JS_StackFramePrincipals(cx, caller),
+                                      cx->runtime->atomState.evalAtom);
+        if (!ok)
+            goto out;
+
+        scopeobj = js_NewWithObject(cx, scopeobj,
+                                    JS_GetGlobalForObject(cx, scopeobj), -1);
+        if (!scopeobj) {
+            ok = JS_FALSE;
+            goto out;
+        }
     }
 
     /* Ensure we compile this eval with the right object in the scope chain. */
     scopeobj = js_CheckScopeChainValidity(cx, scopeobj, js_eval_str);
     if (!scopeobj) {
         ok = JS_FALSE;
         goto out;
     }