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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 Handle<Array> recordArray = records.As<Array>(); 306 Handle<Array> recordArray = records.As<Array>();
307 CHECK_EQ(num, static_cast<int>(recordArray->Length())); 307 CHECK_EQ(num, static_cast<int>(recordArray->Length()));
308 for (int i = 0; i < num; ++i) { 308 for (int i = 0; i < num; ++i) {
309 Handle<Value> record = recordArray->Get(i); 309 Handle<Value> record = recordArray->Get(i);
310 CHECK(record->IsObject()); 310 CHECK(record->IsObject());
311 Handle<Object> recordObj = record.As<Object>(); 311 Handle<Object> recordObj = record.As<Object>();
312 CHECK(expectations[i].object->StrictEquals( 312 CHECK(expectations[i].object->StrictEquals(
313 recordObj->Get(String::New("object")))); 313 recordObj->Get(String::New("object"))));
314 CHECK(String::New(expectations[i].type)->Equals( 314 CHECK(String::New(expectations[i].type)->Equals(
315 recordObj->Get(String::New("type")))); 315 recordObj->Get(String::New("type"))));
316 CHECK(String::New(expectations[i].name)->Equals( 316 if (strcmp("splice", expectations[i].type) != 0) {
317 recordObj->Get(String::New("name")))); 317 CHECK(String::New(expectations[i].name)->Equals(
318 if (!expectations[i].old_value.IsEmpty()) { 318 recordObj->Get(String::New("name"))));
319 CHECK(expectations[i].old_value->Equals( 319 if (!expectations[i].old_value.IsEmpty()) {
320 recordObj->Get(String::New("oldValue")))); 320 CHECK(expectations[i].old_value->Equals(
321 recordObj->Get(String::New("oldValue"))));
322 }
321 } 323 }
322 } 324 }
323 } 325 }
324 326
325 #define EXPECT_RECORDS(records, expectations) \ 327 #define EXPECT_RECORDS(records, expectations) \
326 ExpectRecords(records, expectations, ARRAY_SIZE(expectations)) 328 ExpectRecords(records, expectations, ARRAY_SIZE(expectations))
327 329
328 TEST(APITestBasicMutation) { 330 TEST(APITestBasicMutation) {
329 HarmonyIsolate isolate; 331 HarmonyIsolate isolate;
330 HandleScope scope(isolate.GetIsolate()); 332 HandleScope scope(isolate.GetIsolate());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 i::Handle<i::JSWeakMap>::cast( 441 i::Handle<i::JSWeakMap>::cast(
440 i::GetProperty(observation_state, "notifierTargetMap")); 442 i::GetProperty(observation_state, "notifierTargetMap"));
441 CHECK_EQ(1, NumberOfElements(callbackInfoMap)); 443 CHECK_EQ(1, NumberOfElements(callbackInfoMap));
442 CHECK_EQ(1, NumberOfElements(objectInfoMap)); 444 CHECK_EQ(1, NumberOfElements(objectInfoMap));
443 CHECK_EQ(1, NumberOfElements(notifierTargetMap)); 445 CHECK_EQ(1, NumberOfElements(notifierTargetMap));
444 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); 446 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
445 CHECK_EQ(0, NumberOfElements(callbackInfoMap)); 447 CHECK_EQ(0, NumberOfElements(callbackInfoMap));
446 CHECK_EQ(0, NumberOfElements(objectInfoMap)); 448 CHECK_EQ(0, NumberOfElements(objectInfoMap));
447 CHECK_EQ(0, NumberOfElements(notifierTargetMap)); 449 CHECK_EQ(0, NumberOfElements(notifierTargetMap));
448 } 450 }
451
452
453 static bool NamedAccessAlwaysAllowed(Local<Object>, Local<Value>, AccessType,
454 Local<Value>) {
455 return true;
456 }
457
458
459 static bool IndexedAccessAlwaysAllowed(Local<Object>, uint32_t, AccessType,
460 Local<Value>) {
461 return true;
462 }
463
464
465 static bool NamedAccessAllowUnlessBlocked(Local<Object> host, Local<Value> key,
466 AccessType type, Local<Value>) {
467 Handle<Context> context = Context::GetCurrent();
468 return !context->Global()->Get(String::New("blockAccess"))->BooleanValue();
469 }
470
471
472 static bool IndexedAccessAllowUnlessBlocked(Local<Object> host, uint32_t index,
473 AccessType type, Local<Value>) {
474 Handle<Context> context = Context::GetCurrent();
475 return !context->Global()->Get(String::New("blockAccess"))->BooleanValue();
476 }
477
478
479 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.
480 HarmonyIsolate isolate;
481 HandleScope scope;
482 LocalContext context;
483 Handle<ObjectTemplate> tmpl = ObjectTemplate::New();
484 tmpl->SetAccessCheckCallbacks(NamedAccessAllowUnlessBlocked,
485 IndexedAccessAlwaysAllowed);
486 Handle<Object> instance = tmpl->NewInstance();
487 context->Global()->Set(String::New("obj"), instance);
488 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.
489 "objNoCheck = {};"
490 "blockAccess = true;"
491 "observer = function(r) { records = r };"
492 "Object.observe(obj, observer);"
493 "Object.observe(objNoCheck, observer);");
494 Handle<Value> obj_no_check = CompileRun("objNoCheck");
495 {
496 LocalContext context2;
497 context2->Global()->Set(String::New("obj"), instance);
498 context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
499 CompileRun("records2 = null;"
rossberg 2013/08/16 13:51:54 Same here.
adamk 2013/08/20 21:38:16 Done.
500 "observer2 = function(r) { records2 = r };"
501 "Object.observe(obj, observer2);"
502 "Object.observe(objNoCheck, observer2);"
503 "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
504 "objNoCheck.baz = 'quux'");
505 const RecordExpectation expected_records2[] = {
506 { instance, "new", "foo", Handle<Value>() },
507 { obj_no_check, "new", "baz", Handle<Value>() },
508 };
509 EXPECT_RECORDS(CompileRun("records2"), expected_records2);
510 }
511 const RecordExpectation expected_records[] = {
512 { obj_no_check, "new", "baz", Handle<Value>() }
513 };
514 EXPECT_RECORDS(CompileRun("records"), expected_records);
515 }
516
517
518 TEST(ObserveIndexedAccessCheck) {
519 HarmonyIsolate isolate;
520 HandleScope scope;
521 LocalContext context;
522 Handle<ObjectTemplate> tmpl = ObjectTemplate::New();
523 tmpl->SetAccessCheckCallbacks(NamedAccessAlwaysAllowed,
524 IndexedAccessAllowUnlessBlocked);
525 Handle<Object> instance = tmpl->NewInstance();
526 context->Global()->Set(String::New("obj"), instance);
527 CompileRun("records = null;"
528 "objNoCheck = {};"
529 "blockAccess = true;"
530 "observer = function(r) { records = r };"
531 "Object.observe(obj, observer);"
532 "Object.observe(objNoCheck, observer);");
533 Handle<Value> obj_no_check = CompileRun("objNoCheck");
534 {
535 LocalContext context2;
536 context2->Global()->Set(String::New("obj"), instance);
537 context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
538 CompileRun("records2 = null;"
539 "observer2 = function(r) { records2 = r };"
540 "Object.observe(obj, observer2);"
541 "Object.observe(objNoCheck, observer2);"
542 "obj[7] = 'bar';"
543 "objNoCheck[42] = 'quux'");
544 const RecordExpectation expected_records2[] = {
545 { instance, "new", "7", Handle<Value>() },
546 { obj_no_check, "new", "42", Handle<Value>() }
547 };
548 EXPECT_RECORDS(CompileRun("records2"), expected_records2);
549 }
550 const RecordExpectation expected_records[] = {
551 { obj_no_check, "new", "42", Handle<Value>() }
552 };
553 EXPECT_RECORDS(CompileRun("records"), expected_records);
554 }
555
556
557 TEST(ObserveSpliceAccessCheck) {
558 HarmonyIsolate isolate;
559 HandleScope scope;
560 LocalContext context;
561 Handle<ObjectTemplate> tmpl = ObjectTemplate::New();
562 tmpl->SetAccessCheckCallbacks(NamedAccessAlwaysAllowed,
563 IndexedAccessAllowUnlessBlocked);
564 Handle<Object> instance = tmpl->NewInstance();
565 context->Global()->Set(String::New("obj"), instance);
566 CompileRun("records = null;"
567 "obj[1] = 'foo';"
568 "obj.length = 2;"
569 "objNoCheck = {1: 'bar', length: 2};"
570 "blockAccess = true;"
571 "observer = function(r) { records = r };"
572 "Array.observe(obj, observer);"
573 "Array.observe(objNoCheck, observer);");
574 Handle<Value> obj_no_check = CompileRun("objNoCheck");
575 {
576 LocalContext context2;
577 context2->Global()->Set(String::New("obj"), instance);
578 context2->Global()->Set(String::New("objNoCheck"), obj_no_check);
579 CompileRun("records2 = null;"
580 "observer2 = function(r) { records2 = r };"
581 "Array.observe(obj, observer2);"
582 "Array.observe(objNoCheck, observer2);"
583 // No one should hear about this: no splice records are emitted
584 // for access-checked objects
585 "[].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
586 "[].pop.call(objNoCheck);");
587 // 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.
588 const RecordExpectation expected_records2[] = {
589 { obj_no_check, "splice", "", Handle<Value>() }
590 };
591 EXPECT_RECORDS(CompileRun("records2"), expected_records2);
592 }
593 const RecordExpectation expected_records[] = {
594 { obj_no_check, "splice", "", Handle<Value>() }
595 };
596 EXPECT_RECORDS(CompileRun("records"), expected_records);
597 }
OLDNEW
« 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