Chromium Code Reviews| Index: chrome/renderer/extensions/send_request_natives.cc |
| diff --git a/chrome/renderer/extensions/send_request_natives.cc b/chrome/renderer/extensions/send_request_natives.cc |
| index a5a8834f77aff0ee742c5d5c8554f4bcbb3379e9..4c863601fd0930525eb271fa79e424f6cf38aa1e 100644 |
| --- a/chrome/renderer/extensions/send_request_natives.cc |
| +++ b/chrome/renderer/extensions/send_request_natives.cc |
| @@ -4,7 +4,12 @@ |
| #include "chrome/renderer/extensions/send_request_natives.h" |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/lazy_instance.h" |
| #include "base/json/json_reader.h" |
| +#include "base/string_util.h" |
| #include "content/public/renderer/v8_value_converter.h" |
| #include "chrome/renderer/extensions/request_sender.h" |
| @@ -12,6 +17,56 @@ using content::V8ValueConverter; |
| namespace extensions { |
| +namespace { |
| + |
| +// Safely converts v8 objects into values depending on the API that's being |
| +// called. |
| +// |
| +// Some APIs can handle nulls in objects, others can't. For some that can |
|
koz (OOO until 15th September)
2012/09/12 02:08:28
"For some that can" -> "For those that can"
|
| +// (e.g. the storage API) it's important that they can handle nulls since this |
| +// actually changes what values would be stored. |
| +class NullSafeV8ValueConverter { |
| + public: |
| + NullSafeV8ValueConverter() { |
| + null_safe_apis_.push_back("storage."); |
| + } |
| + |
| + scoped_ptr<Value> FromV8Value(const std::string& name, |
| + v8::Handle<v8::Value> value) { |
| + scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| + |
| + // Make "undefined" the same as "null" for optional arguments, but for |
| + // objects strip nulls (like {foo: null}, and therefore {foo: undefined} as |
| + // well) to make it easier for extension APIs to check for optional |
| + // arguments (and unless it's a "null safe" API (as explained above). |
| + converter->SetUndefinedAllowed(true); |
| + if (!IsNullSafe(name)) { |
| + converter->SetStripNullFromObjects(true); |
| + } |
| + |
| + return make_scoped_ptr( |
| + converter->FromV8Value(value, v8::Context::GetCurrent())); |
| + } |
| + |
| + private: |
| + bool IsNullSafe(const std::string& name) { |
| + for (std::vector<std::string>::iterator it = null_safe_apis_.begin(); |
| + it != null_safe_apis_.end(); ++it) { |
| + if (StartsWithASCII(name, *it, true /* case sensitive */)) |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + std::vector<std::string> null_safe_apis_; |
| +}; |
| + |
| +base::LazyInstance<NullSafeV8ValueConverter> g_null_safe_v8_value_converter = |
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| +} // namespace |
| + |
| + |
| SendRequestNatives::SendRequestNatives(Dispatcher* dispatcher, |
| RequestSender* request_sender) |
| : ChromeV8Extension(dispatcher), request_sender_(request_sender) { |
| @@ -38,16 +93,8 @@ v8::Handle<v8::Value> SendRequestNatives::StartRequest( |
| bool has_callback = args[3]->BooleanValue(); |
| bool for_io_thread = args[4]->BooleanValue(); |
| - scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
| - |
| - // Make "undefined" the same as "null" for optional arguments, but for objects |
| - // strip nulls (like {foo: null}, and therefore {foo: undefined} as well) to |
| - // make it easier for extension APIs to check for optional arguments. |
| - converter->SetUndefinedAllowed(true); |
| - converter->SetStripNullFromObjects(true); |
| - |
| - scoped_ptr<Value> value_args( |
| - converter->FromV8Value(args[1], v8::Context::GetCurrent())); |
| + scoped_ptr<Value> value_args = |
| + g_null_safe_v8_value_converter.Get().FromV8Value(name, args[1]); |
| if (!value_args.get() || !value_args->IsType(Value::TYPE_LIST)) { |
| NOTREACHED() << "Unable to convert args passed to StartRequest"; |
| return v8::Undefined(); |