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 // Access check callback denied the access, but some properties |
| 678 // can have a special permissions which override callbacks descision |
| 679 // (currently see v8::AccessControl). |
| 680 break; |
| 681 } |
| 682 |
| 683 if (current == holder) { |
| 684 return true; |
| 685 } |
| 686 |
| 687 current = JSObject::cast(current->GetPrototype()); |
| 688 } |
| 689 |
| 690 // API callbacks can have per callback access exceptions. |
| 691 switch (result->type()) { |
| 692 case CALLBACKS: { |
| 693 if (CheckAccessException(result, access_type)) { |
| 694 return true; |
| 695 } |
| 696 break; |
| 697 } |
| 698 case INTERCEPTOR: { |
| 699 // If the object has an interceptor, try real named properties. |
| 700 // Overwrite the result to fetch the correct property later. |
| 701 holder->LookupRealNamedProperty(name, result); |
| 702 if (result->IsProperty()) { |
| 703 if (CheckAccessException(result, access_type)) { |
| 704 return true; |
| 705 } |
| 706 } |
| 707 break; |
| 708 } |
| 709 default: |
| 710 break; |
| 711 } |
| 712 |
| 713 Top::ReportFailedAccessCheck(current, access_type); |
| 714 return false; |
| 715 } |
| 716 |
| 717 |
647 // Enumerator used as indices into the array returned from GetOwnProperty | 718 // Enumerator used as indices into the array returned from GetOwnProperty |
648 enum PropertyDescriptorIndices { | 719 enum PropertyDescriptorIndices { |
649 IS_ACCESSOR_INDEX, | 720 IS_ACCESSOR_INDEX, |
650 VALUE_INDEX, | 721 VALUE_INDEX, |
651 GETTER_INDEX, | 722 GETTER_INDEX, |
652 SETTER_INDEX, | 723 SETTER_INDEX, |
653 WRITABLE_INDEX, | 724 WRITABLE_INDEX, |
654 ENUMERABLE_INDEX, | 725 ENUMERABLE_INDEX, |
655 CONFIGURABLE_INDEX, | 726 CONFIGURABLE_INDEX, |
656 DESCRIPTOR_SIZE | 727 DESCRIPTOR_SIZE |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 } | 810 } |
740 } | 811 } |
741 | 812 |
742 // Use recursive implementation to also traverse hidden prototypes | 813 // Use recursive implementation to also traverse hidden prototypes |
743 GetOwnPropertyImplementation(*obj, *name, &result); | 814 GetOwnPropertyImplementation(*obj, *name, &result); |
744 | 815 |
745 if (!result.IsProperty()) { | 816 if (!result.IsProperty()) { |
746 return Heap::undefined_value(); | 817 return Heap::undefined_value(); |
747 } | 818 } |
748 | 819 |
| 820 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { |
| 821 return Heap::undefined_value(); |
| 822 } |
| 823 |
749 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); | 824 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); |
750 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); | 825 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); |
751 | 826 |
752 bool is_js_accessor = (result.type() == CALLBACKS) && | 827 bool is_js_accessor = (result.type() == CALLBACKS) && |
753 (result.GetCallbackObject()->IsFixedArray()); | 828 (result.GetCallbackObject()->IsFixedArray()); |
754 | 829 |
755 if (is_js_accessor) { | 830 if (is_js_accessor) { |
756 // __defineGetter__/__defineSetter__ callback. | 831 // __defineGetter__/__defineSetter__ callback. |
| 832 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); |
| 833 |
757 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); | 834 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); |
758 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); | 835 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { |
759 elms->set(GETTER_INDEX, structure->get(0)); | 836 elms->set(GETTER_INDEX, structure->get(0)); |
760 elms->set(SETTER_INDEX, structure->get(1)); | 837 } |
| 838 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { |
| 839 elms->set(SETTER_INDEX, structure->get(1)); |
| 840 } |
761 } else { | 841 } else { |
762 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 842 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
763 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); | 843 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); |
764 | 844 |
765 PropertyAttributes attrs; | 845 PropertyAttributes attrs; |
766 Object* value; | 846 Object* value; |
| 847 // GetProperty will check access and report any violations. |
767 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); | 848 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); |
768 if (!maybe_value->ToObject(&value)) return maybe_value; | 849 if (!maybe_value->ToObject(&value)) return maybe_value; |
769 } | 850 } |
770 elms->set(VALUE_INDEX, value); | 851 elms->set(VALUE_INDEX, value); |
771 } | 852 } |
772 | 853 |
773 return *desc; | 854 return *desc; |
774 } | 855 } |
775 | 856 |
776 | 857 |
(...skipping 10093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10870 } else { | 10951 } else { |
10871 // Handle last resort GC and make sure to allow future allocations | 10952 // Handle last resort GC and make sure to allow future allocations |
10872 // to grow the heap without causing GCs (if possible). | 10953 // to grow the heap without causing GCs (if possible). |
10873 Counters::gc_last_resort_from_js.Increment(); | 10954 Counters::gc_last_resort_from_js.Increment(); |
10874 Heap::CollectAllGarbage(false); | 10955 Heap::CollectAllGarbage(false); |
10875 } | 10956 } |
10876 } | 10957 } |
10877 | 10958 |
10878 | 10959 |
10879 } } // namespace v8::internal | 10960 } } // namespace v8::internal |
OLD | NEW |