Commit a19404f0 authored by yangguo's avatar yangguo Committed by Commit bot

[json] handle proxies in BasicJsonSerializer.

R=cbruni@chromium.org

Review-Url: https://codereview.chromium.org/1994183002
Cr-Commit-Position: refs/heads/master@{#36409}
parent b71f1cc2
......@@ -1088,12 +1088,8 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver,
length = static_cast<uint32_t>(array->length()->Number());
} else {
Handle<Object> val;
Handle<Object> key = isolate->factory()->length_string();
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, val, Runtime::GetObjectProperty(isolate, receiver, key),
false);
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val,
Object::ToLength(isolate, val), false);
isolate, val, Object::GetLengthFromArrayLike(isolate, receiver), false);
// TODO(caitp): Support larger element indexes (up to 2^53-1).
if (!val->ToUint32(&length)) {
length = 0;
......
......@@ -201,9 +201,7 @@ function JSONSerialize(key, holder, replacer, stack, indent, gap) {
function JSONStringify(value, replacer, space) {
if (arguments.length === 1 && !IS_PROXY(value)) {
return %BasicJSONStringify(value, "");
}
if (arguments.length === 1) return %BasicJSONStringify(value, "");
if (!IS_CALLABLE(replacer) && %is_arraylike(replacer)) {
var property_list = new InternalArray();
var seen_properties = new GlobalSet();
......@@ -248,7 +246,7 @@ function JSONStringify(value, replacer, space) {
} else {
gap = "";
}
if (!IS_CALLABLE(replacer) && !property_list && !IS_PROXY(value)) {
if (!IS_CALLABLE(replacer) && !property_list) {
return %BasicJSONStringify(value, gap);
}
return JSONSerialize('', {'': value}, replacer, new Stack(), "", gap);
......
This diff is collapsed.
......@@ -719,14 +719,9 @@ MaybeHandle<FixedArray> Object::CreateListFromArrayLike(
}
// 4. Let len be ? ToLength(? Get(obj, "length")).
Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
Handle<Object> raw_length_obj;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, raw_length_obj,
JSReceiver::GetProperty(receiver, isolate->factory()->length_string()),
FixedArray);
Handle<Object> raw_length_number;
ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number,
Object::ToLength(isolate, raw_length_obj),
Object::GetLengthFromArrayLike(isolate, receiver),
FixedArray);
uint32_t len;
if (!raw_length_number->ToUint32(&len) ||
......@@ -772,6 +767,16 @@ MaybeHandle<FixedArray> Object::CreateListFromArrayLike(
}
// static
MaybeHandle<Object> Object::GetLengthFromArrayLike(Isolate* isolate,
Handle<Object> object) {
Handle<Object> val;
Handle<Object> key = isolate->factory()->length_string();
ASSIGN_RETURN_ON_EXCEPTION(
isolate, val, Runtime::GetObjectProperty(isolate, object, key), Object);
return Object::ToLength(isolate, val);
}
// static
Maybe<bool> JSReceiver::HasProperty(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
......
......@@ -1177,6 +1177,10 @@ class Object {
MUST_USE_RESULT static MaybeHandle<FixedArray> CreateListFromArrayLike(
Isolate* isolate, Handle<Object> object, ElementTypes element_types);
// Get length property and apply ToLength.
MUST_USE_RESULT static MaybeHandle<Object> GetLengthFromArrayLike(
Isolate* isolate, Handle<Object> object);
// Check whether |object| is an instance of Error or NativeError.
static bool IsErrorObject(Isolate* isolate, Handle<Object> object);
......
......@@ -507,3 +507,56 @@ for (var i in log) assertSame(target, log[i][1]);
assertEquals(["get", target, "length", proxy], log[0]);
assertEquals(["get", target, "0", proxy], log[1]);
assertEquals(["deleteProperty", target, "0"], log[2]);
proxy = new Proxy([], {
get: function(target, property) {
if (property == "length") return 7;
return 0;
},
});
assertEquals('[[0,0,0,0,0,0,0]]', JSON.stringify([proxy]));
proxy = new Proxy([], {
get: function(target, property) {
if (property == "length") return 1E40;
return 0;
},
});
assertThrows(() => JSON.stringify([proxy]), RangeError);
log = [];
proxy = new Proxy({}, {
ownKeys: function() {
log.push("ownKeys");
return ["0", "a", "b"];
},
get: function(target, property) {
log.push("get " + property);
return property.toUpperCase();
},
getOwnPropertyDescriptor: function(target, property) {
log.push("descriptor " + property);
return {enumerable: true, configurable: true};
},
isExtensible: assertUnreachable,
has: assertUnreachable,
getPrototypeOf: assertUnreachable,
setPrototypeOf: assertUnreachable,
preventExtensions: assertUnreachable,
setPrototypeOf: assertUnreachable,
defineProperty: assertUnreachable,
set: assertUnreachable,
deleteProperty: assertUnreachable,
apply: assertUnreachable,
construct: assertUnreachable,
});
assertEquals('[{"0":"0","a":"A","b":"B"}]', JSON.stringify([proxy]));
assertEquals(['get toJSON',
'ownKeys',
'descriptor 0',
'descriptor a',
'descriptor b',
'get 0',
'get a',
'get b'], log);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment