Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/runtime/runtime-object.cc

Issue 1242123002: Fix GetOwnPropertyNames on access-checked objects (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Handle empty case Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/debug.h" 9 #include "src/debug.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 isolate, content, 803 isolate, content,
804 JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS)); 804 JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
805 805
806 // Test again, since cache may have been built by preceding call. 806 // Test again, since cache may have been built by preceding call.
807 if (object->IsSimpleEnum()) return object->map(); 807 if (object->IsSimpleEnum()) return object->map();
808 808
809 return *content; 809 return *content;
810 } 810 }
811 811
812 812
813 // Find the length of the prototype chain that is to be handled as one. If a
814 // prototype object is hidden it is to be viewed as part of the the object it
815 // is prototype for.
816 static int OwnPrototypeChainLength(JSObject* obj) {
817 int count = 1;
818 for (PrototypeIterator iter(obj->GetIsolate(), obj);
819 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
820 count++;
821 }
822 return count;
823 }
824
825
826 // Return the names of the own named properties. 813 // Return the names of the own named properties.
827 // args[0]: object 814 // args[0]: object
828 // args[1]: PropertyAttributes as int 815 // args[1]: PropertyAttributes as int
829 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { 816 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
830 HandleScope scope(isolate); 817 HandleScope scope(isolate);
831 DCHECK(args.length() == 2); 818 DCHECK(args.length() == 2);
832 if (!args[0]->IsJSObject()) { 819 if (!args[0]->IsJSObject()) {
833 return isolate->heap()->undefined_value(); 820 return isolate->heap()->undefined_value();
834 } 821 }
835 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 822 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
836 CONVERT_SMI_ARG_CHECKED(filter_value, 1); 823 CONVERT_SMI_ARG_CHECKED(filter_value, 1);
837 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); 824 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
838 825
839 // Skip the global proxy as it has no properties and always delegates to the
840 // real global object.
841 if (obj->IsJSGlobalProxy()) {
842 // Only collect names if access is permitted.
843 if (obj->IsAccessCheckNeeded() && !isolate->MayAccess(obj)) {
844 isolate->ReportFailedAccessCheck(obj);
845 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
846 return *isolate->factory()->NewJSArray(0);
847 }
848 PrototypeIterator iter(isolate, obj);
849 obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
850 }
851
852 // Find the number of objects making up this.
853 int length = OwnPrototypeChainLength(*obj);
854
855 // Find the number of own properties for each of the objects. 826 // Find the number of own properties for each of the objects.
856 ScopedVector<int> own_property_count(length);
857 int total_property_count = 0; 827 int total_property_count = 0;
858 { 828 for (PrototypeIterator iter(isolate, object,
859 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); 829 PrototypeIterator::START_AT_RECEIVER);
860 for (int i = 0; i < length; i++) { 830 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
861 DCHECK(!iter.IsAtEnd()); 831 Handle<JSObject> jsproto =
862 Handle<JSObject> jsproto = 832 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
863 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 833 total_property_count += jsproto->NumberOfOwnProperties(filter);
864 // Only collect names if access is permitted.
865 if (jsproto->IsAccessCheckNeeded() && !isolate->MayAccess(jsproto)) {
866 isolate->ReportFailedAccessCheck(jsproto);
867 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
868 return *isolate->factory()->NewJSArray(0);
869 }
870 int n;
871 n = jsproto->NumberOfOwnProperties(filter);
872 own_property_count[i] = n;
873 total_property_count += n;
874 iter.Advance();
875 }
876 } 834 }
877 835
878 // Allocate an array with storage for all the property names. 836 // Allocate an array with storage for all the property names.
879 Handle<FixedArray> names = 837 Handle<FixedArray> names =
880 isolate->factory()->NewFixedArray(total_property_count); 838 isolate->factory()->NewFixedArray(total_property_count);
881 839
882 // Get the property names. 840 // Get the property names.
883 int next_copy_index = 0; 841 int next_copy_index = 0;
884 int hidden_strings = 0; 842 int hidden_strings = 0;
885 { 843 Handle<Object> hidden_string = isolate->factory()->hidden_string();
886 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); 844 for (PrototypeIterator iter(isolate, object,
887 for (int i = 0; i < length; i++) { 845 PrototypeIterator::START_AT_RECEIVER);
888 DCHECK(!iter.IsAtEnd()); 846 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
889 Handle<JSObject> jsproto = 847 Handle<JSObject> jsproto =
890 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 848 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
891 jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); 849 int own = jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
892 // Names from hidden prototypes may already have been added 850 // Names from hidden prototypes may already have been added
893 // for inherited function template instances. Count the duplicates 851 // for inherited function template instances. Count the duplicates
894 // and stub them out; the final copy pass at the end ignores holes. 852 // and stub them out; the final copy pass at the end ignores holes.
895 for (int j = next_copy_index; j < next_copy_index + own_property_count[i]; 853 for (int j = next_copy_index; j < next_copy_index + own; j++) {
896 j++) { 854 Object* name_from_hidden_proto = names->get(j);
897 Object* name_from_hidden_proto = names->get(j); 855 if (isolate->IsInternallyUsedPropertyName(name_from_hidden_proto)) {
898 if (isolate->IsInternallyUsedPropertyName(name_from_hidden_proto)) { 856 hidden_strings++;
899 hidden_strings++; 857 } else {
900 } else { 858 for (int k = 0; k < next_copy_index; k++) {
901 for (int k = 0; k < next_copy_index; k++) { 859 Object* name = names->get(k);
902 Object* name = names->get(k); 860 if (name_from_hidden_proto == name) {
903 if (name_from_hidden_proto == name) { 861 names->set(j, *hidden_string);
904 names->set(j, isolate->heap()->hidden_string()); 862 hidden_strings++;
905 hidden_strings++; 863 break;
906 break;
907 }
908 } 864 }
909 } 865 }
910 } 866 }
911 next_copy_index += own_property_count[i]; 867 }
868 next_copy_index += own;
869 }
912 870
913 iter.Advance(); 871 CHECK_EQ(total_property_count, next_copy_index);
872
873 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) {
874 for (int i = 0; i < total_property_count; i++) {
875 Handle<Name> name(Name::cast(names->get(i)));
876 if (name.is_identical_to(hidden_string)) continue;
877 LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
878 if (!JSObject::AllCanRead(&it)) {
879 names->set(i, *hidden_string);
880 hidden_strings++;
881 }
914 } 882 }
915 } 883 }
916 884
917 // Filter out name of hidden properties object and 885 // Filter out name of hidden properties object and
918 // hidden prototype duplicates. 886 // hidden prototype duplicates.
919 if (hidden_strings > 0) { 887 if (hidden_strings > 0) {
920 Handle<FixedArray> old_names = names; 888 if (hidden_strings == total_property_count) {
921 names = isolate->factory()->NewFixedArray(names->length() - hidden_strings); 889 names = isolate->factory()->empty_fixed_array();
922 int dest_pos = 0; 890 } else {
923 for (int i = 0; i < total_property_count; i++) { 891 int i;
924 Object* name = old_names->get(i); 892 for (i = 0; i < total_property_count; i++) {
925 if (isolate->IsInternallyUsedPropertyName(name)) { 893 Object* name = names->get(i);
926 hidden_strings--; 894 if (name == *hidden_string) break;
927 continue;
928 } 895 }
929 names->set(dest_pos++, name); 896 int dest_pos = i;
897 for (; i < total_property_count; i++) {
898 Object* name = names->get(i);
899 if (name == *hidden_string) continue;
900 names->set(dest_pos++, name);
901 }
902
903 isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
904 *names, hidden_strings);
930 } 905 }
931 DCHECK_EQ(0, hidden_strings);
932 } 906 }
933 907
934 return *isolate->factory()->NewJSArrayWithElements(names); 908 return *isolate->factory()->NewJSArrayWithElements(names);
935 } 909 }
936 910
937 911
938 // Return the names of the own indexed properties. 912 // Return the names of the own indexed properties.
939 // args[0]: object 913 // args[0]: object
940 RUNTIME_FUNCTION(Runtime_GetOwnElementNames) { 914 RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
941 HandleScope scope(isolate); 915 HandleScope scope(isolate);
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); 1444 CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
1471 1445
1472 RETURN_FAILURE_ON_EXCEPTION( 1446 RETURN_FAILURE_ON_EXCEPTION(
1473 isolate, 1447 isolate,
1474 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(), 1448 JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
1475 setter, attrs)); 1449 setter, attrs));
1476 return isolate->heap()->undefined_value(); 1450 return isolate->heap()->undefined_value();
1477 } 1451 }
1478 } // namespace internal 1452 } // namespace internal
1479 } // namespace v8 1453 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698