OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 if (current->IsAccessCheckNeeded() && | 995 if (current->IsAccessCheckNeeded() && |
996 !(isolate->*mayAccess)(current, key, access_type)) { | 996 !(isolate->*mayAccess)(current, key, access_type)) { |
997 return false; | 997 return false; |
998 } | 998 } |
999 if (current == holder) break; | 999 if (current == holder) break; |
1000 } | 1000 } |
1001 return true; | 1001 return true; |
1002 } | 1002 } |
1003 | 1003 |
1004 | 1004 |
1005 static bool CheckElementAccess( | 1005 enum AccessCheckResult { |
| 1006 ACCESS_FORBIDDEN, |
| 1007 ACCESS_ALLOWED, |
| 1008 ACCESS_ABSENT |
| 1009 }; |
| 1010 |
| 1011 |
| 1012 static AccessCheckResult CheckElementAccess( |
1006 JSObject* obj, | 1013 JSObject* obj, |
1007 uint32_t index, | 1014 uint32_t index, |
1008 v8::AccessType access_type) { | 1015 v8::AccessType access_type) { |
1009 // TODO(1095): we should traverse hidden prototype hierachy as well. | 1016 // TODO(1095): we should traverse hidden prototype hierachy as well. |
1010 if (CheckGenericAccess( | 1017 if (CheckGenericAccess( |
1011 obj, obj, index, access_type, &Isolate::MayIndexedAccess)) { | 1018 obj, obj, index, access_type, &Isolate::MayIndexedAccess)) { |
1012 return true; | 1019 return ACCESS_ALLOWED; |
1013 } | 1020 } |
1014 | 1021 |
1015 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); | 1022 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); |
1016 return false; | 1023 return ACCESS_FORBIDDEN; |
1017 } | 1024 } |
1018 | 1025 |
1019 | 1026 |
1020 static bool CheckPropertyAccess( | 1027 static AccessCheckResult CheckPropertyAccess( |
1021 JSObject* obj, | 1028 JSObject* obj, |
1022 String* name, | 1029 String* name, |
1023 v8::AccessType access_type) { | 1030 v8::AccessType access_type) { |
1024 uint32_t index; | 1031 uint32_t index; |
1025 if (name->AsArrayIndex(&index)) { | 1032 if (name->AsArrayIndex(&index)) { |
1026 return CheckElementAccess(obj, index, access_type); | 1033 return CheckElementAccess(obj, index, access_type); |
1027 } | 1034 } |
1028 | 1035 |
1029 LookupResult lookup(obj->GetIsolate()); | 1036 LookupResult lookup(obj->GetIsolate()); |
1030 obj->LocalLookup(name, &lookup); | 1037 obj->LocalLookup(name, &lookup); |
1031 | 1038 |
| 1039 if (!lookup.IsProperty()) return ACCESS_ABSENT; |
1032 if (CheckGenericAccess<Object*>( | 1040 if (CheckGenericAccess<Object*>( |
1033 obj, lookup.holder(), name, access_type, &Isolate::MayNamedAccess)) { | 1041 obj, lookup.holder(), name, access_type, &Isolate::MayNamedAccess)) { |
1034 return true; | 1042 return ACCESS_ALLOWED; |
1035 } | 1043 } |
1036 | 1044 |
1037 // Access check callback denied the access, but some properties | 1045 // Access check callback denied the access, but some properties |
1038 // can have a special permissions which override callbacks descision | 1046 // can have a special permissions which override callbacks descision |
1039 // (currently see v8::AccessControl). | 1047 // (currently see v8::AccessControl). |
1040 // API callbacks can have per callback access exceptions. | 1048 // API callbacks can have per callback access exceptions. |
1041 switch (lookup.type()) { | 1049 switch (lookup.type()) { |
1042 case CALLBACKS: | 1050 case CALLBACKS: |
1043 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { | 1051 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { |
1044 return true; | 1052 return ACCESS_ALLOWED; |
1045 } | 1053 } |
1046 break; | 1054 break; |
1047 case INTERCEPTOR: | 1055 case INTERCEPTOR: |
1048 // If the object has an interceptor, try real named properties. | 1056 // If the object has an interceptor, try real named properties. |
1049 // Overwrite the result to fetch the correct property later. | 1057 // Overwrite the result to fetch the correct property later. |
1050 lookup.holder()->LookupRealNamedProperty(name, &lookup); | 1058 lookup.holder()->LookupRealNamedProperty(name, &lookup); |
1051 if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) { | 1059 if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) { |
1052 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { | 1060 if (CheckAccessException(lookup.GetCallbackObject(), access_type)) { |
1053 return true; | 1061 return ACCESS_ALLOWED; |
1054 } | 1062 } |
1055 } | 1063 } |
1056 break; | 1064 break; |
1057 default: | 1065 default: |
1058 break; | 1066 break; |
1059 } | 1067 } |
1060 | 1068 |
1061 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); | 1069 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); |
1062 return false; | 1070 return ACCESS_FORBIDDEN; |
1063 } | 1071 } |
1064 | 1072 |
1065 | 1073 |
1066 // Enumerator used as indices into the array returned from GetOwnProperty | 1074 // Enumerator used as indices into the array returned from GetOwnProperty |
1067 enum PropertyDescriptorIndices { | 1075 enum PropertyDescriptorIndices { |
1068 IS_ACCESSOR_INDEX, | 1076 IS_ACCESSOR_INDEX, |
1069 VALUE_INDEX, | 1077 VALUE_INDEX, |
1070 GETTER_INDEX, | 1078 GETTER_INDEX, |
1071 SETTER_INDEX, | 1079 SETTER_INDEX, |
1072 WRITABLE_INDEX, | 1080 WRITABLE_INDEX, |
1073 ENUMERABLE_INDEX, | 1081 ENUMERABLE_INDEX, |
1074 CONFIGURABLE_INDEX, | 1082 CONFIGURABLE_INDEX, |
1075 DESCRIPTOR_SIZE | 1083 DESCRIPTOR_SIZE |
1076 }; | 1084 }; |
1077 | 1085 |
1078 | 1086 |
1079 static MaybeObject* GetOwnProperty(Isolate* isolate, | 1087 static MaybeObject* GetOwnProperty(Isolate* isolate, |
1080 Handle<JSObject> obj, | 1088 Handle<JSObject> obj, |
1081 Handle<String> name) { | 1089 Handle<String> name) { |
1082 Heap* heap = isolate->heap(); | 1090 Heap* heap = isolate->heap(); |
| 1091 // Due to some WebKit tests, we want to make sure that we do not log |
| 1092 // more than one access failure here. |
| 1093 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { |
| 1094 case ACCESS_FORBIDDEN: return heap->false_value(); |
| 1095 case ACCESS_ALLOWED: break; |
| 1096 case ACCESS_ABSENT: return heap->undefined_value(); |
| 1097 } |
| 1098 |
1083 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); | 1099 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); |
1084 if (attrs == ABSENT) return heap->undefined_value(); | 1100 if (attrs == ABSENT) return heap->undefined_value(); |
1085 AccessorPair* accessors = obj->GetLocalPropertyAccessorPair(*name); | 1101 AccessorPair* accessors = obj->GetLocalPropertyAccessorPair(*name); |
1086 | 1102 |
1087 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); | 1103 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
1088 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); | 1104 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); |
1089 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); | 1105 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); |
1090 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(accessors != NULL)); | 1106 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(accessors != NULL)); |
1091 | 1107 |
1092 if (accessors == NULL) { | 1108 if (accessors == NULL) { |
(...skipping 12208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13301 // Handle last resort GC and make sure to allow future allocations | 13317 // Handle last resort GC and make sure to allow future allocations |
13302 // to grow the heap without causing GCs (if possible). | 13318 // to grow the heap without causing GCs (if possible). |
13303 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13319 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13304 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13320 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13305 "Runtime::PerformGC"); | 13321 "Runtime::PerformGC"); |
13306 } | 13322 } |
13307 } | 13323 } |
13308 | 13324 |
13309 | 13325 |
13310 } } // namespace v8::internal | 13326 } } // namespace v8::internal |
OLD | NEW |