| Index: content/renderer/v8_value_converter_impl.cc
|
| diff --git a/content/renderer/v8_value_converter_impl.cc b/content/renderer/v8_value_converter_impl.cc
|
| index 4192ec8e4a70c46707d286ec09881e44a3da1321..bcd4dec19f7f6786af1615390a0970a035001cc1 100644
|
| --- a/content/renderer/v8_value_converter_impl.cc
|
| +++ b/content/renderer/v8_value_converter_impl.cc
|
| @@ -27,18 +27,20 @@ V8ValueConverter* V8ValueConverter::create() {
|
| } // namespace content
|
|
|
| V8ValueConverterImpl::V8ValueConverterImpl()
|
| - : undefined_allowed_(false),
|
| + : undefined_value_behavior_(TREAT_AS_ERROR),
|
| date_allowed_(false),
|
| regexp_allowed_(false),
|
| strip_null_from_objects_(false) {
|
| }
|
|
|
| -bool V8ValueConverterImpl::GetUndefinedAllowed() const {
|
| - return undefined_allowed_;
|
| +content::V8ValueConverter::UndefinedValueBehavior
|
| + V8ValueConverterImpl::GetUndefinedValueBehavior() const {
|
| + return undefined_value_behavior_;
|
| }
|
|
|
| -void V8ValueConverterImpl::SetUndefinedAllowed(bool val) {
|
| - undefined_allowed_ = val;
|
| +void V8ValueConverterImpl::SetUndefinedValueBehavior(
|
| + UndefinedValueBehavior val) {
|
| + undefined_value_behavior_ = val;
|
| }
|
|
|
| bool V8ValueConverterImpl::GetDateAllowed() const {
|
| @@ -200,23 +202,43 @@ 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()) {
|
| + switch (undefined_value_behavior_) {
|
| + case TREAT_AS_ERROR:
|
| + LOG(ERROR) << "Unexpected 'undefined' v8 value encountered.";
|
| + return NULL;
|
| + case OMIT:
|
| + return NULL;
|
| + case CONVERT_TO_NULL:
|
| + return Value::CreateNullValue();
|
| + }
|
| + NOTREACHED();
|
| + }
|
|
|
| - if (date_allowed_ && val->IsDate()) {
|
| + if (val->IsDate()) {
|
| + if (!date_allowed_)
|
| + // JSON.stringify would convert this to a string, but {} is more
|
| + // consistent within this class.
|
| + return new DictionaryValue();
|
| 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 (!regexp_allowed_)
|
| + // JSON.stringify converts to {}.
|
| + return new DictionaryValue();
|
| + 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())
|
| + // JSON.stringify refuses to convert function(){}.
|
| + return NULL;
|
| +
|
| if (val->IsObject()) {
|
| BinaryValue* binary_value = FromV8Buffer(val);
|
| if (binary_value) {
|
| @@ -225,8 +247,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 +281,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 +361,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,
|
|
|