Revision: 15963
Author: [email protected]
Date: Tue Jul 30 10:05:50 2013
Log: Pipe a script's CORS status through V8 during compilation.
In order to properly sanitize exception data during a 'window.onerror'
handler, we need to know whether a script was served with proper CORS
headers at the time it was loaded into V8. This patch adds a single bool
to ScriptOrigin, and pipes that through the compiler to land on the
Script object. We can then retrieve the parameter when calling the
embedder's exception callback.
BUG=crbug.com/159566
[email protected]
Review URL: https://codereview.chromium.org/20646006
Patch from Mike West <[email protected]>.
http://code.google.com/p/v8/source/detail?r=15963
Modified:
/branches/bleeding_edge/include/v8.h
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/compilation-cache.cc
/branches/bleeding_edge/src/compilation-cache.h
/branches/bleeding_edge/src/compiler.cc
/branches/bleeding_edge/src/compiler.h
/branches/bleeding_edge/src/debug.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/test/cctest/test-api.cc
/branches/bleeding_edge/test/cctest/test-compiler.cc
=======================================
--- /branches/bleeding_edge/include/v8.h Tue Jul 30 00:05:15 2013
+++ /branches/bleeding_edge/include/v8.h Tue Jul 30 10:05:50 2013
@@ -942,17 +942,21 @@
V8_INLINE(ScriptOrigin(
Handle<Value> resource_name,
Handle<Integer> resource_line_offset = Handle<Integer>(),
- Handle<Integer> resource_column_offset = Handle<Integer>()))
+ Handle<Integer> resource_column_offset = Handle<Integer>(),
+ Handle<Boolean> resource_is_shared_cross_origin = Handle<Boolean>()))
: resource_name_(resource_name),
resource_line_offset_(resource_line_offset),
- resource_column_offset_(resource_column_offset) { }
+ resource_column_offset_(resource_column_offset),
+ resource_is_shared_cross_origin_(resource_is_shared_cross_origin)
{ }
V8_INLINE(Handle<Value> ResourceName() const);
V8_INLINE(Handle<Integer> ResourceLineOffset() const);
V8_INLINE(Handle<Integer> ResourceColumnOffset() const);
+ V8_INLINE(Handle<Boolean> ResourceIsSharedCrossOrigin() const);
private:
Handle<Value> resource_name_;
Handle<Integer> resource_line_offset_;
Handle<Integer> resource_column_offset_;
+ Handle<Boolean> resource_is_shared_cross_origin_;
};
@@ -1130,6 +1134,12 @@
*/
int GetEndColumn() const;
+ /**
+ * Passes on the value set by the embedder when it fed the script from
which
+ * this Message was generated to V8.
+ */
+ bool IsSharedCrossOrigin() const;
+
// TODO(1245381): Print to a string instead of on a FILE.
static void PrintCurrentStackTrace(FILE* out);
@@ -5995,6 +6005,10 @@
Handle<Integer> ScriptOrigin::ResourceColumnOffset() const {
return resource_column_offset_;
}
+
+Handle<Boolean> ScriptOrigin::ResourceIsSharedCrossOrigin() const {
+ return resource_is_shared_cross_origin_;
+}
Handle<Boolean> Boolean::New(bool value) {
=======================================
--- /branches/bleeding_edge/src/api.cc Tue Jul 30 01:35:48 2013
+++ /branches/bleeding_edge/src/api.cc Tue Jul 30 10:05:50 2013
@@ -1918,6 +1918,7 @@
i::Handle<i::Object> name_obj;
int line_offset = 0;
int column_offset = 0;
+ bool is_shared_cross_origin = false;
if (origin != NULL) {
if (!origin->ResourceName().IsEmpty()) {
name_obj = Utils::OpenHandle(*origin->ResourceName());
@@ -1929,6 +1930,10 @@
column_offset =
static_cast<int>(origin->ResourceColumnOffset()->Value());
}
+ if (!origin->ResourceIsSharedCrossOrigin().IsEmpty()) {
+ is_shared_cross_origin =
+ origin->ResourceIsSharedCrossOrigin() == v8::True();
+ }
}
EXCEPTION_PREAMBLE(isolate);
i::ScriptDataImpl* pre_data_impl =
@@ -1945,6 +1950,7 @@
name_obj,
line_offset,
column_offset,
+ is_shared_cross_origin,
isolate->global_context(),
NULL,
pre_data_impl,
@@ -2410,6 +2416,20 @@
int end = message->end_position();
return static_cast<int>(start_col_obj->Number()) + (end - start);
}
+
+
+bool Message::IsSharedCrossOrigin() const {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ if (IsDeadCheck(isolate, "v8::Message::IsSharedCrossOrigin()")) return 0;
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ i::Handle<i::JSMessageObject> message =
+ i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
+ i::Handle<i::JSValue> script =
+ i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
+ isolate));
+ return i::Script::cast(script->value())->is_shared_cross_origin();
+}
Local<String> Message::GetSourceLine() const {
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue Jul 30 09:33:08 2013
+++ /branches/bleeding_edge/src/bootstrapper.cc Tue Jul 30 10:05:50 2013
@@ -1525,6 +1525,7 @@
script_name,
0,
0,
+ false,
top_context,
extension,
NULL,
=======================================
--- /branches/bleeding_edge/src/compilation-cache.cc Fri Jul 5 02:52:11
2013
+++ /branches/bleeding_edge/src/compilation-cache.cc Tue Jul 30 10:05:50
2013
@@ -144,7 +144,8 @@
Handle<SharedFunctionInfo> function_info,
Handle<Object> name,
int line_offset,
- int column_offset) {
+ int column_offset,
+ bool is_shared_cross_origin) {
Handle<Script> script =
Handle<Script>(Script::cast(function_info->script()), isolate());
// If the script name isn't set, the boilerplate script should have
@@ -157,6 +158,8 @@
if (column_offset != script->column_offset()->value()) return false;
// Check that both names are strings. If not, no match.
if (!name->IsString() || !script->name()->IsString()) return false;
+ // Were both scripts tagged by the embedder as being shared cross-origin?
+ if (is_shared_cross_origin != script->is_shared_cross_origin()) return
false;
// Compare the two name strings for equality.
return String::cast(*name)->Equals(String::cast(script->name()));
}
@@ -171,6 +174,7 @@
Handle<Object> name,
int line_offset,
int column_offset,
+ bool is_shared_cross_origin,
Handle<Context> context) {
Object* result = NULL;
int generation;
@@ -186,7 +190,11 @@
Handle<SharedFunctionInfo>::cast(probe);
// Break when we've found a suitable shared function info that
// matches the origin.
- if (HasOrigin(function_info, name, line_offset, column_offset)) {
+ if (HasOrigin(function_info,
+ name,
+ line_offset,
+ column_offset,
+ is_shared_cross_origin)) {
result = *function_info;
break;
}
@@ -214,7 +222,11 @@
if (result != NULL) {
Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result),
isolate());
- ASSERT(HasOrigin(shared, name, line_offset, column_offset));
+ ASSERT(HasOrigin(shared,
+ name,
+ line_offset,
+ column_offset,
+ is_shared_cross_origin));
// If the script was found in a later generation, we promote it to
// the first generation to let it survive longer in the cache.
if (generation != 0) Put(source, context, shared);
@@ -391,12 +403,18 @@
Handle<Object> name,
int line_offset,
int column_offset,
+ bool is_shared_cross_origin,
Handle<Context> context) {
if (!IsEnabled()) {
return Handle<SharedFunctionInfo>::null();
}
- return script_.Lookup(source, name, line_offset, column_offset, context);
+ return script_.Lookup(source,
+ name,
+ line_offset,
+ column_offset,
+ is_shared_cross_origin,
+ context);
}
=======================================
--- /branches/bleeding_edge/src/compilation-cache.h Tue Aug 28 03:49:23 2012
+++ /branches/bleeding_edge/src/compilation-cache.h Tue Jul 30 10:05:50 2013
@@ -99,6 +99,7 @@
Handle<Object> name,
int line_offset,
int column_offset,
+ bool is_shared_cross_origin,
Handle<Context> context);
void Put(Handle<String> source,
Handle<Context> context,
@@ -119,7 +120,8 @@
bool HasOrigin(Handle<SharedFunctionInfo> function_info,
Handle<Object> name,
int line_offset,
- int column_offset);
+ int column_offset,
+ bool is_shared_cross_origin);
void* script_histogram_;
bool script_histogram_initialized_;
@@ -212,6 +214,7 @@
Handle<Object> name,
int line_offset,
int column_offset,
+ bool is_shared_cross_origin,
Handle<Context> context);
// Finds the shared function info for a source string for eval in a
=======================================
--- /branches/bleeding_edge/src/compiler.cc Tue Jul 30 10:00:05 2013
+++ /branches/bleeding_edge/src/compiler.cc Tue Jul 30 10:05:50 2013
@@ -667,6 +667,7 @@
Handle<Object> script_name,
int line_offset,
int column_offset,
+ bool is_shared_cross_origin,
Handle<Context> context,
v8::Extension* extension,
ScriptDataImpl* pre_data,
@@ -689,6 +690,7 @@
script_name,
line_offset,
column_offset,
+ is_shared_cross_origin,
context);
}
@@ -712,6 +714,7 @@
script->set_line_offset(Smi::FromInt(line_offset));
script->set_column_offset(Smi::FromInt(column_offset));
}
+ script->set_is_shared_cross_origin(is_shared_cross_origin);
script->set_data(script_data.is_null() ? HEAP->undefined_value()
: *script_data);
=======================================
--- /branches/bleeding_edge/src/compiler.h Wed Jul 17 01:44:10 2013
+++ /branches/bleeding_edge/src/compiler.h Tue Jul 30 10:05:50 2013
@@ -572,6 +572,7 @@
Handle<Object> script_name,
int line_offset,
int column_offset,
+ bool is_shared_cross_origin,
Handle<Context> context,
v8::Extension* extension,
ScriptDataImpl* pre_data,
=======================================
--- /branches/bleeding_edge/src/debug.cc Tue Jul 30 01:35:48 2013
+++ /branches/bleeding_edge/src/debug.cc Tue Jul 30 10:05:50 2013
@@ -786,6 +786,7 @@
function_info = Compiler::Compile(source_code,
script_name,
0, 0,
+ false,
context,
NULL, NULL,
Handle<String>::null(),
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Tue Jul 30 10:00:05 2013
+++ /branches/bleeding_edge/src/objects-inl.h Tue Jul 30 10:05:50 2013
@@ -4499,6 +4499,7 @@
ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
kEvalFrominstructionsOffsetOffset)
ACCESSORS_TO_SMI(Script, flags, kFlagsOffset)
+BOOL_ACCESSORS(Script, flags, is_shared_cross_origin,
kIsSharedCrossOriginBit)
Script::CompilationType Script::compilation_type() {
return BooleanBit::get(flags(), kCompilationTypeBit) ?
=======================================
--- /branches/bleeding_edge/src/objects.h Tue Jul 30 10:00:05 2013
+++ /branches/bleeding_edge/src/objects.h Tue Jul 30 10:05:50 2013
@@ -5876,6 +5876,12 @@
inline CompilationState compilation_state();
inline void set_compilation_state(CompilationState state);
+ // [is_shared_cross_origin]: An opaque boolean set by the embedder via
+ // ScriptOrigin, and used by the embedder to make decisions about the
+ // script's level of privilege. V8 just passes this through. Encoded in
+ // the 'flags' field.
+ DECL_BOOLEAN_ACCESSORS(is_shared_cross_origin)
+
static inline Script* cast(Object* obj);
// If script source is an external string, check that the underlying
@@ -5907,6 +5913,7 @@
// Bit positions in the flags field.
static const int kCompilationTypeBit = 0;
static const int kCompilationStateBit = 1;
+ static const int kIsSharedCrossOriginBit = 2;
DISALLOW_IMPLICIT_CONSTRUCTORS(Script);
};
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Tue Jul 30 00:05:15 2013
+++ /branches/bleeding_edge/test/cctest/test-api.cc Tue Jul 30 10:05:50 2013
@@ -3565,6 +3565,7 @@
CHECK_EQ(5.76, data->NumberValue());
CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
CHECK_EQ(7.56, message->GetScriptData()->NumberValue());
+ CHECK(!message->IsSharedCrossOrigin());
message_received = true;
}
@@ -3591,6 +3592,7 @@
v8::Handle<Value> data) {
CHECK(data->IsNumber());
CHECK_EQ(1337, data->Int32Value());
+ CHECK(!message->IsSharedCrossOrigin());
message_received = true;
}
@@ -3615,6 +3617,7 @@
v8::Local<v8::Value> hidden_property =
v8::Object::Cast(*data)->GetHiddenValue(v8_str("hidden key"));
CHECK(v8_str("hidden value")->Equals(hidden_property));
+ CHECK(!message->IsSharedCrossOrigin());
message_received = true;
}
@@ -3634,6 +3637,112 @@
// clear out the message listener
v8::V8::RemoveMessageListeners(check_message_2);
}
+
+
+static void check_message_3(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
+ CHECK(message->IsSharedCrossOrigin());
+ CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ message_received = true;
+}
+
+
+TEST(MessageHandler3) {
+ message_received = false;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ CHECK(!message_received);
+ v8::V8::AddMessageListener(check_message_3);
+ LocalContext context;
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8_str("6.75"),
+ v8::Integer::New(1),
+ v8::Integer::New(2),
+ v8::True());
+ v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
+ &origin);
+ script->Run();
+ CHECK(message_received);
+ // clear out the message listener
+ v8::V8::RemoveMessageListeners(check_message_3);
+}
+
+
+static void check_message_4(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
+ CHECK(!message->IsSharedCrossOrigin());
+ CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ message_received = true;
+}
+
+
+TEST(MessageHandler4) {
+ message_received = false;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ CHECK(!message_received);
+ v8::V8::AddMessageListener(check_message_4);
+ LocalContext context;
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8_str("6.75"),
+ v8::Integer::New(1),
+ v8::Integer::New(2),
+ v8::False());
+ v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
+ &origin);
+ script->Run();
+ CHECK(message_received);
+ // clear out the message listener
+ v8::V8::RemoveMessageListeners(check_message_4);
+}
+
+
+static void check_message_5a(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
+ CHECK(message->IsSharedCrossOrigin());
+ CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ message_received = true;
+}
+
+
+static void check_message_5b(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
+ CHECK(!message->IsSharedCrossOrigin());
+ CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
+ message_received = true;
+}
+
+
+TEST(MessageHandler5) {
+ message_received = false;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ CHECK(!message_received);
+ v8::V8::AddMessageListener(check_message_5a);
+ LocalContext context;
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8_str("6.75"),
+ v8::Integer::New(1),
+ v8::Integer::New(2),
+ v8::True());
+ v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
+ &origin);
+ script->Run();
+ CHECK(message_received);
+ // clear out the message listener
+ v8::V8::RemoveMessageListeners(check_message_5a);
+
+ message_received = false;
+ v8::V8::AddMessageListener(check_message_5b);
+ origin =
+ v8::ScriptOrigin(v8_str("6.75"),
+ v8::Integer::New(1),
+ v8::Integer::New(2),
+ v8::False());
+ script = Script::Compile(v8_str("throw 'error'"),
+ &origin);
+ script->Run();
+ CHECK(message_received);
+ // clear out the message listener
+ v8::V8::RemoveMessageListeners(check_message_5b);
+}
THREADED_TEST(GetSetProperty) {
=======================================
--- /branches/bleeding_edge/test/cctest/test-compiler.cc Tue Jun 25
04:16:13 2013
+++ /branches/bleeding_edge/test/cctest/test-compiler.cc Tue Jul 30
10:05:50 2013
@@ -105,6 +105,7 @@
Handle<String>(),
0,
0,
+ false,
Handle<Context>(isolate->native_context()),
NULL,
NULL,
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.