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

Side by Side Diff: src/objects.cc

Issue 6101001: Don't let JSON parsed objects hit inherited setters. (Closed)
Patch Set: Address review comments. Created 9 years, 11 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.h ('k') | src/parser.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 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 6777 matching lines...) Expand 10 before | Expand all | Expand 10 after
6788 // Handle [] on String objects. 6788 // Handle [] on String objects.
6789 if (this->IsStringObjectWithCharacterAt(index)) return true; 6789 if (this->IsStringObjectWithCharacterAt(index)) return true;
6790 6790
6791 Object* pt = GetPrototype(); 6791 Object* pt = GetPrototype();
6792 if (pt == Heap::null_value()) return false; 6792 if (pt == Heap::null_value()) return false;
6793 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 6793 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
6794 } 6794 }
6795 6795
6796 6796
6797 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, 6797 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index,
6798 Object* value) { 6798 Object* value,
6799 bool check_prototype) {
6799 // Make sure that the top context does not change when doing 6800 // Make sure that the top context does not change when doing
6800 // callbacks or interceptor calls. 6801 // callbacks or interceptor calls.
6801 AssertNoContextChange ncc; 6802 AssertNoContextChange ncc;
6802 HandleScope scope; 6803 HandleScope scope;
6803 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 6804 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
6804 Handle<JSObject> this_handle(this); 6805 Handle<JSObject> this_handle(this);
6805 Handle<Object> value_handle(value); 6806 Handle<Object> value_handle(value);
6806 if (!interceptor->setter()->IsUndefined()) { 6807 if (!interceptor->setter()->IsUndefined()) {
6807 v8::IndexedPropertySetter setter = 6808 v8::IndexedPropertySetter setter =
6808 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); 6809 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter());
6809 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); 6810 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index));
6810 CustomArguments args(interceptor->data(), this, this); 6811 CustomArguments args(interceptor->data(), this, this);
6811 v8::AccessorInfo info(args.end()); 6812 v8::AccessorInfo info(args.end());
6812 v8::Handle<v8::Value> result; 6813 v8::Handle<v8::Value> result;
6813 { 6814 {
6814 // Leaving JavaScript. 6815 // Leaving JavaScript.
6815 VMState state(EXTERNAL); 6816 VMState state(EXTERNAL);
6816 result = setter(index, v8::Utils::ToLocal(value_handle), info); 6817 result = setter(index, v8::Utils::ToLocal(value_handle), info);
6817 } 6818 }
6818 RETURN_IF_SCHEDULED_EXCEPTION(); 6819 RETURN_IF_SCHEDULED_EXCEPTION();
6819 if (!result.IsEmpty()) return *value_handle; 6820 if (!result.IsEmpty()) return *value_handle;
6820 } 6821 }
6821 MaybeObject* raw_result = 6822 MaybeObject* raw_result =
6822 this_handle->SetElementWithoutInterceptor(index, *value_handle); 6823 this_handle->SetElementWithoutInterceptor(index,
6824 *value_handle,
6825 check_prototype);
6823 RETURN_IF_SCHEDULED_EXCEPTION(); 6826 RETURN_IF_SCHEDULED_EXCEPTION();
6824 return raw_result; 6827 return raw_result;
6825 } 6828 }
6826 6829
6827 6830
6828 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, 6831 MaybeObject* JSObject::GetElementWithCallback(Object* receiver,
6829 Object* structure, 6832 Object* structure,
6830 uint32_t index, 6833 uint32_t index,
6831 Object* holder) { 6834 Object* holder) {
6832 ASSERT(!structure->IsProxy()); 6835 ASSERT(!structure->IsProxy());
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
6923 } 6926 }
6924 6927
6925 UNREACHABLE(); 6928 UNREACHABLE();
6926 return NULL; 6929 return NULL;
6927 } 6930 }
6928 6931
6929 6932
6930 // Adding n elements in fast case is O(n*n). 6933 // Adding n elements in fast case is O(n*n).
6931 // Note: revisit design to have dual undefined values to capture absent 6934 // Note: revisit design to have dual undefined values to capture absent
6932 // elements. 6935 // elements.
6933 MaybeObject* JSObject::SetFastElement(uint32_t index, Object* value) { 6936 MaybeObject* JSObject::SetFastElement(uint32_t index,
6937 Object* value,
6938 bool check_prototype) {
6934 ASSERT(HasFastElements()); 6939 ASSERT(HasFastElements());
6935 6940
6936 Object* elms_obj; 6941 Object* elms_obj;
6937 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); 6942 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements();
6938 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; 6943 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
6939 } 6944 }
6940 FixedArray* elms = FixedArray::cast(elms_obj); 6945 FixedArray* elms = FixedArray::cast(elms_obj);
6941 uint32_t elms_length = static_cast<uint32_t>(elms->length()); 6946 uint32_t elms_length = static_cast<uint32_t>(elms->length());
6942 6947
6943 if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) { 6948 if (check_prototype && !IsJSArray() &&
6949 (index >= elms_length || elms->get(index)->IsTheHole())) {
6944 if (SetElementWithCallbackSetterInPrototypes(index, value)) { 6950 if (SetElementWithCallbackSetterInPrototypes(index, value)) {
6945 return value; 6951 return value;
6946 } 6952 }
6947 } 6953 }
6948 6954
6949 // Check whether there is extra space in fixed array.. 6955 // Check whether there is extra space in fixed array..
6950 if (index < elms_length) { 6956 if (index < elms_length) {
6951 elms->set(index, value); 6957 elms->set(index, value);
6952 if (IsJSArray()) { 6958 if (IsJSArray()) {
6953 // Update the length of the array if needed. 6959 // Update the length of the array if needed.
(...skipping 22 matching lines...) Expand all
6976 return value; 6982 return value;
6977 } 6983 }
6978 } 6984 }
6979 6985
6980 // Otherwise default to slow case. 6986 // Otherwise default to slow case.
6981 Object* obj; 6987 Object* obj;
6982 { MaybeObject* maybe_obj = NormalizeElements(); 6988 { MaybeObject* maybe_obj = NormalizeElements();
6983 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 6989 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6984 } 6990 }
6985 ASSERT(HasDictionaryElements()); 6991 ASSERT(HasDictionaryElements());
6986 return SetElement(index, value); 6992 return SetElement(index, value, check_prototype);
6987 } 6993 }
6988 6994
6989 6995
6990 MaybeObject* JSObject::SetElement(uint32_t index, Object* value) { 6996 MaybeObject* JSObject::SetElement(uint32_t index,
6997 Object* value,
6998 bool check_prototype) {
6991 // Check access rights if needed. 6999 // Check access rights if needed.
6992 if (IsAccessCheckNeeded() && 7000 if (IsAccessCheckNeeded() &&
6993 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { 7001 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) {
6994 HandleScope scope; 7002 HandleScope scope;
6995 Handle<Object> value_handle(value); 7003 Handle<Object> value_handle(value);
6996 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); 7004 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET);
6997 return *value_handle; 7005 return *value_handle;
6998 } 7006 }
6999 7007
7000 if (IsJSGlobalProxy()) { 7008 if (IsJSGlobalProxy()) {
7001 Object* proto = GetPrototype(); 7009 Object* proto = GetPrototype();
7002 if (proto->IsNull()) return value; 7010 if (proto->IsNull()) return value;
7003 ASSERT(proto->IsJSGlobalObject()); 7011 ASSERT(proto->IsJSGlobalObject());
7004 return JSObject::cast(proto)->SetElement(index, value); 7012 return JSObject::cast(proto)->SetElement(index, value, check_prototype);
7005 } 7013 }
7006 7014
7007 // Check for lookup interceptor 7015 // Check for lookup interceptor
7008 if (HasIndexedInterceptor()) { 7016 if (HasIndexedInterceptor()) {
7009 return SetElementWithInterceptor(index, value); 7017 return SetElementWithInterceptor(index, value, check_prototype);
7010 } 7018 }
7011 7019
7012 return SetElementWithoutInterceptor(index, value); 7020 return SetElementWithoutInterceptor(index, value, check_prototype);
7013 } 7021 }
7014 7022
7015 7023
7016 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, 7024 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
7017 Object* value) { 7025 Object* value,
7026 bool check_prototype) {
7018 switch (GetElementsKind()) { 7027 switch (GetElementsKind()) {
7019 case FAST_ELEMENTS: 7028 case FAST_ELEMENTS:
7020 // Fast case. 7029 // Fast case.
7021 return SetFastElement(index, value); 7030 return SetFastElement(index, value, check_prototype);
7022 case PIXEL_ELEMENTS: { 7031 case PIXEL_ELEMENTS: {
7023 PixelArray* pixels = PixelArray::cast(elements()); 7032 PixelArray* pixels = PixelArray::cast(elements());
7024 return pixels->SetValue(index, value); 7033 return pixels->SetValue(index, value);
7025 } 7034 }
7026 case EXTERNAL_BYTE_ELEMENTS: { 7035 case EXTERNAL_BYTE_ELEMENTS: {
7027 ExternalByteArray* array = ExternalByteArray::cast(elements()); 7036 ExternalByteArray* array = ExternalByteArray::cast(elements());
7028 return array->SetValue(index, value); 7037 return array->SetValue(index, value);
7029 } 7038 }
7030 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { 7039 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
7031 ExternalUnsignedByteArray* array = 7040 ExternalUnsignedByteArray* array =
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
7064 Object* element = dictionary->ValueAt(entry); 7073 Object* element = dictionary->ValueAt(entry);
7065 PropertyDetails details = dictionary->DetailsAt(entry); 7074 PropertyDetails details = dictionary->DetailsAt(entry);
7066 if (details.type() == CALLBACKS) { 7075 if (details.type() == CALLBACKS) {
7067 return SetElementWithCallback(element, index, value, this); 7076 return SetElementWithCallback(element, index, value, this);
7068 } else { 7077 } else {
7069 dictionary->UpdateMaxNumberKey(index); 7078 dictionary->UpdateMaxNumberKey(index);
7070 dictionary->ValueAtPut(entry, value); 7079 dictionary->ValueAtPut(entry, value);
7071 } 7080 }
7072 } else { 7081 } else {
7073 // Index not already used. Look for an accessor in the prototype chain. 7082 // Index not already used. Look for an accessor in the prototype chain.
7074 if (!IsJSArray()) { 7083 if (check_prototype && !IsJSArray() &&
7075 if (SetElementWithCallbackSetterInPrototypes(index, value)) { 7084 SetElementWithCallbackSetterInPrototypes(index, value)) {
7076 return value; 7085 return value;
7077 }
7078 } 7086 }
7079 // When we set the is_extensible flag to false we always force 7087 // When we set the is_extensible flag to false we always force
7080 // the element into dictionary mode (and force them to stay there). 7088 // the element into dictionary mode (and force them to stay there).
7081 if (!map()->is_extensible()) { 7089 if (!map()->is_extensible()) {
7082 Handle<Object> number(Factory::NewNumberFromUint(index)); 7090 Handle<Object> number(Factory::NewNumberFromUint(index));
7083 Handle<String> index_string(Factory::NumberToString(number)); 7091 Handle<String> index_string(Factory::NumberToString(number));
7084 Handle<Object> args[1] = { index_string }; 7092 Handle<Object> args[1] = { index_string };
7085 return Top::Throw(*Factory::NewTypeError("object_not_extensible", 7093 return Top::Throw(*Factory::NewTypeError("object_not_extensible",
7086 HandleVector(args, 1))); 7094 HandleVector(args, 1)));
7087 } 7095 }
(...skipping 2771 matching lines...) Expand 10 before | Expand all | Expand 10 after
9859 if (break_point_objects()->IsUndefined()) return 0; 9867 if (break_point_objects()->IsUndefined()) return 0;
9860 // Single beak point. 9868 // Single beak point.
9861 if (!break_point_objects()->IsFixedArray()) return 1; 9869 if (!break_point_objects()->IsFixedArray()) return 1;
9862 // Multiple break points. 9870 // Multiple break points.
9863 return FixedArray::cast(break_point_objects())->length(); 9871 return FixedArray::cast(break_point_objects())->length();
9864 } 9872 }
9865 #endif 9873 #endif
9866 9874
9867 9875
9868 } } // namespace v8::internal 9876 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698