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

Side by Side Diff: src/runtime.cc

Issue 339553002: Simplify access checks performed by GetOwnProperty (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 <stdlib.h> 5 #include <stdlib.h>
6 #include <limits> 6 #include <limits>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 1896 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 (access_type == v8::ACCESS_GET && info->all_can_read()) || 1907 (access_type == v8::ACCESS_GET && info->all_can_read()) ||
1908 (access_type == v8::ACCESS_SET && info->all_can_write()); 1908 (access_type == v8::ACCESS_SET && info->all_can_write());
1909 } 1909 }
1910 return false; 1910 return false;
1911 } 1911 }
1912 1912
1913 1913
1914 template<class Key> 1914 template<class Key>
1915 static bool CheckGenericAccess( 1915 static bool CheckGenericAccess(
1916 Handle<JSObject> receiver, 1916 Handle<JSObject> receiver,
1917 Handle<JSObject> holder, 1917 Handle<Object> end,
1918 Key key, 1918 Key key,
1919 v8::AccessType access_type, 1919 v8::AccessType access_type,
1920 bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) { 1920 bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) {
1921 Isolate* isolate = receiver->GetIsolate(); 1921 Isolate* isolate = receiver->GetIsolate();
1922 for (Handle<JSObject> current = receiver; 1922 for (Handle<Object> current = receiver;
1923 true; 1923 !current.is_identical_to(end);
1924 current = handle(JSObject::cast(current->GetPrototype()), isolate)) { 1924 current = Object::GetPrototype(isolate, current)) {
1925 if (current->IsAccessCheckNeeded() && 1925 if (current->IsAccessCheckNeeded() &&
1926 !(isolate->*mayAccess)(current, key, access_type)) { 1926 !(isolate->*mayAccess)(
1927 Handle<JSObject>::cast(current), key, access_type)) {
1927 return false; 1928 return false;
1928 } 1929 }
1929 if (current.is_identical_to(holder)) break;
1930 } 1930 }
1931 return true; 1931 return true;
1932 } 1932 }
1933 1933
1934 1934
1935 enum AccessCheckResult { 1935 static void CheckPropertyAccess(Handle<JSObject> obj,
1936 ACCESS_FORBIDDEN, 1936 Handle<Name> name,
1937 ACCESS_ALLOWED, 1937 v8::AccessType access_type) {
1938 ACCESS_ABSENT 1938 Isolate* isolate = obj->GetIsolate();
1939 };
1940
1941
1942 static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
1943 Handle<Name> name,
1944 v8::AccessType access_type) {
1945 uint32_t index; 1939 uint32_t index;
1946 if (name->AsArrayIndex(&index)) { 1940 if (name->AsArrayIndex(&index)) {
1941 Handle<Object> next(obj->GetPrototype(), isolate);
1947 // TODO(1095): we should traverse hidden prototype hierachy as well. 1942 // TODO(1095): we should traverse hidden prototype hierachy as well.
1948 if (CheckGenericAccess( 1943 if (!CheckGenericAccess(
1949 obj, obj, index, access_type, &Isolate::MayIndexedAccess)) { 1944 obj, next, index, access_type, &Isolate::MayIndexedAccess)) {
1950 return ACCESS_ALLOWED; 1945 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
1951 } 1946 }
1952 1947 return;
1953 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
1954 return ACCESS_FORBIDDEN;
1955 } 1948 }
1956 1949
1957 Isolate* isolate = obj->GetIsolate();
1958 LookupResult lookup(isolate); 1950 LookupResult lookup(isolate);
1959 obj->LookupOwn(name, &lookup, true); 1951 obj->LookupOwn(name, &lookup, true);
1960 1952
1961 if (!lookup.IsProperty()) return ACCESS_ABSENT; 1953 Handle<Object> next = lookup.IsProperty()
1962 Handle<JSObject> holder(lookup.holder(), isolate); 1954 ? handle(lookup.holder()->GetPrototype(), isolate)
1955 : Handle<Object>::cast(isolate->factory()->null_value());
1963 if (CheckGenericAccess<Handle<Object> >( 1956 if (CheckGenericAccess<Handle<Object> >(
1964 obj, holder, name, access_type, &Isolate::MayNamedAccess)) { 1957 obj, next, name, access_type, &Isolate::MayNamedAccess)) {
1965 return ACCESS_ALLOWED; 1958 return;
1966 } 1959 }
1967 1960
1968 // Access check callback denied the access, but some properties 1961 // Access check callback denied the access, but some properties
1969 // can have a special permissions which override callbacks descision 1962 // can have a special permissions which override callbacks descision
1970 // (currently see v8::AccessControl). 1963 // (currently see v8::AccessControl).
1971 // API callbacks can have per callback access exceptions. 1964 // API callbacks can have per callback access exceptions.
1972 switch (lookup.type()) { 1965 if (lookup.IsFound() && lookup.type() == INTERCEPTOR) {
1973 case CALLBACKS: 1966 lookup.holder()->LookupOwnRealNamedProperty(name, &lookup);
1974 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { 1967 }
1975 return ACCESS_ALLOWED; 1968
1976 } 1969 if (lookup.IsPropertyCallbacks() &&
1977 break; 1970 CheckAccessException(lookup.GetCallbackObject(), access_type)) {
1978 case INTERCEPTOR: 1971 return;
1979 // If the object has an interceptor, try real named properties.
1980 // Overwrite the result to fetch the correct property later.
1981 holder->LookupRealNamedProperty(name, &lookup);
1982 if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
1983 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
1984 return ACCESS_ALLOWED;
1985 }
1986 }
1987 break;
1988 default:
1989 break;
1990 } 1972 }
1991 1973
1992 isolate->ReportFailedAccessCheck(obj, access_type); 1974 isolate->ReportFailedAccessCheck(obj, access_type);
1993 return ACCESS_FORBIDDEN;
1994 } 1975 }
1995 1976
1996 1977
1997 // Enumerator used as indices into the array returned from GetOwnProperty 1978 // Enumerator used as indices into the array returned from GetOwnProperty
1998 enum PropertyDescriptorIndices { 1979 enum PropertyDescriptorIndices {
1999 IS_ACCESSOR_INDEX, 1980 IS_ACCESSOR_INDEX,
2000 VALUE_INDEX, 1981 VALUE_INDEX,
2001 GETTER_INDEX, 1982 GETTER_INDEX,
2002 SETTER_INDEX, 1983 SETTER_INDEX,
2003 WRITABLE_INDEX, 1984 WRITABLE_INDEX,
2004 ENUMERABLE_INDEX, 1985 ENUMERABLE_INDEX,
2005 CONFIGURABLE_INDEX, 1986 CONFIGURABLE_INDEX,
2006 DESCRIPTOR_SIZE 1987 DESCRIPTOR_SIZE
2007 }; 1988 };
2008 1989
2009 1990
2010 MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate, 1991 MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
2011 Handle<JSObject> obj, 1992 Handle<JSObject> obj,
2012 Handle<Name> name) { 1993 Handle<Name> name) {
2013 Heap* heap = isolate->heap(); 1994 Heap* heap = isolate->heap();
2014 Factory* factory = isolate->factory(); 1995 Factory* factory = isolate->factory();
2015 // Due to some WebKit tests, we want to make sure that we do not log 1996
2016 // more than one access failure here. 1997 CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
2017 AccessCheckResult access_check_result =
2018 CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
2019 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 1998 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2020 switch (access_check_result) {
2021 case ACCESS_FORBIDDEN: return factory->false_value();
2022 case ACCESS_ALLOWED: break;
2023 case ACCESS_ABSENT: return factory->undefined_value();
2024 }
2025 1999
2026 PropertyAttributes attrs = JSReceiver::GetOwnPropertyAttributes(obj, name); 2000 PropertyAttributes attrs = JSReceiver::GetOwnPropertyAttributes(obj, name);
2027 if (attrs == ABSENT) { 2001 if (attrs == ABSENT) {
2028 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 2002 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2029 return factory->undefined_value(); 2003 return factory->undefined_value();
2030 } 2004 }
2031 ASSERT(!isolate->has_scheduled_exception()); 2005 ASSERT(!isolate->has_scheduled_exception());
2032 Handle<AccessorPair> accessors; 2006 Handle<AccessorPair> accessors;
2033 bool has_accessors = 2007 bool has_accessors =
2034 JSObject::GetOwnPropertyAccessorPair(obj, name).ToHandle(&accessors); 2008 JSObject::GetOwnPropertyAccessorPair(obj, name).ToHandle(&accessors);
2035 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); 2009 Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
2036 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); 2010 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
2037 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); 2011 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
2038 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(has_accessors)); 2012 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(has_accessors));
2039 2013
2040 if (!has_accessors) { 2014 if (!has_accessors) {
2041 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); 2015 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
2042 // Runtime::GetObjectProperty does access check. 2016 // Runtime::GetObjectProperty does access check.
2043 Handle<Object> value; 2017 Handle<Object> value;
2044 ASSIGN_RETURN_ON_EXCEPTION( 2018 ASSIGN_RETURN_ON_EXCEPTION(
2045 isolate, value, Runtime::GetObjectProperty(isolate, obj, name), 2019 isolate, value, Runtime::GetObjectProperty(isolate, obj, name),
2046 Object); 2020 Object);
2047 elms->set(VALUE_INDEX, *value); 2021 elms->set(VALUE_INDEX, *value);
2048 } else { 2022 } else {
2049 // Access checks are performed for both accessors separately.
2050 // When they fail, the respective field is not set in the descriptor.
2051 Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate); 2023 Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
2052 Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate); 2024 Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
2053 2025 elms->set(GETTER_INDEX, *getter);
2054 if (!getter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_GET)) { 2026 elms->set(SETTER_INDEX, *setter);
2055 ASSERT(!isolate->has_scheduled_exception());
2056 elms->set(GETTER_INDEX, *getter);
2057 } else {
2058 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2059 }
2060
2061 if (!setter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_SET)) {
2062 ASSERT(!isolate->has_scheduled_exception());
2063 elms->set(SETTER_INDEX, *setter);
2064 } else {
2065 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2066 }
2067 } 2027 }
2068 2028
2069 return isolate->factory()->NewJSArrayWithElements(elms); 2029 return factory->NewJSArrayWithElements(elms);
2070 } 2030 }
2071 2031
2072 2032
2073 // Returns an array with the property description: 2033 // Returns an array with the property description:
2074 // if args[1] is not a property on args[0] 2034 // if args[1] is not a property on args[0]
2075 // returns undefined 2035 // returns undefined
2076 // if args[1] is a data property on args[0] 2036 // if args[1] is a data property on args[0]
2077 // [false, value, Writeable, Enumerable, Configurable] 2037 // [false, value, Writeable, Enumerable, Configurable]
2078 // if args[1] is an accessor on args[0] 2038 // if args[1] is an accessor on args[0]
2079 // [true, GetFunction, SetFunction, Enumerable, Configurable] 2039 // [true, GetFunction, SetFunction, Enumerable, Configurable]
(...skipping 13131 matching lines...) Expand 10 before | Expand all | Expand 10 after
15211 } 15171 }
15212 return NULL; 15172 return NULL;
15213 } 15173 }
15214 15174
15215 15175
15216 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 15176 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15217 return &(kIntrinsicFunctions[static_cast<int>(id)]); 15177 return &(kIntrinsicFunctions[static_cast<int>(id)]);
15218 } 15178 }
15219 15179
15220 } } // namespace v8::internal 15180 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698