| 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 |