| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium 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 "chrome/renderer/extensions/safe_builtins.h" | 5 #include "extensions/renderer/safe_builtins.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "chrome/renderer/extensions/chrome_v8_context.h" | 10 #include "extensions/renderer/script_context.h" |
| 11 | 11 |
| 12 namespace extensions { | 12 namespace extensions { |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 const char kClassName[] = "extensions::SafeBuiltins"; | 16 const char kClassName[] = "extensions::SafeBuiltins"; |
| 17 | 17 |
| 18 // Documentation for makeCallback in the JavaScript, out here to reduce the | 18 // Documentation for makeCallback in the JavaScript, out here to reduce the |
| 19 // (very small) amount of effort that the v8 parser needs to do: | 19 // (very small) amount of effort that the v8 parser needs to do: |
| 20 // | 20 // |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 | 120 |
| 121 v8::Local<v8::String> MakeKey(const char* name, v8::Isolate* isolate) { | 121 v8::Local<v8::String> MakeKey(const char* name, v8::Isolate* isolate) { |
| 122 return v8::String::NewFromUtf8( | 122 return v8::String::NewFromUtf8( |
| 123 isolate, base::StringPrintf("%s::%s", kClassName, name).c_str()); | 123 isolate, base::StringPrintf("%s::%s", kClassName, name).c_str()); |
| 124 } | 124 } |
| 125 | 125 |
| 126 void SaveImpl(const char* name, | 126 void SaveImpl(const char* name, |
| 127 v8::Local<v8::Value> value, | 127 v8::Local<v8::Value> value, |
| 128 v8::Local<v8::Context> context) { | 128 v8::Local<v8::Context> context) { |
| 129 CHECK(!value.IsEmpty() && value->IsObject()) << name; | 129 CHECK(!value.IsEmpty() && value->IsObject()) << name; |
| 130 context->Global() | 130 context->Global()->SetHiddenValue(MakeKey(name, context->GetIsolate()), |
| 131 ->SetHiddenValue(MakeKey(name, context->GetIsolate()), value); | 131 value); |
| 132 } | 132 } |
| 133 | 133 |
| 134 v8::Local<v8::Object> Load(const char* name, v8::Handle<v8::Context> context) { | 134 v8::Local<v8::Object> Load(const char* name, v8::Handle<v8::Context> context) { |
| 135 v8::Local<v8::Value> value = | 135 v8::Local<v8::Value> value = |
| 136 context->Global()->GetHiddenValue(MakeKey(name, context->GetIsolate())); | 136 context->Global()->GetHiddenValue(MakeKey(name, context->GetIsolate())); |
| 137 CHECK(!value.IsEmpty() && value->IsObject()) << name; | 137 CHECK(!value.IsEmpty() && value->IsObject()) << name; |
| 138 return value->ToObject(); | 138 return value->ToObject(); |
| 139 } | 139 } |
| 140 | 140 |
| 141 class ExtensionImpl : public v8::Extension { | 141 class ExtensionImpl : public v8::Extension { |
| 142 public: | 142 public: |
| 143 ExtensionImpl() : v8::Extension(kClassName, kScript) {} | 143 ExtensionImpl() : v8::Extension(kClassName, kScript) {} |
| 144 | 144 |
| 145 private: | 145 private: |
| 146 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( | 146 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( |
| 147 v8::Isolate* isolate, | 147 v8::Isolate* isolate, |
| 148 v8::Handle<v8::String> name) OVERRIDE { | 148 v8::Handle<v8::String> name) OVERRIDE { |
| 149 if (name->Equals(v8::String::NewFromUtf8(isolate, "Apply"))) | 149 if (name->Equals(v8::String::NewFromUtf8(isolate, "Apply"))) |
| 150 return v8::FunctionTemplate::New(isolate, Apply); | 150 return v8::FunctionTemplate::New(isolate, Apply); |
| 151 if (name->Equals(v8::String::NewFromUtf8(isolate, "Save"))) | 151 if (name->Equals(v8::String::NewFromUtf8(isolate, "Save"))) |
| 152 return v8::FunctionTemplate::New(isolate, Save); | 152 return v8::FunctionTemplate::New(isolate, Save); |
| 153 NOTREACHED() << *v8::String::Utf8Value(name); | 153 NOTREACHED() << *v8::String::Utf8Value(name); |
| 154 return v8::Handle<v8::FunctionTemplate>(); | 154 return v8::Handle<v8::FunctionTemplate>(); |
| 155 } | 155 } |
| 156 | 156 |
| 157 static void Apply(const v8::FunctionCallbackInfo<v8::Value>& info) { | 157 static void Apply(const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 158 CHECK(info.Length() == 5 && | 158 CHECK(info.Length() == 5 && info[0]->IsFunction() && // function |
| 159 info[0]->IsFunction() && // function | |
| 160 // info[1] could be an object or a string | 159 // info[1] could be an object or a string |
| 161 info[2]->IsObject() && // args | 160 info[2]->IsObject() && // args |
| 162 info[3]->IsInt32() && // first_arg_index | 161 info[3]->IsInt32() && // first_arg_index |
| 163 info[4]->IsInt32()); // args_length | 162 info[4]->IsInt32()); // args_length |
| 164 v8::Local<v8::Function> function = info[0].As<v8::Function>(); | 163 v8::Local<v8::Function> function = info[0].As<v8::Function>(); |
| 165 v8::Local<v8::Object> recv; | 164 v8::Local<v8::Object> recv; |
| 166 if (info[1]->IsObject()) { | 165 if (info[1]->IsObject()) { |
| 167 recv = info[1]->ToObject(); | 166 recv = info[1]->ToObject(); |
| 168 } else if (info[1]->IsString()) { | 167 } else if (info[1]->IsString()) { |
| 169 recv = v8::StringObject::New(info[1]->ToString())->ToObject(); | 168 recv = v8::StringObject::New(info[1]->ToString())->ToObject(); |
| 170 } else { | 169 } else { |
| 171 info.GetIsolate()->ThrowException( | 170 info.GetIsolate()->ThrowException( |
| 172 v8::Exception::TypeError(v8::String::NewFromUtf8( | 171 v8::Exception::TypeError(v8::String::NewFromUtf8( |
| 173 info.GetIsolate(), | 172 info.GetIsolate(), |
| 174 "The first argument is the receiver and must be an object"))); | 173 "The first argument is the receiver and must be an object"))); |
| 175 return; | 174 return; |
| 176 } | 175 } |
| 177 v8::Local<v8::Object> args = info[2]->ToObject(); | 176 v8::Local<v8::Object> args = info[2]->ToObject(); |
| 178 int first_arg_index = static_cast<int>(info[3]->ToInt32()->Value()); | 177 int first_arg_index = static_cast<int>(info[3]->ToInt32()->Value()); |
| 179 int args_length = static_cast<int>(info[4]->ToInt32()->Value()); | 178 int args_length = static_cast<int>(info[4]->ToInt32()->Value()); |
| 180 | 179 |
| 181 int argc = args_length - first_arg_index; | 180 int argc = args_length - first_arg_index; |
| 182 scoped_ptr<v8::Local<v8::Value>[]> argv(new v8::Local<v8::Value>[argc]); | 181 scoped_ptr<v8::Local<v8::Value> []> argv(new v8::Local<v8::Value>[argc]); |
| 183 for (int i = 0; i < argc; ++i) { | 182 for (int i = 0; i < argc; ++i) { |
| 184 CHECK(args->Has(i + first_arg_index)); | 183 CHECK(args->Has(i + first_arg_index)); |
| 185 argv[i] = args->Get(i + first_arg_index); | 184 argv[i] = args->Get(i + first_arg_index); |
| 186 } | 185 } |
| 187 | 186 |
| 188 v8::Local<v8::Value> return_value = function->Call(recv, argc, argv.get()); | 187 v8::Local<v8::Value> return_value = function->Call(recv, argc, argv.get()); |
| 189 if (!return_value.IsEmpty()) | 188 if (!return_value.IsEmpty()) |
| 190 info.GetReturnValue().Set(return_value); | 189 info.GetReturnValue().Set(return_value); |
| 191 } | 190 } |
| 192 | 191 |
| 193 static void Save(const v8::FunctionCallbackInfo<v8::Value>& info) { | 192 static void Save(const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 194 CHECK(info.Length() == 2 && | 193 CHECK(info.Length() == 2 && info[0]->IsString() && info[1]->IsObject()); |
| 195 info[0]->IsString() && | |
| 196 info[1]->IsObject()); | |
| 197 SaveImpl(*v8::String::Utf8Value(info[0]), | 194 SaveImpl(*v8::String::Utf8Value(info[0]), |
| 198 info[1], | 195 info[1], |
| 199 info.GetIsolate()->GetCallingContext()); | 196 info.GetIsolate()->GetCallingContext()); |
| 200 } | 197 } |
| 201 }; | 198 }; |
| 202 | 199 |
| 203 } // namespace | 200 } // namespace |
| 204 | 201 |
| 205 // static | 202 // static |
| 206 v8::Extension* SafeBuiltins::CreateV8Extension() { | 203 v8::Extension* SafeBuiltins::CreateV8Extension() { return new ExtensionImpl(); } |
| 207 return new ExtensionImpl(); | |
| 208 } | |
| 209 | 204 |
| 210 SafeBuiltins::SafeBuiltins(ChromeV8Context* context) : context_(context) {} | 205 SafeBuiltins::SafeBuiltins(ScriptContext* context) : context_(context) {} |
| 211 | 206 |
| 212 SafeBuiltins::~SafeBuiltins() {} | 207 SafeBuiltins::~SafeBuiltins() {} |
| 213 | 208 |
| 214 v8::Local<v8::Object> SafeBuiltins::GetArray() const { | 209 v8::Local<v8::Object> SafeBuiltins::GetArray() const { |
| 215 return Load("Array", context_->v8_context()); | 210 return Load("Array", context_->v8_context()); |
| 216 } | 211 } |
| 217 | 212 |
| 218 v8::Local<v8::Object> SafeBuiltins::GetFunction() const { | 213 v8::Local<v8::Object> SafeBuiltins::GetFunction() const { |
| 219 return Load("Function", context_->v8_context()); | 214 return Load("Function", context_->v8_context()); |
| 220 } | 215 } |
| 221 | 216 |
| 222 v8::Local<v8::Object> SafeBuiltins::GetJSON() const { | 217 v8::Local<v8::Object> SafeBuiltins::GetJSON() const { |
| 223 return Load("JSON", context_->v8_context()); | 218 return Load("JSON", context_->v8_context()); |
| 224 } | 219 } |
| 225 | 220 |
| 226 v8::Local<v8::Object> SafeBuiltins::GetObjekt() const { | 221 v8::Local<v8::Object> SafeBuiltins::GetObjekt() const { |
| 227 return Load("Object", context_->v8_context()); | 222 return Load("Object", context_->v8_context()); |
| 228 } | 223 } |
| 229 | 224 |
| 230 v8::Local<v8::Object> SafeBuiltins::GetRegExp() const { | 225 v8::Local<v8::Object> SafeBuiltins::GetRegExp() const { |
| 231 return Load("RegExp", context_->v8_context()); | 226 return Load("RegExp", context_->v8_context()); |
| 232 } | 227 } |
| 233 | 228 |
| 234 v8::Local<v8::Object> SafeBuiltins::GetString() const { | 229 v8::Local<v8::Object> SafeBuiltins::GetString() const { |
| 235 return Load("String", context_->v8_context()); | 230 return Load("String", context_->v8_context()); |
| 236 } | 231 } |
| 237 | 232 |
| 238 } // namespace extensions | 233 } // namespace extensions |
| OLD | NEW |