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 |