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

Side by Side Diff: src/builtins.cc

Issue 2034083002: Don't compile functions in a context the caller doesn't have access to (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: updates Created 4 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
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 "src/builtins.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 4084 matching lines...) Expand 10 before | Expand all | Expand 10 after
4095 4095
4096 4096
4097 // static 4097 // static
4098 void Builtins::Generate_DatePrototypeGetUTCSeconds(MacroAssembler* masm) { 4098 void Builtins::Generate_DatePrototypeGetUTCSeconds(MacroAssembler* masm) {
4099 Generate_DatePrototype_GetField(masm, JSDate::kSecondUTC); 4099 Generate_DatePrototype_GetField(masm, JSDate::kSecondUTC);
4100 } 4100 }
4101 4101
4102 4102
4103 namespace { 4103 namespace {
4104 4104
4105 // Walk up the stack expecting:
4106 // - ExitFrame
4107 // - call() (maybe)
4108 // - apply() (maybe)
4109 // - bind() (maybe)
4110 // - JSFunction caller (maybe)
4111 //
4112 // return true if the caller has access to the callee or if an exit frame was
4113 // hit, in which case allow it through, as it could have come through the api.
4114 bool HasAccessToContextForCreateDynamicFunction(
4115 Isolate* isolate, Handle<JSObject> target_global_proxy) {
4116 bool exit_handled = true;
4117 bool has_access = true;
4118 bool done = false;
4119 StackFrameIterator it(isolate);
4120 // Skip exit frame that corresponds to the builtin call.
4121 it.Advance();
4122 for (; !it.done() && !done; it.Advance()) {
4123 StackFrame* raw_frame = it.frame();
4124 if (!raw_frame->is_java_script()) {
4125 if (raw_frame->is_exit()) exit_handled = false;
4126 continue;
4127 }
4128 JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame);
4129 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
4130 outer_frame->Summarize(&frames);
4131 for (int i = frames.length() - 1; i >= 0 && !done; --i) {
4132 FrameSummary& frame = frames[i];
4133 Handle<JSFunction> fun = frame.function();
4134 if (!isolate->MayAccess(handle(fun->context()), target_global_proxy)) {
4135 has_access = false;
4136 done = true;
4137 continue;
4138 }
4139 done = true;
4140 }
4141 }
4142 return !exit_handled || has_access;
4143 }
4144
4105 // ES6 section 19.2.1.1.1 CreateDynamicFunction 4145 // ES6 section 19.2.1.1.1 CreateDynamicFunction
4106 MaybeHandle<JSFunction> CreateDynamicFunction( 4146 MaybeHandle<Object> CreateDynamicFunction(
4107 Isolate* isolate, 4147 Isolate* isolate,
4108 BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args, 4148 BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args,
4109 const char* token) { 4149 const char* token) {
4110 // Compute number of arguments, ignoring the receiver. 4150 // Compute number of arguments, ignoring the receiver.
4111 DCHECK_LE(1, args.length()); 4151 DCHECK_LE(1, args.length());
4112 int const argc = args.length() - 1; 4152 int const argc = args.length() - 1;
4113 4153
4154 Handle<JSFunction> target = args.target<JSFunction>();
4155 Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
4156
4157 if (!HasAccessToContextForCreateDynamicFunction(isolate,
4158 target_global_proxy)) {
4159 isolate->CountUsage(v8::Isolate::kFunctionConstructorReturnedUndefined);
4160 return isolate->factory()->undefined_value();
4161 }
4162
4114 // Build the source string. 4163 // Build the source string.
4115 Handle<String> source; 4164 Handle<String> source;
4116 { 4165 {
4117 IncrementalStringBuilder builder(isolate); 4166 IncrementalStringBuilder builder(isolate);
4118 builder.AppendCharacter('('); 4167 builder.AppendCharacter('(');
4119 builder.AppendCString(token); 4168 builder.AppendCString(token);
4120 builder.AppendCharacter('('); 4169 builder.AppendCharacter('(');
4121 bool parenthesis_in_arg_string = false; 4170 bool parenthesis_in_arg_string = false;
4122 if (argc > 1) { 4171 if (argc > 1) {
4123 for (int i = 1; i < argc; ++i) { 4172 for (int i = 1; i < argc; ++i) {
4124 if (i > 1) builder.AppendCharacter(','); 4173 if (i > 1) builder.AppendCharacter(',');
4125 Handle<String> param; 4174 Handle<String> param;
4126 ASSIGN_RETURN_ON_EXCEPTION( 4175 ASSIGN_RETURN_ON_EXCEPTION(
4127 isolate, param, Object::ToString(isolate, args.at<Object>(i)), 4176 isolate, param, Object::ToString(isolate, args.at<Object>(i)),
4128 JSFunction); 4177 Object);
4129 param = String::Flatten(param); 4178 param = String::Flatten(param);
4130 builder.AppendString(param); 4179 builder.AppendString(param);
4131 // If the formal parameters string include ) - an illegal 4180 // If the formal parameters string include ) - an illegal
4132 // character - it may make the combined function expression 4181 // character - it may make the combined function expression
4133 // compile. We avoid this problem by checking for this early on. 4182 // compile. We avoid this problem by checking for this early on.
4134 DisallowHeapAllocation no_gc; // Ensure vectors stay valid. 4183 DisallowHeapAllocation no_gc; // Ensure vectors stay valid.
4135 String::FlatContent param_content = param->GetFlatContent(); 4184 String::FlatContent param_content = param->GetFlatContent();
4136 for (int i = 0, length = param->length(); i < length; ++i) { 4185 for (int i = 0, length = param->length(); i < length; ++i) {
4137 if (param_content.Get(i) == ')') { 4186 if (param_content.Get(i) == ')') {
4138 parenthesis_in_arg_string = true; 4187 parenthesis_in_arg_string = true;
4139 break; 4188 break;
4140 } 4189 }
4141 } 4190 }
4142 } 4191 }
4143 // If the formal parameters include an unbalanced block comment, the 4192 // If the formal parameters include an unbalanced block comment, the
4144 // function must be rejected. Since JavaScript does not allow nested 4193 // function must be rejected. Since JavaScript does not allow nested
4145 // comments we can include a trailing block comment to catch this. 4194 // comments we can include a trailing block comment to catch this.
4146 builder.AppendCString("\n/**/"); 4195 builder.AppendCString("\n/**/");
4147 } 4196 }
4148 builder.AppendCString(") {\n"); 4197 builder.AppendCString(") {\n");
4149 if (argc > 0) { 4198 if (argc > 0) {
4150 Handle<String> body; 4199 Handle<String> body;
4151 ASSIGN_RETURN_ON_EXCEPTION( 4200 ASSIGN_RETURN_ON_EXCEPTION(
4152 isolate, body, Object::ToString(isolate, args.at<Object>(argc)), 4201 isolate, body, Object::ToString(isolate, args.at<Object>(argc)),
4153 JSFunction); 4202 Object);
4154 builder.AppendString(body); 4203 builder.AppendString(body);
4155 } 4204 }
4156 builder.AppendCString("\n})"); 4205 builder.AppendCString("\n})");
4157 ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), JSFunction); 4206 ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), Object);
4158 4207
4159 // The SyntaxError must be thrown after all the (observable) ToString 4208 // The SyntaxError must be thrown after all the (observable) ToString
4160 // conversions are done. 4209 // conversions are done.
4161 if (parenthesis_in_arg_string) { 4210 if (parenthesis_in_arg_string) {
4162 THROW_NEW_ERROR(isolate, 4211 THROW_NEW_ERROR(isolate,
4163 NewSyntaxError(MessageTemplate::kParenthesisInArgString), 4212 NewSyntaxError(MessageTemplate::kParenthesisInArgString),
4164 JSFunction); 4213 Object);
4165 } 4214 }
4166 } 4215 }
4167 4216
4168 // Compile the string in the constructor and not a helper so that errors to 4217 // Compile the string in the constructor and not a helper so that errors to
4169 // come from here. 4218 // come from here.
4170 Handle<JSFunction> target = args.target<JSFunction>();
4171 Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
4172 Handle<JSFunction> function; 4219 Handle<JSFunction> function;
4173 { 4220 {
4174 ASSIGN_RETURN_ON_EXCEPTION( 4221 ASSIGN_RETURN_ON_EXCEPTION(
4175 isolate, function, 4222 isolate, function,
4176 CompileString(handle(target->native_context(), isolate), source, 4223 CompileString(handle(target->native_context(), isolate), source,
4177 ONLY_SINGLE_FUNCTION_LITERAL), 4224 ONLY_SINGLE_FUNCTION_LITERAL),
4178 JSFunction); 4225 Object);
4179 Handle<Object> result; 4226 Handle<Object> result;
4180 ASSIGN_RETURN_ON_EXCEPTION( 4227 ASSIGN_RETURN_ON_EXCEPTION(
4181 isolate, result, 4228 isolate, result,
4182 Execution::Call(isolate, function, target_global_proxy, 0, nullptr), 4229 Execution::Call(isolate, function, target_global_proxy, 0, nullptr),
4183 JSFunction); 4230 Object);
4184 function = Handle<JSFunction>::cast(result); 4231 function = Handle<JSFunction>::cast(result);
4185 function->shared()->set_name_should_print_as_anonymous(true); 4232 function->shared()->set_name_should_print_as_anonymous(true);
4186 } 4233 }
4187 4234
4188 // If new.target is equal to target then the function created 4235 // If new.target is equal to target then the function created
4189 // is already correctly setup and nothing else should be done 4236 // is already correctly setup and nothing else should be done
4190 // here. But if new.target is not equal to target then we are 4237 // here. But if new.target is not equal to target then we are
4191 // have a Function builtin subclassing case and therefore the 4238 // have a Function builtin subclassing case and therefore the
4192 // function has wrong initial map. To fix that we create a new 4239 // function has wrong initial map. To fix that we create a new
4193 // function object with correct initial map. 4240 // function object with correct initial map.
4194 Handle<Object> unchecked_new_target = args.new_target(); 4241 Handle<Object> unchecked_new_target = args.new_target();
4195 if (!unchecked_new_target->IsUndefined() && 4242 if (!unchecked_new_target->IsUndefined() &&
4196 !unchecked_new_target.is_identical_to(target)) { 4243 !unchecked_new_target.is_identical_to(target)) {
4197 Handle<JSReceiver> new_target = 4244 Handle<JSReceiver> new_target =
4198 Handle<JSReceiver>::cast(unchecked_new_target); 4245 Handle<JSReceiver>::cast(unchecked_new_target);
4199 Handle<Map> initial_map; 4246 Handle<Map> initial_map;
4200 ASSIGN_RETURN_ON_EXCEPTION( 4247 ASSIGN_RETURN_ON_EXCEPTION(
4201 isolate, initial_map, 4248 isolate, initial_map,
4202 JSFunction::GetDerivedMap(isolate, target, new_target), JSFunction); 4249 JSFunction::GetDerivedMap(isolate, target, new_target), Object);
4203 4250
4204 Handle<SharedFunctionInfo> shared_info(function->shared(), isolate); 4251 Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
4205 Handle<Map> map = Map::AsLanguageMode( 4252 Handle<Map> map = Map::AsLanguageMode(
4206 initial_map, shared_info->language_mode(), shared_info->kind()); 4253 initial_map, shared_info->language_mode(), shared_info->kind());
4207 4254
4208 Handle<Context> context(function->context(), isolate); 4255 Handle<Context> context(function->context(), isolate);
4209 function = isolate->factory()->NewFunctionFromSharedFunctionInfo( 4256 function = isolate->factory()->NewFunctionFromSharedFunctionInfo(
4210 map, shared_info, context, NOT_TENURED); 4257 map, shared_info, context, NOT_TENURED);
4211 } 4258 }
4212 return function; 4259 return function;
4213 } 4260 }
4214 4261
4215 } // namespace 4262 } // namespace
4216 4263
4217 4264
4218 // ES6 section 19.2.1.1 Function ( p1, p2, ... , pn, body ) 4265 // ES6 section 19.2.1.1 Function ( p1, p2, ... , pn, body )
4219 BUILTIN(FunctionConstructor) { 4266 BUILTIN(FunctionConstructor) {
4220 HandleScope scope(isolate); 4267 HandleScope scope(isolate);
4221 Handle<JSFunction> result; 4268 Handle<Object> result;
4222 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 4269 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4223 isolate, result, CreateDynamicFunction(isolate, args, "function")); 4270 isolate, result, CreateDynamicFunction(isolate, args, "function"));
4224 return *result; 4271 return *result;
4225 } 4272 }
4226 4273
4227 4274
4228 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args ) 4275 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args )
4229 BUILTIN(FunctionPrototypeBind) { 4276 BUILTIN(FunctionPrototypeBind) {
4230 HandleScope scope(isolate); 4277 HandleScope scope(isolate);
4231 DCHECK_LE(1, args.length()); 4278 DCHECK_LE(1, args.length());
(...skipping 1561 matching lines...) Expand 10 before | Expand all | Expand 10 after
5793 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) 5840 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T)
5794 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 5841 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
5795 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 5842 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
5796 #undef DEFINE_BUILTIN_ACCESSOR_C 5843 #undef DEFINE_BUILTIN_ACCESSOR_C
5797 #undef DEFINE_BUILTIN_ACCESSOR_A 5844 #undef DEFINE_BUILTIN_ACCESSOR_A
5798 #undef DEFINE_BUILTIN_ACCESSOR_T 5845 #undef DEFINE_BUILTIN_ACCESSOR_T
5799 #undef DEFINE_BUILTIN_ACCESSOR_H 5846 #undef DEFINE_BUILTIN_ACCESSOR_H
5800 5847
5801 } // namespace internal 5848 } // namespace internal
5802 } // namespace v8 5849 } // namespace v8
OLDNEW
« no previous file with comments | « include/v8.h ('k') | src/d8.h » ('j') | test/mjsunit/cross-realm-filtering.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698