OLD | NEW |
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 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 } | 458 } |
459 | 459 |
460 | 460 |
461 static bool IndexedAccessAlwaysAllowed(Local<Object>, uint32_t, AccessType, | 461 static bool IndexedAccessAlwaysAllowed(Local<Object>, uint32_t, AccessType, |
462 Local<Value>) { | 462 Local<Value>) { |
463 return true; | 463 return true; |
464 } | 464 } |
465 | 465 |
466 | 466 |
467 static AccessType g_access_block_type = ACCESS_GET; | 467 static AccessType g_access_block_type = ACCESS_GET; |
| 468 static const uint32_t kBlockedContextIndex = 1337; |
468 | 469 |
469 | 470 |
470 static bool NamedAccessAllowUnlessBlocked(Local<Object> host, | 471 static bool NamedAccessAllowUnlessBlocked(Local<Object> host, |
471 Local<Value> key, | 472 Local<Value> key, |
472 AccessType type, | 473 AccessType type, |
473 Local<Value>) { | 474 Local<Value> data) { |
474 if (type != g_access_block_type) return true; | 475 if (type != g_access_block_type) return true; |
475 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( | 476 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( |
476 Utils::OpenHandle(*host)->GetIsolate()); | 477 Utils::OpenHandle(*host)->GetIsolate()); |
477 Handle<Object> global = isolate->GetCurrentContext()->Global(); | 478 Handle<Object> global = isolate->GetCurrentContext()->Global(); |
478 Handle<Value> blacklist = global->Get(String::New("blacklist")); | 479 if (!global->Has(kBlockedContextIndex)) return true; |
479 if (!blacklist->IsObject()) return true; | 480 return !key->IsString() || !key->Equals(data); |
480 if (key->IsString()) return !blacklist.As<Object>()->Has(key); | |
481 return true; | |
482 } | 481 } |
483 | 482 |
484 | 483 |
485 static bool IndexedAccessAllowUnlessBlocked(Local<Object> host, | 484 static bool IndexedAccessAllowUnlessBlocked(Local<Object> host, |
486 uint32_t index, | 485 uint32_t index, |
487 AccessType type, | 486 AccessType type, |
488 Local<Value>) { | 487 Local<Value> data) { |
489 if (type != ACCESS_GET) return true; | 488 if (type != g_access_block_type) return true; |
490 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( | 489 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( |
491 Utils::OpenHandle(*host)->GetIsolate()); | 490 Utils::OpenHandle(*host)->GetIsolate()); |
492 Handle<Object> global = isolate->GetCurrentContext()->Global(); | 491 Handle<Object> global = isolate->GetCurrentContext()->Global(); |
493 Handle<Value> blacklist = global->Get(String::New("blacklist")); | 492 if (!global->Has(kBlockedContextIndex)) return true; |
494 if (!blacklist->IsObject()) return true; | 493 return index != data->Uint32Value(); |
495 return !blacklist.As<Object>()->Has(index); | |
496 } | 494 } |
497 | 495 |
498 | 496 |
499 static bool BlockAccessKeys(Local<Object> host, Local<Value> key, | 497 static bool BlockAccessKeys(Local<Object> host, Local<Value> key, |
500 AccessType type, Local<Value>) { | 498 AccessType type, Local<Value>) { |
501 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( | 499 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( |
502 Utils::OpenHandle(*host)->GetIsolate()); | 500 Utils::OpenHandle(*host)->GetIsolate()); |
503 Handle<Object> global = isolate->GetCurrentContext()->Global(); | 501 Handle<Object> global = isolate->GetCurrentContext()->Global(); |
504 Handle<Value> blacklist = global->Get(String::New("blacklist")); | 502 return type != ACCESS_KEYS || !global->Has(kBlockedContextIndex); |
505 if (!blacklist->IsObject()) return true; | |
506 return type != ACCESS_KEYS || | |
507 !blacklist.As<Object>()->Has(String::New("__block_access_keys")); | |
508 } | 503 } |
509 | 504 |
510 | 505 |
511 static Handle<Object> CreateAccessCheckedObject( | 506 static Handle<Object> CreateAccessCheckedObject( |
512 NamedSecurityCallback namedCallback, | 507 NamedSecurityCallback namedCallback, |
513 IndexedSecurityCallback indexedCallback) { | 508 IndexedSecurityCallback indexedCallback, |
| 509 Handle<Value> data = Handle<Value>()) { |
514 Handle<ObjectTemplate> tmpl = ObjectTemplate::New(); | 510 Handle<ObjectTemplate> tmpl = ObjectTemplate::New(); |
515 tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback); | 511 tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback, data); |
516 Handle<Object> instance = tmpl->NewInstance(); | 512 Handle<Object> instance = tmpl->NewInstance(); |
517 instance->CreationContext()->Global()->Set(String::New("obj"), instance); | 513 Handle<Object> global = instance->CreationContext()->Global(); |
| 514 global->Set(String::New("obj"), instance); |
| 515 global->Set(kBlockedContextIndex, v8::True()); |
518 return instance; | 516 return instance; |
519 } | 517 } |
520 | 518 |
521 | 519 |
522 TEST(NamedAccessCheck) { | 520 TEST(NamedAccessCheck) { |
523 HarmonyIsolate isolate; | 521 HarmonyIsolate isolate; |
524 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; | 522 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
525 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 523 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
526 HandleScope scope(isolate.GetIsolate()); | 524 HandleScope scope(isolate.GetIsolate()); |
527 LocalContext context(isolate.GetIsolate()); | 525 LocalContext context(isolate.GetIsolate()); |
528 g_access_block_type = types[i]; | 526 g_access_block_type = types[i]; |
529 Handle<Object> instance = CreateAccessCheckedObject( | 527 Handle<Object> instance = CreateAccessCheckedObject( |
530 NamedAccessAllowUnlessBlocked, IndexedAccessAlwaysAllowed); | 528 NamedAccessAllowUnlessBlocked, |
| 529 IndexedAccessAlwaysAllowed, |
| 530 String::New("foo")); |
531 CompileRun("var records = null;" | 531 CompileRun("var records = null;" |
532 "var objNoCheck = {};" | 532 "var objNoCheck = {};" |
533 "var blacklist = {foo: true};" | |
534 "var observer = function(r) { records = r };" | 533 "var observer = function(r) { records = r };" |
535 "Object.observe(obj, observer);" | 534 "Object.observe(obj, observer);" |
536 "Object.observe(objNoCheck, observer);"); | 535 "Object.observe(objNoCheck, observer);"); |
537 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 536 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
538 { | 537 { |
539 LocalContext context2(isolate.GetIsolate()); | 538 LocalContext context2(isolate.GetIsolate()); |
540 context2->Global()->Set(String::New("obj"), instance); | 539 context2->Global()->Set(String::New("obj"), instance); |
541 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 540 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
542 CompileRun("var records2 = null;" | 541 CompileRun("var records2 = null;" |
543 "var observer2 = function(r) { records2 = r };" | 542 "var observer2 = function(r) { records2 = r };" |
(...skipping 23 matching lines...) Expand all Loading... |
567 | 566 |
568 | 567 |
569 TEST(IndexedAccessCheck) { | 568 TEST(IndexedAccessCheck) { |
570 HarmonyIsolate isolate; | 569 HarmonyIsolate isolate; |
571 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; | 570 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
572 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 571 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
573 HandleScope scope(isolate.GetIsolate()); | 572 HandleScope scope(isolate.GetIsolate()); |
574 LocalContext context(isolate.GetIsolate()); | 573 LocalContext context(isolate.GetIsolate()); |
575 g_access_block_type = types[i]; | 574 g_access_block_type = types[i]; |
576 Handle<Object> instance = CreateAccessCheckedObject( | 575 Handle<Object> instance = CreateAccessCheckedObject( |
577 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); | 576 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, |
| 577 Number::New(7)); |
578 CompileRun("var records = null;" | 578 CompileRun("var records = null;" |
579 "var objNoCheck = {};" | 579 "var objNoCheck = {};" |
580 "var blacklist = {7: true};" | |
581 "var observer = function(r) { records = r };" | 580 "var observer = function(r) { records = r };" |
582 "Object.observe(obj, observer);" | 581 "Object.observe(obj, observer);" |
583 "Object.observe(objNoCheck, observer);"); | 582 "Object.observe(objNoCheck, observer);"); |
584 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 583 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
585 { | 584 { |
586 LocalContext context2(isolate.GetIsolate()); | 585 LocalContext context2(isolate.GetIsolate()); |
587 context2->Global()->Set(String::New("obj"), instance); | 586 context2->Global()->Set(String::New("obj"), instance); |
588 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 587 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
589 CompileRun("var records2 = null;" | 588 CompileRun("var records2 = null;" |
590 "var observer2 = function(r) { records2 = r };" | 589 "var observer2 = function(r) { records2 = r };" |
(...skipping 21 matching lines...) Expand all Loading... |
612 } | 611 } |
613 } | 612 } |
614 | 613 |
615 | 614 |
616 TEST(SpliceAccessCheck) { | 615 TEST(SpliceAccessCheck) { |
617 HarmonyIsolate isolate; | 616 HarmonyIsolate isolate; |
618 HandleScope scope(isolate.GetIsolate()); | 617 HandleScope scope(isolate.GetIsolate()); |
619 LocalContext context(isolate.GetIsolate()); | 618 LocalContext context(isolate.GetIsolate()); |
620 g_access_block_type = ACCESS_GET; | 619 g_access_block_type = ACCESS_GET; |
621 Handle<Object> instance = CreateAccessCheckedObject( | 620 Handle<Object> instance = CreateAccessCheckedObject( |
622 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); | 621 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, |
| 622 Number::New(1)); |
623 CompileRun("var records = null;" | 623 CompileRun("var records = null;" |
624 "obj[1] = 'foo';" | 624 "obj[1] = 'foo';" |
625 "obj.length = 2;" | 625 "obj.length = 2;" |
626 "var objNoCheck = {1: 'bar', length: 2};" | 626 "var objNoCheck = {1: 'bar', length: 2};" |
627 "var blacklist = {1: true};" | |
628 "observer = function(r) { records = r };" | 627 "observer = function(r) { records = r };" |
629 "Array.observe(obj, observer);" | 628 "Array.observe(obj, observer);" |
630 "Array.observe(objNoCheck, observer);"); | 629 "Array.observe(objNoCheck, observer);"); |
631 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 630 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
632 { | 631 { |
633 LocalContext context2(isolate.GetIsolate()); | 632 LocalContext context2(isolate.GetIsolate()); |
634 context2->Global()->Set(String::New("obj"), instance); | 633 context2->Global()->Set(String::New("obj"), instance); |
635 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 634 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
636 CompileRun("var records2 = null;" | 635 CompileRun("var records2 = null;" |
637 "var observer2 = function(r) { records2 = r };" | 636 "var observer2 = function(r) { records2 = r };" |
(...skipping 22 matching lines...) Expand all Loading... |
660 | 659 |
661 TEST(DisallowAllForAccessKeys) { | 660 TEST(DisallowAllForAccessKeys) { |
662 HarmonyIsolate isolate; | 661 HarmonyIsolate isolate; |
663 HandleScope scope(isolate.GetIsolate()); | 662 HandleScope scope(isolate.GetIsolate()); |
664 LocalContext context(isolate.GetIsolate()); | 663 LocalContext context(isolate.GetIsolate()); |
665 Handle<Object> instance = CreateAccessCheckedObject( | 664 Handle<Object> instance = CreateAccessCheckedObject( |
666 BlockAccessKeys, IndexedAccessAlwaysAllowed); | 665 BlockAccessKeys, IndexedAccessAlwaysAllowed); |
667 CompileRun("var records = null;" | 666 CompileRun("var records = null;" |
668 "var objNoCheck = {};" | 667 "var objNoCheck = {};" |
669 "var observer = function(r) { records = r };" | 668 "var observer = function(r) { records = r };" |
670 "var blacklist = {__block_access_keys: true};" | |
671 "Object.observe(obj, observer);" | 669 "Object.observe(obj, observer);" |
672 "Object.observe(objNoCheck, observer);"); | 670 "Object.observe(objNoCheck, observer);"); |
673 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 671 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
674 { | 672 { |
675 LocalContext context2(isolate.GetIsolate()); | 673 LocalContext context2(isolate.GetIsolate()); |
676 context2->Global()->Set(String::New("obj"), instance); | 674 context2->Global()->Set(String::New("obj"), instance); |
677 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 675 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
678 CompileRun("var records2 = null;" | 676 CompileRun("var records2 = null;" |
679 "var observer2 = function(r) { records2 = r };" | 677 "var observer2 = function(r) { records2 = r };" |
680 "Object.observe(obj, observer2);" | 678 "Object.observe(obj, observer2);" |
(...skipping 16 matching lines...) Expand all Loading... |
697 | 695 |
698 | 696 |
699 TEST(AccessCheckDisallowApiModifications) { | 697 TEST(AccessCheckDisallowApiModifications) { |
700 HarmonyIsolate isolate; | 698 HarmonyIsolate isolate; |
701 HandleScope scope(isolate.GetIsolate()); | 699 HandleScope scope(isolate.GetIsolate()); |
702 LocalContext context(isolate.GetIsolate()); | 700 LocalContext context(isolate.GetIsolate()); |
703 Handle<Object> instance = CreateAccessCheckedObject( | 701 Handle<Object> instance = CreateAccessCheckedObject( |
704 BlockAccessKeys, IndexedAccessAlwaysAllowed); | 702 BlockAccessKeys, IndexedAccessAlwaysAllowed); |
705 CompileRun("var records = null;" | 703 CompileRun("var records = null;" |
706 "var observer = function(r) { records = r };" | 704 "var observer = function(r) { records = r };" |
707 "var blacklist = {__block_access_keys: true};" | |
708 "Object.observe(obj, observer);"); | 705 "Object.observe(obj, observer);"); |
709 { | 706 { |
710 LocalContext context2(isolate.GetIsolate()); | 707 LocalContext context2(isolate.GetIsolate()); |
711 context2->Global()->Set(String::New("obj"), instance); | 708 context2->Global()->Set(String::New("obj"), instance); |
712 CompileRun("var records2 = null;" | 709 CompileRun("var records2 = null;" |
713 "var observer2 = function(r) { records2 = r };" | 710 "var observer2 = function(r) { records2 = r };" |
714 "Object.observe(obj, observer2);"); | 711 "Object.observe(obj, observer2);"); |
715 instance->Set(5, String::New("bar")); | 712 instance->Set(5, String::New("bar")); |
716 instance->Set(String::New("foo"), String::New("bar")); | 713 instance->Set(String::New("foo"), String::New("bar")); |
717 CompileRun(""); // trigger delivery | 714 CompileRun(""); // trigger delivery |
718 const RecordExpectation expected_records2[] = { | 715 const RecordExpectation expected_records2[] = { |
719 { instance, "new", "5", Handle<Value>() }, | 716 { instance, "new", "5", Handle<Value>() }, |
720 { instance, "new", "foo", Handle<Value>() } | 717 { instance, "new", "foo", Handle<Value>() } |
721 }; | 718 }; |
722 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 719 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
723 } | 720 } |
724 CHECK(CompileRun("records")->IsNull()); | 721 CHECK(CompileRun("records")->IsNull()); |
725 } | 722 } |
OLD | NEW |