diff options
author | kalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-17 04:05:24 +0000 |
---|---|---|
committer | kalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-17 04:05:24 +0000 |
commit | e0658bcde3e33be5f5c50f6c6aeef693bf5c2a99 (patch) | |
tree | 5daa748e37e6476057dcf21412dc4e232f16810b /content/renderer/v8_value_converter_impl.cc | |
parent | 53606d54350cc33bc434ec65a388dfea1211b632 (diff) | |
download | chromium_src-e0658bcde3e33be5f5c50f6c6aeef693bf5c2a99.zip chromium_src-e0658bcde3e33be5f5c50f6c6aeef693bf5c2a99.tar.gz chromium_src-e0658bcde3e33be5f5c50f6c6aeef693bf5c2a99.tar.bz2 |
Make V8ValueConverter.FromV8Value be more consistent with JSON.stringify: don't
serialize undefined as null, don't serialize functions as objects, omit values
from objects when they don't serialize, and insert null into arrays when they
don't serialize.
It is now possible for FromV8Value to return NULL; previously it would return
Value::CreateNullValue on failure.
This is needed for the Storage API, where we promise that the values that are
passed in are serialized as JSON, yet the value conversion doesn't work in a
way that allows it.
However, the null-stripping behavior needs to be configurable so that existing
extension APIs (which only expect null/undefined to appear for optional values)
still work.
BUG=145081
Review URL: https://chromiumcodereview.appspot.com/10890002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157074 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/v8_value_converter_impl.cc')
-rw-r--r-- | content/renderer/v8_value_converter_impl.cc | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/content/renderer/v8_value_converter_impl.cc b/content/renderer/v8_value_converter_impl.cc index 8d55ecc..4c2130d 100644 --- a/content/renderer/v8_value_converter_impl.cc +++ b/content/renderer/v8_value_converter_impl.cc @@ -27,38 +27,22 @@ V8ValueConverter* V8ValueConverter::create() { } // namespace content V8ValueConverterImpl::V8ValueConverterImpl() - : undefined_allowed_(false), - date_allowed_(false), - regexp_allowed_(false), + : date_allowed_(false), + reg_exp_allowed_(false), + function_allowed_(false), strip_null_from_objects_(false) { } -bool V8ValueConverterImpl::GetUndefinedAllowed() const { - return undefined_allowed_; -} - -void V8ValueConverterImpl::SetUndefinedAllowed(bool val) { - undefined_allowed_ = val; -} - -bool V8ValueConverterImpl::GetDateAllowed() const { - return date_allowed_; -} - void V8ValueConverterImpl::SetDateAllowed(bool val) { date_allowed_ = val; } -bool V8ValueConverterImpl::GetRegexpAllowed() const { - return regexp_allowed_; -} - -void V8ValueConverterImpl::SetRegexpAllowed(bool val) { - regexp_allowed_ = val; +void V8ValueConverterImpl::SetRegExpAllowed(bool val) { + reg_exp_allowed_ = val; } -bool V8ValueConverterImpl::GetStripNullFromObjects() const { - return strip_null_from_objects_; +void V8ValueConverterImpl::SetFunctionAllowed(bool val) { + function_allowed_ = val; } void V8ValueConverterImpl::SetStripNullFromObjects(bool val) { @@ -200,23 +184,37 @@ Value* V8ValueConverterImpl::FromV8ValueImpl(v8::Handle<v8::Value> val, return Value::CreateStringValue(std::string(*utf8, utf8.length())); } - if (undefined_allowed_ && val->IsUndefined()) - return Value::CreateNullValue(); + if (val->IsUndefined()) + // JSON.stringify ignores undefined. + return NULL; - if (date_allowed_ && val->IsDate()) { + if (val->IsDate()) { + if (!date_allowed_) + // JSON.stringify would convert this to a string, but an object is more + // consistent within this class. + return FromV8Object(val->ToObject(), unique_set); v8::Date* date = v8::Date::Cast(*val); return Value::CreateDoubleValue(date->NumberValue() / 1000.0); } - if (regexp_allowed_ && val->IsRegExp()) { - return Value::CreateStringValue( - *v8::String::Utf8Value(val->ToString())); + if (val->IsRegExp()) { + if (!reg_exp_allowed_) + // JSON.stringify converts to an object. + return FromV8Object(val->ToObject(), unique_set); + return Value::CreateStringValue(*v8::String::Utf8Value(val->ToString())); } // v8::Value doesn't have a ToArray() method for some reason. if (val->IsArray()) return FromV8Array(val.As<v8::Array>(), unique_set); + if (val->IsFunction()) { + if (!function_allowed_) + // JSON.stringify refuses to convert function(){}. + return NULL; + return FromV8Object(val->ToObject(), unique_set); + } + if (val->IsObject()) { BinaryValue* binary_value = FromV8Buffer(val); if (binary_value) { @@ -225,8 +223,9 @@ Value* V8ValueConverterImpl::FromV8ValueImpl(v8::Handle<v8::Value> val, return FromV8Object(val->ToObject(), unique_set); } } + LOG(ERROR) << "Unexpected v8 value type encountered."; - return Value::CreateNullValue(); + return NULL; } Value* V8ValueConverterImpl::FromV8Array(v8::Handle<v8::Array> val, @@ -258,9 +257,12 @@ Value* V8ValueConverterImpl::FromV8Array(v8::Handle<v8::Array> val, continue; Value* child = FromV8ValueImpl(child_v8, unique_set); - CHECK(child); - - result->Append(child); + if (child) + result->Append(child); + else + // JSON.stringify puts null in places where values don't serialize, for + // example undefined and functions. Emulate that behavior. + result->Append(Value::CreateNullValue()); } return result; } @@ -335,7 +337,10 @@ Value* V8ValueConverterImpl::FromV8Object( } scoped_ptr<Value> child(FromV8ValueImpl(child_v8, unique_set)); - CHECK(child.get()); + if (!child.get()) + // JSON.stringify skips properties whose values don't serialize, for + // example undefined and functions. Emulate that behavior. + continue; // Strip null if asked (and since undefined is turned into null, undefined // too). The use case for supporting this is JSON-schema support, |