Commit b286773f authored by yurys@chromium.org's avatar yurys@chromium.org

Web Inspector: console evaluation doesn't work on breakpoint in pages with CSP

https://bugs.webkit.org/show_bug.cgi?id=77203

Inspector console evaluation now works when debugger is paused in a page with
content-security-policy prohibiting evals.

Reviewed by Pavel Feldman.

Source/WebCore:

Test: inspector/debugger/eval-on-pause-blocked.html

* bindings/js/JSInjectedScriptHostCustom.cpp:
* bindings/js/ScriptState.cpp:
(WebCore::evalEnabled):
(WebCore):
(WebCore::setEvalEnabled):
* bindings/js/ScriptState.h:
(WebCore):
* bindings/v8/ScriptObject.h:
(WebCore::ScriptObject::ScriptObject):
* bindings/v8/ScriptState.cpp:
(WebCore::evalEnabled):
(WebCore):
(WebCore::setEvalEnabled):
* bindings/v8/ScriptState.h:
(WebCore):
* bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
* inspector/InjectedScript.cpp:
(WebCore::InjectedScript::makeCall):
* inspector/InjectedScriptHost.idl:
* inspector/InjectedScriptSource.js:
(.):

LayoutTests:

* inspector/debugger/eval-on-pause-blocked-expected.txt: Added.
* inspector/debugger/eval-on-pause-blocked.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@106657 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f1591ee8
2012-01-27 Yury Semikhatsky <yurys@chromium.org>
Web Inspector: console evaluation doesn't work on breakpoint in pages with CSP
https://bugs.webkit.org/show_bug.cgi?id=77203
Inspector console evaluation now works when debugger is paused in a page with
content-security-policy prohibiting evals.
Reviewed by Pavel Feldman.
* inspector/debugger/eval-on-pause-blocked-expected.txt: Added.
* inspector/debugger/eval-on-pause-blocked.html: Added.
2012-02-03 Allan Sandfeld Jensen <allan.jensen@nokia.com>
Test that timers do not fire from subframes of suspended documents.
Test that evaluation in the context of top frame will not be blocked by Content-Security-Policy. Bug 77203.
Debugger was enabled.
Set timer for test function.
Script execution paused.
Evaluated in console in the top frame context: foo = 2012
Script execution resumed.
Debugger was disabled.
<html>
<head>
<script src="../../http/tests/inspector/inspector-test.js"></script>
<script src="../../http/tests/inspector/debugger-test.js"></script>
<meta http-equiv="X-WebKit-CSP" content="script-src 'unsafe-inline'">
<script>
function testFunction()
{
var foo = 2012;
debugger;
}
var test = function()
{
InspectorTest.startDebuggerTest(step1);
function step1()
{
InspectorTest.runTestFunctionAndWaitUntilPaused(step2);
}
function step2()
{
InspectorTest.evaluateInConsole("foo", step3);
}
function step3(result)
{
InspectorTest.addResult("Evaluated in console in the top frame context: foo = " + result);
InspectorTest.completeDebuggerTest();
}
}
</script>
</head>
<body onload="runTest()">
<p>
Test that evaluation in the context of top frame will not be blocked by Content-Security-Policy.
<a href="https://bugs.webkit.org/show_bug.cgi?id=77203">Bug 77203.</a>
</p>
</body>
</html>
2012-01-27 Yury Semikhatsky <yurys@chromium.org>
Web Inspector: console evaluation doesn't work on breakpoint in pages with CSP
https://bugs.webkit.org/show_bug.cgi?id=77203
Inspector console evaluation now works when debugger is paused in a page with
content-security-policy prohibiting evals.
Reviewed by Pavel Feldman.
Test: inspector/debugger/eval-on-pause-blocked.html
* bindings/js/JSInjectedScriptHostCustom.cpp:
* bindings/js/ScriptState.cpp:
(WebCore::evalEnabled):
(WebCore):
(WebCore::setEvalEnabled):
* bindings/js/ScriptState.h:
(WebCore):
* bindings/v8/ScriptObject.h:
(WebCore::ScriptObject::ScriptObject):
* bindings/v8/ScriptState.cpp:
(WebCore::evalEnabled):
(WebCore):
(WebCore::setEvalEnabled):
* bindings/v8/ScriptState.h:
(WebCore):
* bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
* inspector/InjectedScript.cpp:
(WebCore::InjectedScript::makeCall):
* inspector/InjectedScriptHost.idl:
* inspector/InjectedScriptSource.js:
(.):
2012-02-03 Rob Buis <rbuis@rim.com>
Upstream targetType usage on ResourceRequest for BlackBerry port
......@@ -76,28 +76,6 @@ ScriptValue InjectedScriptHost::nodeAsScriptValue(ScriptState* state, Node* node
return ScriptValue(state->globalData(), toJS(state, deprecatedGlobalObjectForPrototype(state), node));
}
JSValue JSInjectedScriptHost::evaluate(ExecState* exec)
{
JSValue expression = exec->argument(0);
if (!expression.isString())
return throwError(exec, createError(exec, "String argument expected."));
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
JSFunction* evalFunction = globalObject->evalFunction();
CallData callData;
CallType callType = evalFunction->methodTable()->getCallData(evalFunction, callData);
if (callType == CallTypeNone)
return jsUndefined();
MarkedArgumentBuffer args;
args.append(expression);
bool wasEvalEnabled = globalObject->evalEnabled();
globalObject->setEvalEnabled(true);
JSValue result = JSC::call(exec, evalFunction, callType, callData, exec->globalThisValue(), args);
globalObject->setEvalEnabled(wasEvalEnabled);
return result;
}
JSValue JSInjectedScriptHost::inspectedNode(ExecState* exec)
{
if (exec->argumentCount() < 1)
......
......@@ -71,6 +71,18 @@ DOMWindow* domWindowFromScriptState(ScriptState* scriptState)
return static_cast<JSDOMWindowBase*>(globalObject)->impl();
}
bool evalEnabled(ScriptState* scriptState)
{
JSC::JSGlobalObject* globalObject = scriptState->lexicalGlobalObject();
return globalObject->evalEnabled();
}
void setEvalEnabled(ScriptState* scriptState, bool enabled)
{
JSC::JSGlobalObject* globalObject = scriptState->lexicalGlobalObject();
return globalObject->setEvalEnabled(enabled);
}
ScriptState* mainWorldScriptState(Frame* frame)
{
JSDOMWindowShell* shell = frame->script()->windowShell(mainThreadNormalWorld());
......
......@@ -66,6 +66,9 @@ private:
DOMWindow* domWindowFromScriptState(ScriptState*);
bool evalEnabled(ScriptState*);
void setEvalEnabled(ScriptState*, bool);
ScriptState* mainWorldScriptState(Frame*);
ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
......
......@@ -43,7 +43,7 @@ namespace WebCore {
class ScriptObject : public ScriptValue {
public:
ScriptObject(ScriptState*, v8::Handle<v8::Object>);
ScriptObject() {};
ScriptObject() : m_scriptState(0) { };
virtual ~ScriptObject() {}
v8::Local<v8::Object> v8Object() const;
......
......@@ -109,6 +109,18 @@ DOMWindow* domWindowFromScriptState(ScriptState* scriptState)
return scriptState->domWindow();
}
bool evalEnabled(ScriptState* scriptState)
{
v8::HandleScope handleScope;
return scriptState->context()->IsCodeGenerationFromStringsAllowed();
}
void setEvalEnabled(ScriptState* scriptState, bool enabled)
{
v8::HandleScope handleScope;
return scriptState->context()->AllowCodeGenerationFromStrings(enabled);
}
ScriptState* mainWorldScriptState(Frame* frame)
{
v8::HandleScope handleScope;
......
......@@ -109,6 +109,9 @@ private:
DOMWindow* domWindowFromScriptState(ScriptState*);
bool evalEnabled(ScriptState*);
void setEvalEnabled(ScriptState*, bool);
ScriptState* mainWorldScriptState(Frame*);
ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
......
......@@ -66,22 +66,6 @@ ScriptValue InjectedScriptHost::nodeAsScriptValue(ScriptState* state, Node* node
return ScriptValue(toV8(node));
}
v8::Handle<v8::Value> V8InjectedScriptHost::evaluateCallback(const v8::Arguments& args)
{
INC_STATS("InjectedScriptHost.evaluate()");
if (args.Length() < 1)
return v8::ThrowException(v8::Exception::Error(v8::String::New("One argument expected.")));
v8::Handle<v8::String> expression = args[0]->ToString();
if (expression.IsEmpty())
return v8::ThrowException(v8::Exception::Error(v8::String::New("The argument must be a string.")));
v8::Handle<v8::Script> script = v8::Script::Compile(expression);
if (script.IsEmpty()) // Return immediately in case of exception to let the caller handle it.
return v8::Handle<v8::Value>();
return script->Run();
}
v8::Handle<v8::Value> V8InjectedScriptHost::inspectedNodeCallback(const v8::Arguments& args)
{
INC_STATS("InjectedScriptHost.inspectedNode()");
......
......@@ -208,7 +208,21 @@ void InjectedScript::makeCall(ScriptFunctionCall& function, RefPtr<InspectorValu
DOMWindow* domWindow = domWindowFromScriptState(m_injectedScriptObject.scriptState());
InspectorInstrumentationCookie cookie = domWindow && domWindow->frame() ? InspectorInstrumentation::willCallFunction(domWindow->frame()->page(), "InjectedScript", 1) : InspectorInstrumentationCookie();
bool hadException = false;
ScriptState* scriptState = m_injectedScriptObject.scriptState();
bool evalIsDisabled = false;
if (scriptState) {
evalIsDisabled = !evalEnabled(scriptState);
// Temporarily enable allow evals for inspector.
if (evalIsDisabled)
setEvalEnabled(scriptState, true);
}
ScriptValue resultValue = function.call(hadException);
if (evalIsDisabled)
setEvalEnabled(scriptState, false);
InspectorInstrumentation::didCallFunction(cookie);
ASSERT(!hadException);
......
......@@ -36,8 +36,6 @@ module core {
] InjectedScriptHost {
void clearConsoleMessages();
[Custom] DOMObject evaluate(in DOMString text);
void copyText(in DOMString text);
[Custom] void inspect(in DOMObject objectId, in DOMObject hints);
[Custom] DOMObject inspectedNode(in int num);
......
......@@ -141,7 +141,7 @@ InjectedScript.prototype = {
_parseObjectId: function(objectId)
{
return InjectedScriptHost.evaluate("(" + objectId + ")");
return eval("(" + objectId + ")");
},
releaseObjectGroup: function(objectGroupName)
......@@ -156,7 +156,7 @@ InjectedScript.prototype = {
dispatch: function(methodName, args)
{
var argsArray = InjectedScriptHost.evaluate("(" + args + ")");
var argsArray = eval("(" + args + ")");
var result = this[methodName].apply(this, argsArray);
if (typeof result === "undefined") {
inspectedWindow.console.error("Web Inspector error: InjectedScript.%s returns undefined", methodName);
......@@ -259,7 +259,7 @@ InjectedScript.prototype = {
evaluate: function(expression, objectGroup, injectCommandLineAPI, returnByValue)
{
return this._evaluateAndWrap(InjectedScriptHost.evaluate, InjectedScriptHost, expression, objectGroup, false, injectCommandLineAPI, returnByValue);
return this._evaluateAndWrap(inspectedWindow.eval, inspectedWindow, expression, objectGroup, false, injectCommandLineAPI, returnByValue);
},
callFunctionOn: function(objectId, expression, args, returnByValue)
......@@ -271,7 +271,7 @@ InjectedScript.prototype = {
if (args) {
var resolvedArgs = [];
args = InjectedScriptHost.evaluate(args);
args = eval(args);
for (var i = 0; i < args.length; ++i) {
var objectId = args[i].objectId;
if (objectId) {
......@@ -293,7 +293,7 @@ InjectedScript.prototype = {
try {
var objectGroup = this._idToObjectGroupName[parsedObjectId.id];
var func = InjectedScriptHost.evaluate("(" + expression + ")");
var func = eval("(" + expression + ")");
if (typeof func !== "function")
return "Given expression does not evaluate to a function";
......@@ -366,7 +366,7 @@ InjectedScript.prototype = {
_callFrameForId: function(topCallFrame, callFrameId)
{
var parsedCallFrameId = InjectedScriptHost.evaluate("(" + callFrameId + ")");
var parsedCallFrameId = eval("(" + callFrameId + ")");
var ordinal = parsedCallFrameId.ordinal;
var callFrame = topCallFrame;
while (--ordinal >= 0 && callFrame)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment