summaryrefslogtreecommitdiffstats
path: root/content/renderer/v8_value_converter_impl.cc
diff options
context:
space:
mode:
authorkalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-17 04:05:24 +0000
committerkalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-17 04:05:24 +0000
commite0658bcde3e33be5f5c50f6c6aeef693bf5c2a99 (patch)
tree5daa748e37e6476057dcf21412dc4e232f16810b /content/renderer/v8_value_converter_impl.cc
parent53606d54350cc33bc434ec65a388dfea1211b632 (diff)
downloadchromium_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.cc73
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,