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

Allow evals for debugger even if they are prohibited in the debugee context.

BUG=154733
Review URL: https://codereview.chromium.org/11111015

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12726 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3d0d2117
...@@ -11793,6 +11793,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { ...@@ -11793,6 +11793,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
scope_info, scope_info,
function_context); function_context);
// Check if eval is blocked in the context and temporarily allow it
// for debugger.
Handle<Context> native_context = Handle<Context>(context->native_context());
bool eval_disabled =
native_context->allow_code_gen_from_strings()->IsFalse();
if (eval_disabled) {
native_context->set_allow_code_gen_from_strings(
isolate->heap()->true_value());
}
// Invoke the evaluation function and return the result. // Invoke the evaluation function and return the result.
Handle<Object> argv[] = { arguments, source }; Handle<Object> argv[] = { arguments, source };
Handle<Object> result = Handle<Object> result =
...@@ -11801,6 +11810,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { ...@@ -11801,6 +11810,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
ARRAY_SIZE(argv), ARRAY_SIZE(argv),
argv, argv,
&has_pending_exception); &has_pending_exception);
if (eval_disabled) {
native_context->set_allow_code_gen_from_strings(
isolate->heap()->false_value());
}
if (has_pending_exception) return Failure::Exception(); if (has_pending_exception) return Failure::Exception();
// Skip the global proxy as it has no properties and always delegates to the // Skip the global proxy as it has no properties and always delegates to the
......
...@@ -2381,7 +2381,7 @@ TEST(DebuggerStatementBreakpoint) { ...@@ -2381,7 +2381,7 @@ TEST(DebuggerStatementBreakpoint) {
} }
// Thest that the evaluation of expressions when a break point is hit generates // Test that the evaluation of expressions when a break point is hit generates
// the correct results. // the correct results.
TEST(DebugEvaluate) { TEST(DebugEvaluate) {
v8::HandleScope scope; v8::HandleScope scope;
...@@ -2497,6 +2497,98 @@ TEST(DebugEvaluate) { ...@@ -2497,6 +2497,98 @@ TEST(DebugEvaluate) {
CheckDebuggerUnloaded(); CheckDebuggerUnloaded();
} }
int debugEventCount = 0;
static void CheckDebugEvent(const v8::Debug::EventDetails& eventDetails) {
if (eventDetails.GetEvent() == v8::Break) ++debugEventCount;
}
// Test that the conditional breakpoints work event if code generation from
// strings is prohibited in the debugee context.
TEST(ConditionalBreakpointWithCodeGenerationDisallowed) {
v8::HandleScope scope;
DebugLocalContext env;
env.ExposeDebug();
v8::Debug::SetDebugEventListener2(CheckDebugEvent);
v8::Local<v8::Function> foo = CompileFunction(&env,
"function foo(x) {\n"
" var s = 'String value2';\n"
" return s + x;\n"
"}",
"foo");
// Set conditional breakpoint with condition 'true'.
CompileRun("debug.Debug.setBreakPoint(foo, 2, 0, 'true')");
debugEventCount = 0;
env->AllowCodeGenerationFromStrings(false);
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, debugEventCount);
v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
bool checkedDebugEvals = true;
v8::Handle<v8::Function> checkGlobalEvalFunction;
v8::Handle<v8::Function> checkFrameEvalFunction;
static void CheckDebugEval(const v8::Debug::EventDetails& eventDetails) {
if (eventDetails.GetEvent() == v8::Break) {
++debugEventCount;
v8::HandleScope handleScope;
v8::Handle<v8::Value> args[] = { eventDetails.GetExecutionState() };
CHECK(checkGlobalEvalFunction->Call(
eventDetails.GetEventContext()->Global(), 1, args)->IsTrue());
CHECK(checkFrameEvalFunction->Call(
eventDetails.GetEventContext()->Global(), 1, args)->IsTrue());
}
}
// Test that the evaluation of expressions when a break point is hit generates
// the correct results in case code generation from strings is disallowed in the
// debugee context.
TEST(DebugEvaluateWithCodeGenerationDisallowed) {
v8::HandleScope scope;
DebugLocalContext env;
env.ExposeDebug();
v8::Debug::SetDebugEventListener2(CheckDebugEval);
v8::Local<v8::Function> foo = CompileFunction(&env,
"var global = 'Global';\n"
"function foo(x) {\n"
" var local = 'Local';\n"
" debugger;\n"
" return local + x;\n"
"}",
"foo");
checkGlobalEvalFunction = CompileFunction(&env,
"function checkGlobalEval(exec_state) {\n"
" return exec_state.evaluateGlobal('global').value() === 'Global';\n"
"}",
"checkGlobalEval");
checkFrameEvalFunction = CompileFunction(&env,
"function checkFrameEval(exec_state) {\n"
" return exec_state.frame(0).evaluate('local').value() === 'Local';\n"
"}",
"checkFrameEval");
debugEventCount = 0;
env->AllowCodeGenerationFromStrings(false);
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, debugEventCount);
checkGlobalEvalFunction.Clear();
checkFrameEvalFunction.Clear();
v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
// Copies a C string to a 16-bit string. Does not check for buffer overflow. // Copies a C string to a 16-bit string. Does not check for buffer overflow.
// Does not use the V8 engine to convert strings, so it can be used // Does not use the V8 engine to convert strings, so it can be used
// in any thread. Returns the length of the string. // in any thread. Returns the length of the string.
......
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