Reviewers: Sven Panne, Mike West (chromium),
Message:
Please take a look.
Description:
Throw a more descriptive exception when blocking 'eval' via CSP.
BUG=140191
[email protected],[email protected]
Please review this at https://chromiumcodereview.appspot.com/10837358/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M include/v8.h
M src/api.cc
M src/contexts.h
M src/contexts.cc
M src/messages.js
M src/runtime.cc
Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index
b210638871c08b4f1e9ef050f184b7307dbf639a..d4bc6c635a4c06194bbe2ee50e623b63f04dd3c6
100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -3644,8 +3644,13 @@ class V8EXPORT Context {
* constructor. If that callback returns true, the call will be
* allowed, otherwise an exception will be thrown. If no callback is
* set an exception will be thrown.
+ *
+ * If the 'error_message' is provided and code generation from strings
+ * is not allowed, then it will used as an error description for
+ * the exception to be thrown.
*/
- void AllowCodeGenerationFromStrings(bool allow);
+ void AllowCodeGenerationFromStrings(
+ bool allow, Handle<String> error_message = Handle<String>());
/**
* Returns true if code generation from strings is allowed for the
context.
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index
c8a9e90821a1ced337c8b3ddfed526f7c6cfc69f..bda49f8570eb17fc061f88e561f08a8102a06a53
100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -4539,7 +4539,8 @@ void Context::ReattachGlobal(Handle<Object>
global_object) {
}
-void Context::AllowCodeGenerationFromStrings(bool allow) {
+void Context::AllowCodeGenerationFromStrings(bool allow,
+ Handle<String> error_message)
{
i::Isolate* isolate = i::Isolate::Current();
if
(IsDeadCheck(isolate, "v8::Context::AllowCodeGenerationFromStrings()")) {
return;
@@ -4548,8 +4549,16 @@ void Context::AllowCodeGenerationFromStrings(bool
allow) {
i::Object** ctx = reinterpret_cast<i::Object**>(this);
i::Handle<i::Context> context =
i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
- context->set_allow_code_gen_from_strings(
- allow ? isolate->heap()->true_value() :
isolate->heap()->false_value());
+ if (allow) {
+ context->AllowCodeGenerationFromStrings();
+ } else {
+ const char* default_error =
+ "Code generation from strings disallowed for this context";
+ i::Handle<i::String> error = error_message.IsEmpty()
+ ?
isolate->factory()->NewStringFromAscii(i::CStrVector(default_error))
+ : Utils::OpenHandle(*error_message);
+ context->ForbidCodeGenerationFromStrings(error);
+ }
}
@@ -4563,7 +4572,7 @@ bool Context::IsCodeGenerationFromStringsAllowed() {
i::Object** ctx = reinterpret_cast<i::Object**>(this);
i::Handle<i::Context> context =
i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
- return !context->allow_code_gen_from_strings()->IsFalse();
+ return context->IsCodeGenerationFromStringsAllowed();
}
Index: src/contexts.cc
diff --git a/src/contexts.cc b/src/contexts.cc
index
ef480527ff718b41c85f26399d692e3bf521bb42..a9d31c99f989af553fd91aeaccf2c46cdc63e77f
100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -305,6 +305,26 @@ void Context::ClearOptimizedFunctions() {
}
+void Context::AllowCodeGenerationFromStrings() {
+
set_error_message_for_code_gen_from_strings(GetHeap()->undefined_value());
+}
+
+
+void Context::ForbidCodeGenerationFromStrings(Handle<String>
error_message) {
+ set_error_message_for_code_gen_from_strings(*error_message);
+}
+
+
+bool Context::IsCodeGenerationFromStringsAllowed() {
+ return error_message_for_code_gen_from_strings()->IsUndefined();
+}
+
+
+Handle<Object> Context::ErrorMessageForCodeGenerationFromStrings() {
+ return Handle<Object>(error_message_for_code_gen_from_strings());
+}
+
+
#ifdef DEBUG
bool Context::IsBootstrappingOrValidParentContext(
Object* object, Context* child) {
Index: src/contexts.h
diff --git a/src/contexts.h b/src/contexts.h
index
8df16dd50ac47f897720f1d1c738944e3043c396..e1b1d0d2cd98cf63ad2152b5d140bf3724d548cc
100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -153,7 +153,8 @@ enum BindingFlags {
V(OUT_OF_MEMORY_INDEX, Object, out_of_memory) \
V(MAP_CACHE_INDEX, Object, map_cache) \
V(CONTEXT_DATA_INDEX, Object, data) \
- V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object,
allow_code_gen_from_strings) \
+ V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
+ error_message_for_code_gen_from_strings) \
V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
to_complete_property_descriptor) \
V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
@@ -279,7 +280,7 @@ class Context: public FixedArray {
CONTEXT_EXTENSION_FUNCTION_INDEX,
OUT_OF_MEMORY_INDEX,
CONTEXT_DATA_INDEX,
- ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
+ ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX,
TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX,
DERIVED_HAS_TRAP_INDEX,
DERIVED_GET_TRAP_INDEX,
@@ -376,6 +377,11 @@ class Context: public FixedArray {
Object* OptimizedFunctionsListHead();
void ClearOptimizedFunctions();
+ void AllowCodeGenerationFromStrings();
+ void ForbidCodeGenerationFromStrings(Handle<String> error_message);
+ bool IsCodeGenerationFromStringsAllowed();
+ Handle<Object> ErrorMessageForCodeGenerationFromStrings();
+
#define NATIVE_CONTEXT_FIELD_ACCESSORS(index, type, name) \
void set_##name(type* value) { \
ASSERT(IsNativeContext()); \
Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index
4da38051f9200746250867e23f9cc4228c524178..179ad7274c4bb29324ec945eab8064c8a613255a
100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -140,7 +140,7 @@ function FormatMessage(message) {
var messagesDictionary = [
// Error
"cyclic_proto", ["Cyclic __proto__ value"],
- "code_gen_from_strings", ["Code generation from strings
disallowed for this context"],
+ "code_gen_from_strings", ["%0"],
// TypeError
"unexpected_token", ["Unexpected token ", "%0"],
"unexpected_token_number", ["Unexpected number"],
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
3017f3f1e50710a3650032b9f78297435a64d18f..67d26ff12b5e11fc904d402b9ebe32368f93485f
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -9025,7 +9025,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
bool CodeGenerationFromStringsAllowed(Isolate* isolate,
Handle<Context> context) {
- ASSERT(context->allow_code_gen_from_strings()->IsFalse());
+ ASSERT(!context->IsCodeGenerationFromStringsAllowed());
// Check with callback if set.
AllowCodeGenerationFromStringsCallback callback =
isolate->allow_code_gen_callback();
@@ -9050,10 +9050,12 @@ RUNTIME_FUNCTION(MaybeObject*,
Runtime_CompileString) {
// Check if native context allows code generation from
// strings. Throw an exception if it doesn't.
- if (context->allow_code_gen_from_strings()->IsFalse() &&
+ if (!context->IsCodeGenerationFromStringsAllowed() &&
!CodeGenerationFromStringsAllowed(isolate, context)) {
- return isolate->Throw(*isolate->factory()->NewError(
- "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
+ Handle<Object> error_message =
+ context->ErrorMessageForCodeGenerationFromStrings();
+ return isolate->Throw(*isolate->factory()->NewEvalError(
+ "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
}
// Compile source string in the native context.
@@ -9078,10 +9080,12 @@ static ObjectPair CompileGlobalEval(Isolate*
isolate,
// Check if native context allows code generation from
// strings. Throw an exception if it doesn't.
- if (native_context->allow_code_gen_from_strings()->IsFalse() &&
+ if (!native_context->IsCodeGenerationFromStringsAllowed() &&
!CodeGenerationFromStringsAllowed(isolate, native_context)) {
- isolate->Throw(*isolate->factory()->NewError(
- "code_gen_from_strings", HandleVector<Object>(NULL, 0)));
+ Handle<Object> error_message =
+ native_context->ErrorMessageForCodeGenerationFromStrings();
+ isolate->Throw(*isolate->factory()->NewEvalError(
+ "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
return MakePair(Failure::Exception(), NULL);
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev