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

Side by Side Diff: src/builtins/builtins-promise.cc

Issue 2628863002: Do security checks in the promise constructor (Closed)
Patch Set: updates Created 3 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/builtins/builtins-promise.h ('k') | src/code-stub-assembler.h » ('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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/builtins/builtins-promise.h" 5 #include "src/builtins/builtins-promise.h"
6 #include "src/builtins/builtins-constructor.h" 6 #include "src/builtins/builtins-constructor.h"
7 #include "src/builtins/builtins-utils.h" 7 #include "src/builtins/builtins-utils.h"
8 #include "src/builtins/builtins.h" 8 #include "src/builtins/builtins.h"
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/code-stub-assembler.h" 10 #include "src/code-stub-assembler.h"
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 Heap::kUndefinedValueRootIndex); 897 Heap::kUndefinedValueRootIndex);
898 StoreObjectFieldRoot(promise, JSPromise::kDeferredOnRejectOffset, 898 StoreObjectFieldRoot(promise, JSPromise::kDeferredOnRejectOffset,
899 Heap::kUndefinedValueRootIndex); 899 Heap::kUndefinedValueRootIndex);
900 StoreObjectFieldRoot(promise, JSPromise::kFulfillReactionsOffset, 900 StoreObjectFieldRoot(promise, JSPromise::kFulfillReactionsOffset,
901 Heap::kUndefinedValueRootIndex); 901 Heap::kUndefinedValueRootIndex);
902 StoreObjectFieldRoot(promise, JSPromise::kRejectReactionsOffset, 902 StoreObjectFieldRoot(promise, JSPromise::kRejectReactionsOffset,
903 Heap::kUndefinedValueRootIndex); 903 Heap::kUndefinedValueRootIndex);
904 } 904 }
905 } 905 }
906 906
907 void PromiseBuiltinsAssembler::BranchIfAccessCheckFailed(
908 Node* context, Node* native_context, Node* promise_constructor,
909 Node* executor, Label* if_noaccess) {
910 Variable var_executor(this, MachineRepresentation::kTagged);
911 var_executor.Bind(executor);
912 Label has_access(this), call_runtime(this, Label::kDeferred);
913
914 // If executor is a bound function, load the bound function until we've
915 // reached an actual function.
916 Label found_function(this), loop_over_bound_function(this, &var_executor);
917 Goto(&loop_over_bound_function);
918 Bind(&loop_over_bound_function);
919 {
920 Node* executor_type = LoadInstanceType(var_executor.value());
921 GotoIf(InstanceTypeEqual(executor_type, JS_FUNCTION_TYPE), &found_function);
922 GotoUnless(InstanceTypeEqual(executor_type, JS_BOUND_FUNCTION_TYPE),
923 &call_runtime);
924 var_executor.Bind(LoadObjectField(
925 var_executor.value(), JSBoundFunction::kBoundTargetFunctionOffset));
926 Goto(&loop_over_bound_function);
927 }
928
929 // Load the context from the function and compare it to the Promise
930 // constructor's context. If they match, everything is fine, otherwise, bail
931 // out to the runtime.
932 Bind(&found_function);
933 {
934 Node* function_context =
935 LoadObjectField(var_executor.value(), JSFunction::kContextOffset);
936 Node* native_function_context = LoadNativeContext(function_context);
937 Branch(WordEqual(native_context, native_function_context), &has_access,
938 &call_runtime);
939 }
940
941 Bind(&call_runtime);
942 {
943 Branch(WordEqual(CallRuntime(Runtime::kAllowDynamicFunction, context,
944 promise_constructor),
945 BooleanConstant(true)),
946 &has_access, if_noaccess);
947 }
948
949 Bind(&has_access);
950 }
951
907 // ES#sec-promise-reject-functions 952 // ES#sec-promise-reject-functions
908 // Promise Reject Functions 953 // Promise Reject Functions
909 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) { 954 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) {
910 Node* const value = Parameter(1); 955 Node* const value = Parameter(1);
911 Node* const context = Parameter(4); 956 Node* const context = Parameter(4);
912 957
913 Label out(this); 958 Label out(this);
914 959
915 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. 960 // 3. Let alreadyResolved be F.[[AlreadyResolved]].
916 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot; 961 int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 999
955 Node* const executor_map = LoadMap(executor); 1000 Node* const executor_map = LoadMap(executor);
956 GotoUnless(IsCallableMap(executor_map), &if_notcallable); 1001 GotoUnless(IsCallableMap(executor_map), &if_notcallable);
957 1002
958 Node* const native_context = LoadNativeContext(context); 1003 Node* const native_context = LoadNativeContext(context);
959 Node* const promise_fun = 1004 Node* const promise_fun =
960 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); 1005 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
961 Node* const is_debug_active = IsDebugActive(); 1006 Node* const is_debug_active = IsDebugActive();
962 Label if_targetisnotmodified(this), 1007 Label if_targetisnotmodified(this),
963 if_targetismodified(this, Label::kDeferred), run_executor(this), 1008 if_targetismodified(this, Label::kDeferred), run_executor(this),
964 debug_push(this); 1009 debug_push(this), if_noaccess(this, Label::kDeferred);
1010
1011 BranchIfAccessCheckFailed(context, native_context, promise_fun, executor,
1012 &if_noaccess);
965 1013
966 Branch(WordEqual(promise_fun, new_target), &if_targetisnotmodified, 1014 Branch(WordEqual(promise_fun, new_target), &if_targetisnotmodified,
967 &if_targetismodified); 1015 &if_targetismodified);
968 1016
969 Variable var_result(this, MachineRepresentation::kTagged), 1017 Variable var_result(this, MachineRepresentation::kTagged),
970 var_reject_call(this, MachineRepresentation::kTagged), 1018 var_reject_call(this, MachineRepresentation::kTagged),
971 var_reason(this, MachineRepresentation::kTagged); 1019 var_reason(this, MachineRepresentation::kTagged);
972 1020
973 Bind(&if_targetisnotmodified); 1021 Bind(&if_targetisnotmodified);
974 { 1022 {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 } 1087 }
1040 1088
1041 // 2. If IsCallable(executor) is false, throw a TypeError exception. 1089 // 2. If IsCallable(executor) is false, throw a TypeError exception.
1042 Bind(&if_notcallable); 1090 Bind(&if_notcallable);
1043 { 1091 {
1044 Node* const message_id = 1092 Node* const message_id =
1045 SmiConstant(MessageTemplate::kResolverNotAFunction); 1093 SmiConstant(MessageTemplate::kResolverNotAFunction);
1046 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); 1094 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
1047 Return(UndefinedConstant()); // Never reached. 1095 Return(UndefinedConstant()); // Never reached.
1048 } 1096 }
1097
1098 // Silently fail if the stack looks fishy.
1099 Bind(&if_noaccess);
1100 {
1101 Node* const counter_id =
1102 SmiConstant(v8::Isolate::kPromiseConstructorReturnedUndefined);
1103 CallRuntime(Runtime::kIncrementUseCounter, context, counter_id);
1104 Return(UndefinedConstant());
1105 }
1049 } 1106 }
1050 1107
1051 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { 1108 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
1052 Node* const parent = Parameter(1); 1109 Node* const parent = Parameter(1);
1053 Node* const context = Parameter(4); 1110 Node* const context = Parameter(4);
1054 Return(AllocateAndInitJSPromise(context, parent)); 1111 Return(AllocateAndInitJSPromise(context, parent));
1055 } 1112 }
1056 1113
1057 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) { 1114 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) {
1058 Node* const maybe_promise = Parameter(1); 1115 Node* const maybe_promise = Parameter(1);
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 1506
1450 // 5. Return promiseCapability.[[Promise]]. 1507 // 5. Return promiseCapability.[[Promise]].
1451 Node* const promise = 1508 Node* const promise =
1452 LoadObjectField(capability, JSPromiseCapability::kPromiseOffset); 1509 LoadObjectField(capability, JSPromiseCapability::kPromiseOffset);
1453 Return(promise); 1510 Return(promise);
1454 } 1511 }
1455 } 1512 }
1456 1513
1457 } // namespace internal 1514 } // namespace internal
1458 } // namespace v8 1515 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698