Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(547)

Unified Diff: test/cctest/test-object-observe.cc

Issue 22962009: Add access check for observed objects (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Nearly complete Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-object-observe.cc
diff --git a/test/cctest/test-object-observe.cc b/test/cctest/test-object-observe.cc
index 44ddb6fa2061a482dacdf1c639080c922a0cd47a..677c3f891720bf2ee4acb9bdeeec854ed945fe29 100644
--- a/test/cctest/test-object-observe.cc
+++ b/test/cctest/test-object-observe.cc
@@ -313,11 +313,13 @@ static void ExpectRecords(Handle<Value> records,
recordObj->Get(String::New("object"))));
CHECK(String::New(expectations[i].type)->Equals(
recordObj->Get(String::New("type"))));
- CHECK(String::New(expectations[i].name)->Equals(
- recordObj->Get(String::New("name"))));
- if (!expectations[i].old_value.IsEmpty()) {
- CHECK(expectations[i].old_value->Equals(
- recordObj->Get(String::New("oldValue"))));
+ if (strcmp("splice", expectations[i].type) != 0) {
+ CHECK(String::New(expectations[i].name)->Equals(
+ recordObj->Get(String::New("name"))));
+ if (!expectations[i].old_value.IsEmpty()) {
+ CHECK(expectations[i].old_value->Equals(
+ recordObj->Get(String::New("oldValue"))));
+ }
}
}
}
@@ -446,3 +448,150 @@ TEST(ObservationWeakMap) {
CHECK_EQ(0, NumberOfElements(objectInfoMap));
CHECK_EQ(0, NumberOfElements(notifierTargetMap));
}
+
+
+static bool NamedAccessAlwaysAllowed(Local<Object>, Local<Value>, AccessType,
+ Local<Value>) {
+ return true;
+}
+
+
+static bool IndexedAccessAlwaysAllowed(Local<Object>, uint32_t, AccessType,
+ Local<Value>) {
+ return true;
+}
+
+
+static bool NamedAccessAllowUnlessBlocked(Local<Object> host, Local<Value> key,
+ AccessType type, Local<Value>) {
+ Handle<Context> context = Context::GetCurrent();
+ return !context->Global()->Get(String::New("blockAccess"))->BooleanValue();
+}
+
+
+static bool IndexedAccessAllowUnlessBlocked(Local<Object> host, uint32_t index,
+ AccessType type, Local<Value>) {
+ Handle<Context> context = Context::GetCurrent();
+ return !context->Global()->Get(String::New("blockAccess"))->BooleanValue();
+}
+
+
+TEST(ObserveNamedAccessCheck) {
rossberg 2013/08/16 13:51:54 Would be good to refine the test such that only in
adamk 2013/08/20 21:38:16 Done.
+ HarmonyIsolate isolate;
+ HandleScope scope;
+ LocalContext context;
+ Handle<ObjectTemplate> tmpl = ObjectTemplate::New();
+ tmpl->SetAccessCheckCallbacks(NamedAccessAllowUnlessBlocked,
+ IndexedAccessAlwaysAllowed);
+ Handle<Object> instance = tmpl->NewInstance();
+ context->Global()->Set(String::New("obj"), instance);
+ CompileRun("records = null;"
rossberg 2013/08/16 13:51:54 Nit: can we make these proper 'var' declarations?
adamk 2013/08/20 21:38:16 Done.
+ "objNoCheck = {};"
+ "blockAccess = true;"
+ "observer = function(r) { records = r };"
+ "Object.observe(obj, observer);"
+ "Object.observe(objNoCheck, observer);");
+ Handle<Value> obj_no_check = CompileRun("objNoCheck");
+ {
+ LocalContext context2;
+ context2->Global()->Set(String::New("obj"), instance);
+ context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
+ CompileRun("records2 = null;"
rossberg 2013/08/16 13:51:54 Same here.
adamk 2013/08/20 21:38:16 Done.
+ "observer2 = function(r) { records2 = r };"
+ "Object.observe(obj, observer2);"
+ "Object.observe(objNoCheck, observer2);"
+ "obj.foo = 'bar';"
rossberg 2013/08/16 13:51:54 Please add other forms of mutation, in particular,
adamk 2013/08/20 21:38:16 Happy to expand this a little bit, but I'd be inte
+ "objNoCheck.baz = 'quux'");
+ const RecordExpectation expected_records2[] = {
+ { instance, "new", "foo", Handle<Value>() },
+ { obj_no_check, "new", "baz", Handle<Value>() },
+ };
+ EXPECT_RECORDS(CompileRun("records2"), expected_records2);
+ }
+ const RecordExpectation expected_records[] = {
+ { obj_no_check, "new", "baz", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records"), expected_records);
+}
+
+
+TEST(ObserveIndexedAccessCheck) {
+ HarmonyIsolate isolate;
+ HandleScope scope;
+ LocalContext context;
+ Handle<ObjectTemplate> tmpl = ObjectTemplate::New();
+ tmpl->SetAccessCheckCallbacks(NamedAccessAlwaysAllowed,
+ IndexedAccessAllowUnlessBlocked);
+ Handle<Object> instance = tmpl->NewInstance();
+ context->Global()->Set(String::New("obj"), instance);
+ CompileRun("records = null;"
+ "objNoCheck = {};"
+ "blockAccess = true;"
+ "observer = function(r) { records = r };"
+ "Object.observe(obj, observer);"
+ "Object.observe(objNoCheck, observer);");
+ Handle<Value> obj_no_check = CompileRun("objNoCheck");
+ {
+ LocalContext context2;
+ context2->Global()->Set(String::New("obj"), instance);
+ context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
+ CompileRun("records2 = null;"
+ "observer2 = function(r) { records2 = r };"
+ "Object.observe(obj, observer2);"
+ "Object.observe(objNoCheck, observer2);"
+ "obj[7] = 'bar';"
+ "objNoCheck[42] = 'quux'");
+ const RecordExpectation expected_records2[] = {
+ { instance, "new", "7", Handle<Value>() },
+ { obj_no_check, "new", "42", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records2"), expected_records2);
+ }
+ const RecordExpectation expected_records[] = {
+ { obj_no_check, "new", "42", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records"), expected_records);
+}
+
+
+TEST(ObserveSpliceAccessCheck) {
+ HarmonyIsolate isolate;
+ HandleScope scope;
+ LocalContext context;
+ Handle<ObjectTemplate> tmpl = ObjectTemplate::New();
+ tmpl->SetAccessCheckCallbacks(NamedAccessAlwaysAllowed,
+ IndexedAccessAllowUnlessBlocked);
+ Handle<Object> instance = tmpl->NewInstance();
+ context->Global()->Set(String::New("obj"), instance);
+ CompileRun("records = null;"
+ "obj[1] = 'foo';"
+ "obj.length = 2;"
+ "objNoCheck = {1: 'bar', length: 2};"
+ "blockAccess = true;"
+ "observer = function(r) { records = r };"
+ "Array.observe(obj, observer);"
+ "Array.observe(objNoCheck, observer);");
+ Handle<Value> obj_no_check = CompileRun("objNoCheck");
+ {
+ LocalContext context2;
+ context2->Global()->Set(String::New("obj"), instance);
+ context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
+ CompileRun("records2 = null;"
+ "observer2 = function(r) { records2 = r };"
+ "Array.observe(obj, observer2);"
+ "Array.observe(objNoCheck, observer2);"
+ // No one should hear about this: no splice records are emitted
+ // for access-checked objects
+ "[].pop.call(obj);"
rossberg 2013/08/16 13:51:54 Can we check some more complex array functions, to
adamk 2013/08/20 21:38:16 How complex do you want? It's not clear to me what
rossberg 2013/08/21 10:45:52 Doesn't have to be crazy. I'd be content with one
adamk 2013/08/21 17:18:36 The nature of splice records is that there aren't
+ "[].pop.call(objNoCheck);");
+ // TODO(adamk): Support splice records
rossberg 2013/08/16 13:51:54 What is this TODO about?
adamk 2013/08/20 21:38:16 Made it longer.
+ const RecordExpectation expected_records2[] = {
+ { obj_no_check, "splice", "", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records2"), expected_records2);
+ }
+ const RecordExpectation expected_records[] = {
+ { obj_no_check, "splice", "", Handle<Value>() }
+ };
+ EXPECT_RECORDS(CompileRun("records"), expected_records);
+}
« no previous file with comments | « src/runtime.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698