Reviewed by Geoff, Maciej.
Fix <rdar://problem/
5445058>
REGRESSION: Unable to upload picture to eBay auction due to domain security check
eBay uses window.eval() between windows. In Firefox window.eval() switches execution
and security context to the target window, something WebKit did not do. With WebKit
security tightening in r24781, this broke picture uploads.
Fix by making WebKit switch context in window.eval().
* kjs/Context.cpp:
(KJS::Context::Context):
(KJS::Context::~Context):
* kjs/context.h:
Save and restore interpreter context independently from calling context.
* kjs/function.cpp:
(KJS::GlobalFuncImp::callAsFunction):
If eval is called for global object different than current one, switch execution context
to that object and push it to scope.
LayoutTests:
Reviewed by Geoff, Maciej.
Test for <rdar://problem/
5445058>
REGRESSION: Unable to upload picture to eBay auction due to domain security check
* fast/js/window-eval-context-expected.txt: Added.
* fast/js/window-eval-context.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@25534
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2007-09-12 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Geoff, Maciej.
+
+ Fix <rdar://problem/5445058>
+ REGRESSION: Unable to upload picture to eBay auction due to domain security check
+
+ eBay uses window.eval() between windows. In Firefox window.eval() switches execution
+ and security context to the target window, something WebKit did not do. With WebKit
+ security tightening in r24781, this broke picture uploads.
+
+ Fix by making WebKit switch context in window.eval().
+
+ * kjs/Context.cpp:
+ (KJS::Context::Context):
+ (KJS::Context::~Context):
+ * kjs/context.h:
+ Save and restore interpreter context independently from calling context.
+
+ * kjs/function.cpp:
+ (KJS::GlobalFuncImp::callAsFunction):
+ If eval is called for global object different than current one, switch execution context
+ to that object and push it to scope.
+
2007-09-12 Sam Weinig <sam@webkit.org>
Reviewed by Geoffrey Garen.
FunctionBodyNode* currentBody, CodeType type, Context* callingCon,
FunctionImp* func, const List* args)
: m_interpreter(interpreter)
+ , m_savedContext(interpreter->context())
, m_currentBody(currentBody)
, m_function(func)
, m_arguments(args)
Context::~Context()
{
- m_interpreter->setContext(m_callingContext);
+ m_interpreter->setContext(m_savedContext);
// The arguments list is only needed to potentially create the arguments object,
// which isn't accessible from nested scopes so we can discard the list as soon
Interpreter* m_interpreter;
Context* m_callingContext;
+ Context* m_savedContext;
FunctionBodyNode* m_currentBody;
ExecState* m_execState;
return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ );
}
-JSValue* GlobalFuncImp::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const List& args)
+JSValue* GlobalFuncImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
{
JSValue* res = jsUndefined();
if (!progNode)
return throwError(exec, SyntaxError, errMsg, errLine, sid, NULL);
+ bool switchGlobal = exec->dynamicInterpreter()->isGlobalObject(thisObj) && thisObj != exec->dynamicInterpreter()->globalObject();
+
// enter a new execution context
+ Interpreter* interpreter = switchGlobal ? exec->dynamicInterpreter()->interpreterForGlobalObject(thisObj) : exec->dynamicInterpreter();
JSObject* thisVal = static_cast<JSObject*>(exec->context()->thisValue());
- Context ctx(exec->dynamicInterpreter()->globalObject(),
- exec->dynamicInterpreter(),
+ Context ctx(interpreter->globalObject(),
+ interpreter,
thisVal,
progNode.get(),
EvalCode,
exec->context());
- ExecState newExec(exec->dynamicInterpreter(), &ctx);
+ ExecState newExec(interpreter, &ctx);
if (exec->hadException())
newExec.setException(exec->exception());
ctx.setExecState(&newExec);
+
+ if (switchGlobal)
+ ctx.pushScope(thisObj);
// execute the code
progNode->processVarDecls(&newExec);
Completion c = progNode->execute(&newExec);
+
+ if (switchGlobal)
+ ctx.popScope();
// if an exception occured, propogate it back to the previous execution object
if (newExec.hadException())
+2007-09-12 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Geoff, Maciej.
+
+ Test for <rdar://problem/5445058>
+ REGRESSION: Unable to upload picture to eBay auction due to domain security check
+
+ * fast/js/window-eval-context-expected.txt: Added.
+ * fast/js/window-eval-context.html: Added.
+
2007-09-12 John Seif <johneseif@gmail.com>
Reviewed by Darin.
--- /dev/null
+
+Test that otherWindow.eval() keeps variables of calling context visible: PASS
+Test that otherWindow.eval() is executed with otherWindow in scope PASS
+Test that otherWindow.eval() has otherWindow as the window object : PASS
+Test that otherWindow.eval() does not change 'this': PASS
--- /dev/null
+<body>
+<script>
+function print(message, color)
+{
+ var paragraph = document.createElement("div");
+ paragraph.appendChild(document.createTextNode(message));
+ paragraph.style.fontFamily = "monospace";
+ if (color)
+ paragraph.style.color = color;
+ document.getElementById("console").appendChild(paragraph);
+}
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+<iframe id=i src='about:blank' width=10 height=10>
+</iframe><br>
+<div id=console></div>
+<script>
+var otherWindow = document.getElementById('i').contentWindow;
+var res;
+var localVar = 1;
+
+res = otherWindow.eval('localVar == 1');
+print("Test that otherWindow.eval() keeps variables of calling context visible: " + (res ? "PASS" : "FAIL")) ;
+
+otherWindow.localVar = 2;
+res = otherWindow.eval('localVar == 2');
+print("Test that otherWindow.eval() is executed with otherWindow in scope " + (res ? "PASS" : "FAIL")) ;
+
+res = otherWindow.eval('window == otherWindow');
+print("Test that otherWindow.eval() has otherWindow as the window object : " + (res ? "PASS" : "FAIL")) ;
+
+var savedThis = this;
+res = otherWindow.eval('this == savedThis');
+print("Test that otherWindow.eval() does not change 'this': " + (res ? "PASS" : "FAIL")) ;
+</script>