Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 637 if (!result->IsProperty()) { | 637 if (!result->IsProperty()) { |
| 638 Object* proto = obj->GetPrototype(); | 638 Object* proto = obj->GetPrototype(); |
| 639 if (proto->IsJSObject() && | 639 if (proto->IsJSObject() && |
| 640 JSObject::cast(proto)->map()->is_hidden_prototype()) | 640 JSObject::cast(proto)->map()->is_hidden_prototype()) |
| 641 GetOwnPropertyImplementation(JSObject::cast(proto), | 641 GetOwnPropertyImplementation(JSObject::cast(proto), |
| 642 name, result); | 642 name, result); |
| 643 } | 643 } |
| 644 } | 644 } |
| 645 | 645 |
| 646 | 646 |
| 647 static bool CheckAccessException(LookupResult* result, | |
| 648 v8::AccessType access_type) { | |
| 649 if (result->type() == CALLBACKS) { | |
| 650 Object* callback = result->GetCallbackObject(); | |
| 651 if (callback->IsAccessorInfo()) { | |
| 652 AccessorInfo* info = AccessorInfo::cast(callback); | |
| 653 bool can_access = | |
| 654 (access_type == v8::ACCESS_HAS && | |
| 655 (info->all_can_read() || info->all_can_write())) || | |
| 656 (access_type == v8::ACCESS_GET && info->all_can_read()) || | |
| 657 (access_type == v8::ACCESS_SET && info->all_can_write()); | |
| 658 return can_access; | |
| 659 } | |
| 660 } | |
| 661 | |
| 662 return false; | |
| 663 } | |
| 664 | |
| 665 | |
| 666 static bool CheckAccess(JSObject* obj, | |
| 667 String* name, | |
| 668 LookupResult* result, | |
| 669 v8::AccessType access_type) { | |
| 670 ASSERT(result->IsProperty()); | |
| 671 | |
| 672 JSObject* holder = result->holder(); | |
| 673 JSObject* current = obj; | |
| 674 while (true) { | |
| 675 if (current->IsAccessCheckNeeded() && | |
| 676 !Top::MayNamedAccess(current, name, access_type)) { | |
| 677 // The only hope there is an access exception. | |
|
Mads Ager (chromium)
2011/02/02 10:13:36
I don't understand the comment. Could you expand o
antonm
2011/02/02 12:16:31
Sorry. Is new wording better?
| |
| 678 break; | |
| 679 } | |
| 680 | |
| 681 if (current == holder) { | |
| 682 return true; | |
| 683 } | |
| 684 | |
| 685 current = JSObject::cast(current->GetPrototype()); | |
| 686 } | |
| 687 | |
| 688 // API callbacks can have per callback access exceptions. | |
| 689 switch (result->type()) { | |
| 690 case CALLBACKS: { | |
| 691 if (CheckAccessException(result, access_type)) { | |
| 692 return true; | |
| 693 } | |
| 694 break; | |
| 695 } | |
| 696 case INTERCEPTOR: { | |
| 697 // If the object has an interceptor, try real named properties. | |
| 698 // Overwrite the result to fetch the correct property later. | |
| 699 holder->LookupRealNamedProperty(name, result); | |
| 700 if (result->IsProperty()) { | |
| 701 if (CheckAccessException(result, access_type)) { | |
| 702 return true; | |
| 703 } | |
| 704 } | |
| 705 break; | |
| 706 } | |
| 707 default: | |
| 708 break; | |
| 709 } | |
| 710 | |
| 711 Top::ReportFailedAccessCheck(current, access_type); | |
| 712 return false; | |
| 713 } | |
| 714 | |
| 715 | |
| 647 // Enumerator used as indices into the array returned from GetOwnProperty | 716 // Enumerator used as indices into the array returned from GetOwnProperty |
| 648 enum PropertyDescriptorIndices { | 717 enum PropertyDescriptorIndices { |
| 649 IS_ACCESSOR_INDEX, | 718 IS_ACCESSOR_INDEX, |
| 650 VALUE_INDEX, | 719 VALUE_INDEX, |
| 651 GETTER_INDEX, | 720 GETTER_INDEX, |
| 652 SETTER_INDEX, | 721 SETTER_INDEX, |
| 653 WRITABLE_INDEX, | 722 WRITABLE_INDEX, |
| 654 ENUMERABLE_INDEX, | 723 ENUMERABLE_INDEX, |
| 655 CONFIGURABLE_INDEX, | 724 CONFIGURABLE_INDEX, |
| 656 DESCRIPTOR_SIZE | 725 DESCRIPTOR_SIZE |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 } | 808 } |
| 740 } | 809 } |
| 741 | 810 |
| 742 // Use recursive implementation to also traverse hidden prototypes | 811 // Use recursive implementation to also traverse hidden prototypes |
| 743 GetOwnPropertyImplementation(*obj, *name, &result); | 812 GetOwnPropertyImplementation(*obj, *name, &result); |
| 744 | 813 |
| 745 if (!result.IsProperty()) { | 814 if (!result.IsProperty()) { |
| 746 return Heap::undefined_value(); | 815 return Heap::undefined_value(); |
| 747 } | 816 } |
| 748 | 817 |
| 818 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { | |
| 819 return Heap::undefined_value(); | |
| 820 } | |
| 821 | |
| 749 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); | 822 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); |
| 750 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); | 823 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); |
| 751 | 824 |
| 752 bool is_js_accessor = (result.type() == CALLBACKS) && | 825 bool is_js_accessor = (result.type() == CALLBACKS) && |
| 753 (result.GetCallbackObject()->IsFixedArray()); | 826 (result.GetCallbackObject()->IsFixedArray()); |
| 754 | 827 |
| 755 if (is_js_accessor) { | 828 if (is_js_accessor) { |
| 756 // __defineGetter__/__defineSetter__ callback. | 829 // __defineGetter__/__defineSetter__ callback. |
| 830 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); | |
| 831 | |
| 757 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); | 832 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); |
| 758 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); | 833 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { |
| 759 elms->set(GETTER_INDEX, structure->get(0)); | 834 elms->set(GETTER_INDEX, structure->get(0)); |
| 760 elms->set(SETTER_INDEX, structure->get(1)); | 835 } |
| 836 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { | |
| 837 elms->set(SETTER_INDEX, structure->get(1)); | |
| 838 } | |
| 761 } else { | 839 } else { |
| 762 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 840 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
| 763 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); | 841 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); |
| 764 | 842 |
| 765 PropertyAttributes attrs; | 843 PropertyAttributes attrs; |
| 766 Object* value; | 844 Object* value; |
| 845 // GetProperty will check access and report any violations. | |
| 767 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); | 846 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); |
| 768 if (!maybe_value->ToObject(&value)) return maybe_value; | 847 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 769 } | 848 } |
| 770 elms->set(VALUE_INDEX, value); | 849 elms->set(VALUE_INDEX, value); |
| 771 } | 850 } |
| 772 | 851 |
| 773 return *desc; | 852 return *desc; |
| 774 } | 853 } |
| 775 | 854 |
| 776 | 855 |
| (...skipping 10093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10870 } else { | 10949 } else { |
| 10871 // Handle last resort GC and make sure to allow future allocations | 10950 // Handle last resort GC and make sure to allow future allocations |
| 10872 // to grow the heap without causing GCs (if possible). | 10951 // to grow the heap without causing GCs (if possible). |
| 10873 Counters::gc_last_resort_from_js.Increment(); | 10952 Counters::gc_last_resort_from_js.Increment(); |
| 10874 Heap::CollectAllGarbage(false); | 10953 Heap::CollectAllGarbage(false); |
| 10875 } | 10954 } |
| 10876 } | 10955 } |
| 10877 | 10956 |
| 10878 | 10957 |
| 10879 } } // namespace v8::internal | 10958 } } // namespace v8::internal |
| OLD | NEW |