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

Reply via email to