diff options
author | commit-queue@webkit.org <commit-queue@webkit.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2013-01-07 19:03:44 +0000 |
---|---|---|
committer | commit-queue@webkit.org <commit-queue@webkit.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2013-01-07 19:03:44 +0000 |
commit | fdfd8cb65765c0d0ba085c82e9afbf9475b3f918 (patch) | |
tree | 7aabef456131a570405635456359ea78b2f3d72c | |
parent | 77f726bd3a8ac8da5236b018e8322c8717f0185e (diff) | |
download | chromium_src-fdfd8cb65765c0d0ba085c82e9afbf9475b3f918.zip chromium_src-fdfd8cb65765c0d0ba085c82e9afbf9475b3f918.tar.gz chromium_src-fdfd8cb65765c0d0ba085c82e9afbf9475b3f918.tar.bz2 |
[JSC] Copy non-index properties of arrays in SerializedScriptValue
https://bugs.webkit.org/show_bug.cgi?id=105575
Patch by Michael Pruett <michael@68k.org> on 2013-01-07
Reviewed by Oliver Hunt.
The structured cloning algorithm requires copying all properties of
array objects, including non-index properties.
Source/WebCore:
Tests: fast/storage/serialized-script-value.html
storage/indexeddb/structured-clone.html
* bindings/js/SerializedScriptValue.cpp:
(WebCore):
(WebCore::CloneSerializer::serialize):
(WebCore::CloneDeserializer::putProperty):
(WebCore::CloneDeserializer::deserialize):
LayoutTests:
* fast/storage/resources/serialized-script-value.js:
* fast/storage/serialized-script-value-expected.txt:
* fast/storage/serialized-script-value.html:
* platform/chromium/fast/storage/serialized-script-value-expected.txt:
* platform/chromium/fast/storage/serialized-script-value.html:
git-svn-id: svn://svn.chromium.org/blink/trunk@138964 bbb929c8-8fbe-4397-9dbb-9b2b20218538
8 files changed, 437 insertions, 21 deletions
diff --git a/third_party/WebKit/LayoutTests/ChangeLog b/third_party/WebKit/LayoutTests/ChangeLog index 3b90368..efb26c3 100644 --- a/third_party/WebKit/LayoutTests/ChangeLog +++ b/third_party/WebKit/LayoutTests/ChangeLog @@ -1,3 +1,19 @@ +2013-01-07 Michael Pruett <michael@68k.org> + + [JSC] Copy non-index properties of arrays in SerializedScriptValue + https://bugs.webkit.org/show_bug.cgi?id=105575 + + Reviewed by Oliver Hunt. + + The structured cloning algorithm requires copying all properties of + array objects, including non-index properties. + + * fast/storage/resources/serialized-script-value.js: + * fast/storage/serialized-script-value-expected.txt: + * fast/storage/serialized-script-value.html: + * platform/chromium/fast/storage/serialized-script-value-expected.txt: + * platform/chromium/fast/storage/serialized-script-value.html: + 2013-01-07 Mihnea Ovidenie <mihnea@adobe.com> [CSS Regions] LayoutTests/fast/regions/webkit-flow-inlines-inside-regions-bounds-vertical-rl.html has repainting issues diff --git a/third_party/WebKit/LayoutTests/fast/storage/resources/serialized-script-value.js b/third_party/WebKit/LayoutTests/fast/storage/resources/serialized-script-value.js index 7b64414..48731e8 100644 --- a/third_party/WebKit/LayoutTests/fast/storage/resources/serialized-script-value.js +++ b/third_party/WebKit/LayoutTests/fast/storage/resources/serialized-script-value.js @@ -46,6 +46,16 @@ function makeBuffer(bytesPerElement, serializedValues) { return bufferView.buffer; } +function areValuesIdentical(a, b) { + function sortObject(object) { + if (typeof object != "object" || object === null) + return object; + return Object.keys(object).sort().map(function(key) { + return { key: key, value: sortObject(object[key]) }; + }); + } + return JSON.stringify(sortObject(a)) === JSON.stringify(sortObject(b)); +} function _testSerialization(bytesPerElement, obj, values, oldFormat, serializeExceptionValue) { debug(""); @@ -55,10 +65,12 @@ function _testSerialization(bytesPerElement, obj, values, oldFormat, serializeEx debug("Deserialize to " + JSON.stringify(obj) + ":"); self.newObj = internals.deserializeBuffer(makeBuffer(bytesPerElement, values)); shouldBe("JSON.stringify(newObj)", "JSON.stringify(obj)"); + shouldBeTrue("areValuesIdentical(newObj, obj)"); if (oldFormat) { self.newObj = internals.deserializeBuffer(makeBuffer(bytesPerElement, oldFormat)); shouldBe("JSON.stringify(newObj)", "JSON.stringify(obj)"); + shouldBeTrue("areValuesIdentical(newObj, obj)"); } } diff --git a/third_party/WebKit/LayoutTests/fast/storage/serialized-script-value-expected.txt b/third_party/WebKit/LayoutTests/fast/storage/serialized-script-value-expected.txt index 6649859..947d5f5 100644 --- a/third_party/WebKit/LayoutTests/fast/storage/serialized-script-value-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/storage/serialized-script-value-expected.txt @@ -1,134 +1,224 @@ Deserialize to {"foo":"zoo","bar":{"baz":"myNewKey"}}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"foo":"zoo","bar":{"baz":"myNewKey"}}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"foo":"zoo","bar":"myNewKey"}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"foo":"zoo","bar":"myNewKey"}: PASS bufferView.length is expectedBufferValues.length Deserialize to []: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize []: PASS bufferView.length is expectedBufferValues.length Deserialize to {"foo":"zoo"}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"foo":"zoo"}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"foo":null}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"foo":null}: PASS bufferView.length is expectedBufferValues.length Deserialize to {}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {}: PASS bufferView.length is expectedBufferValues.length Deserialize to undefined: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize undefined: PASS bufferView.length is expectedBufferValues.length Deserialize to true: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize true: PASS bufferView.length is expectedBufferValues.length Deserialize to false: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize false: PASS bufferView.length is expectedBufferValues.length Deserialize to [null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize [null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]: PASS bufferView.length is expectedBufferValues.length Deserialize to 10: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize 10: PASS bufferView.length is expectedBufferValues.length Deserialize to -10: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize -10: PASS bufferView.length is expectedBufferValues.length Deserialize to 1073741824: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize 1073741824: PASS bufferView.length is expectedBufferValues.length Deserialize to 36028797018963970: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize 36028797018963970: PASS bufferView.length is expectedBufferValues.length Deserialize to 1.23: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize 1.23: PASS bufferView.length is expectedBufferValues.length Deserialize to "": PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize "": PASS bufferView.length is expectedBufferValues.length Deserialize to "abc": PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize "abc": PASS bufferView.length is expectedBufferValues.length Deserialize to {"integer":123}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"integer":123}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"string":"str"}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"string":"str"}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"list":[1,2,3]}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"list":[1,2,3]}: PASS bufferView.length is expectedBufferValues.length Deserialize to null: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize null: PASS bufferView.length is expectedBufferValues.length Deserialize to {}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"inner":{"hello":"there"},"outer":{"hello":"there"}}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"inner":{"hello":"there"},"outer":{"hello":"there"}}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"hello":"there"}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"hello":"there"}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"a":"a","u":"αβ","d":42}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"a":"a","u":"αβ","d":42}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"a":"ab","u":"αβ","d":42}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"a":"ab","u":"αβ","d":42}: PASS bufferView.length is expectedBufferValues.length +Deserialize to []: +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +Serialize []: +PASS bufferView.length is expectedBufferValues.length + +Deserialize to ["foo","bar"]: +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +Serialize ["foo","bar"]: +PASS bufferView.length is expectedBufferValues.length + Serialize undefined: PASS thrownException.code is expectedException PASS successfullyParsed is true diff --git a/third_party/WebKit/LayoutTests/fast/storage/serialized-script-value.html b/third_party/WebKit/LayoutTests/fast/storage/serialized-script-value.html index b4f6a3c..7494a5c 100644 --- a/third_party/WebKit/LayoutTests/fast/storage/serialized-script-value.html +++ b/third_party/WebKit/LayoutTests/fast/storage/serialized-script-value.html @@ -17,6 +17,18 @@ function testSerialization(obj, values, oldFormat, serializeExceptionValue) { testSerialization({foo: 'zoo', bar: {baz: 'myNewKey'}}, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, + 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10, + 0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00, + 0x6f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x00, + 0x61, 0x00, 0x72, 0x00, 0x02, 0x03, 0x00, 0x00, + 0x00, 0x62, 0x00, 0x61, 0x00, 0x7a, 0x00, 0x10, + 0x08, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x79, 0x00, + 0x4e, 0x00, 0x65, 0x00, 0x77, 0x00, 0x4b, 0x00, + 0x65, 0x00, 0x79, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00, @@ -31,6 +43,16 @@ testSerialization({foo: 'zoo', bar: {baz: 'myNewKey'}}, testSerialization({foo: 'zoo', bar: 'myNewKey'}, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, + 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10, + 0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00, + 0x6f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x00, + 0x61, 0x00, 0x72, 0x00, 0x10, 0x08, 0x00, 0x00, + 0x00, 0x6d, 0x00, 0x79, 0x00, 0x4e, 0x00, 0x65, + 0x00, 0x77, 0x00, 0x4b, 0x00, 0x65, 0x00, 0x79, + 0x00, 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00, @@ -43,11 +65,21 @@ testSerialization({foo: 'zoo', bar: 'myNewKey'}, testSerialization([], [ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff ]); testSerialization({foo: "zoo"}, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, + 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10, + 0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00, + 0x6f, 0x00, 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00, @@ -55,6 +87,11 @@ testSerialization({foo: "zoo"}, ]); testSerialization({foo: null}, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, + 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x04, + 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff @@ -62,63 +99,113 @@ testSerialization({foo: null}, testSerialization({}, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, + 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0xff ]); testSerialization(undefined, [ + 0x04, 0x00, 0x00, 0x00, 0x03 +], +[ 0x03, 0x00, 0x00, 0x00, 0x03 ]); testSerialization(true, [ + 0x04, 0x00, 0x00, 0x00, 0x09 +], +[ 0x03, 0x00, 0x00, 0x00, 0x09 ]); testSerialization(false, [ + 0x04, 0x00, 0x00, 0x00, 0x08 +], +[ 0x03, 0x00, 0x00, 0x00, 0x08 ]); testSerialization(new Array(100), [ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff ]); testSerialization(10, [ + 0x04, 0x00, 0x00, 0x00, 0x05, 0x0a, 0x00, 0x00, + 0x00 +], +[ 0x03, 0x00, 0x00, 0x00, 0x05, 0x0a, 0x00, 0x00, 0x00 ]); testSerialization(-10, [ + 0x04, 0x00, 0x00, 0x00, 0x05, 0xf6, 0xff, 0xff, + 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x05, 0xf6, 0xff, 0xff, 0xff ]); testSerialization(Math.pow(2,30), [ + 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x40 +], +[ 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40 ]); testSerialization(Math.pow(2,55), [ + 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x43, +], +[ 0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x43, ]); testSerialization(1.23, [ + 0x04, 0x00, 0x00, 0x00, 0x0a, 0xae, 0x47, 0xe1, + 0x7a, 0x14, 0xae, 0xf3, 0x3f +], +[ 0x03, 0x00, 0x00, 0x00, 0x0a, 0xae, 0x47, 0xe1, 0x7a, 0x14, 0xae, 0xf3, 0x3f ]); testSerialization("", [ + 0x04, 0x00, 0x00, 0x00, 0x11 +], +[ 0x03, 0x00, 0x00, 0x00, 0x11 ]); testSerialization("abc", [ + 0x04, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, + 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00 +], +[ 0x03, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00 ]); testSerialization({integer: 123}, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, + 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, + 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x05, + 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x05, @@ -126,6 +213,13 @@ testSerialization({integer: 123}, ]); testSerialization({string: "str"}, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, + 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, + 0x00, 0x6e, 0x00, 0x67, 0x00, 0x10, 0x03, 0x00, + 0x00, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, + 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x10, 0x03, 0x00, @@ -134,6 +228,15 @@ testSerialization({string: "str"}, ]); testSerialization({list: [1,2,3]}, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, + 0x00, 0x6c, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, + 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x00, 0x05, + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x05, 0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -144,10 +247,18 @@ testSerialization({list: [1,2,3]}, ]); testSerialization(null, [ + 0x04, 0x00, 0x00, 0x00, 0x04 +], +[ 0x03, 0x00, 0x00, 0x00, 0x04 ]); testSerialization(/abc/, [ + 0x04, 0x00, 0x00, 0x00, 0x12, 0x03, 0x00, 0x00, + 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x00, + 0x00, 0x00, 0x00 +], +[ 0x03, 0x00, 0x00, 0x00, 0x12, 0x03, 0x00, 0x00, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -158,6 +269,18 @@ var outerObject = {inner: innerObject}; outerObject['outer'] = innerObject; testSerialization(outerObject, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, + 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x65, + 0x00, 0x72, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, + 0x6f, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, 0x74, + 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, + 0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, + 0x00, 0x72, 0x00, 0x13, 0x01, 0xff, 0xff, 0xff, + 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, @@ -171,6 +294,13 @@ testSerialization(outerObject, ]); testSerialization(innerObject, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, + 0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, + 0x00, 0x6f, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, 0x00, + 0x65, 0x00, 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, @@ -181,6 +311,14 @@ testSerialization(innerObject, var unicodeObject = {a: 'a', u: String.fromCharCode(0x03B1,0x03B2), d: 42}; testSerialization(unicodeObject, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, + 0x00, 0x61, 0x00, 0x10, 0xfe, 0xff, 0xff, 0xff, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x75, 0x00, 0x10, + 0x02, 0x00, 0x00, 0x00, 0xb1, 0x03, 0xb2, 0x03, + 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x05, 0x2a, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, 0x10, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x75, 0x00, 0x10, @@ -191,6 +329,15 @@ testSerialization(unicodeObject, unicodeObject.a = 'ab'; testSerialization(unicodeObject, [ + 0x04, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, + 0x00, 0x61, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, + 0x61, 0x00, 0x62, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x75, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0xb1, + 0x03, 0xb2, 0x03, 0x01, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x05, 0x2a, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff +], +[ 0x03, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x61, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x61, 0x00, 0x62, 0x00, 0x01, 0x00, 0x00, 0x00, @@ -200,6 +347,42 @@ testSerialization(unicodeObject, 0xff, 0xff ]); +var arrayObject = []; +arrayObject['a'] = true; +arrayObject['b'] = false; +arrayObject['foo'] = 123; +arrayObject['bar'] = 456; +arrayObject[''] = null; +testSerialization(arrayObject, +[ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0xfd, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x61, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, + 0x62, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x66, + 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x05, 0x7b, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x00, + 0x61, 0x00, 0x72, 0x00, 0x05, 0xc8, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, + 0xff, 0xff +]); + +arrayObject[0] = 'foo'; +arrayObject[1] = 'bar'; +testSerialization(arrayObject, +[ + 0x04, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, + 0x00, 0x62, 0x00, 0x61, 0x00, 0x72, 0x00, 0xfd, + 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x61, + 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x62, 0x00, + 0x08, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x05, 0x7b, + 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01, + 0x05, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0xff, 0xff, 0xff, 0xff +]); + testSerialization(function(){}, [], null, DOMException.DATA_CLONE_ERR); </script> <script src="../js/resources/js-test-post.js"></script> diff --git a/third_party/WebKit/LayoutTests/platform/chromium/fast/storage/serialized-script-value-expected.txt b/third_party/WebKit/LayoutTests/platform/chromium/fast/storage/serialized-script-value-expected.txt index 47e0db5..ac75f39 100644 --- a/third_party/WebKit/LayoutTests/platform/chromium/fast/storage/serialized-script-value-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/chromium/fast/storage/serialized-script-value-expected.txt @@ -1,134 +1,180 @@ Deserialize to {"foo":"zoo","bar":{"baz":"myNewKey"}}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"foo":"zoo","bar":{"baz":"myNewKey"}}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"foo":"zoo","bar":"myNewKey"}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"foo":"zoo","bar":"myNewKey"}: PASS bufferView.length is expectedBufferValues.length Deserialize to []: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize []: PASS bufferView.length is expectedBufferValues.length Deserialize to {"foo":"zoo"}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"foo":"zoo"}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"foo":null}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"foo":null}: PASS bufferView.length is expectedBufferValues.length Deserialize to {}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {}: PASS bufferView.length is expectedBufferValues.length Deserialize to undefined: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize undefined: PASS bufferView.length is expectedBufferValues.length Deserialize to true: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize true: PASS bufferView.length is expectedBufferValues.length Deserialize to false: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize false: PASS bufferView.length is expectedBufferValues.length Deserialize to 10: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize 10: PASS bufferView.length is expectedBufferValues.length Deserialize to -10: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize -10: PASS bufferView.length is expectedBufferValues.length Deserialize to 1073741824: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize 1073741824: PASS bufferView.length is expectedBufferValues.length Deserialize to 36028797018963970: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize 36028797018963970: PASS bufferView.length is expectedBufferValues.length Deserialize to 1.23: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize 1.23: PASS bufferView.length is expectedBufferValues.length Deserialize to "": PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize "": PASS bufferView.length is expectedBufferValues.length Deserialize to "abc": PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize "abc": PASS bufferView.length is expectedBufferValues.length Deserialize to {"integer":123}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"integer":123}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"string":"str"}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"string":"str"}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"list":[1,2,3]}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"list":[1,2,3]}: PASS bufferView.length is expectedBufferValues.length Deserialize to null: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize null: PASS bufferView.length is expectedBufferValues.length Deserialize to {}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"inner":{"hello":"there"},"outer":{"hello":"there"}}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"inner":{"hello":"there"},"outer":{"hello":"there"}}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"hello":"there"}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"hello":"there"}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"a":"a","u":"αβ","d":42}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"a":"a","u":"αβ","d":42}: PASS bufferView.length is expectedBufferValues.length Deserialize to {"a":"ab","u":"αβ","d":42}: PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true Serialize {"a":"ab","u":"αβ","d":42}: PASS bufferView.length is expectedBufferValues.length +Deserialize to []: +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +Serialize []: +PASS bufferView.length is expectedBufferValues.length + +Deserialize to ["foo","bar"]: +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +PASS JSON.stringify(newObj) is JSON.stringify(obj) +PASS areValuesIdentical(newObj, obj) is true +Serialize ["foo","bar"]: +PASS bufferView.length is expectedBufferValues.length + Serialize undefined: PASS thrownException.code is expectedException PASS successfullyParsed is true diff --git a/third_party/WebKit/LayoutTests/platform/chromium/fast/storage/serialized-script-value.html b/third_party/WebKit/LayoutTests/platform/chromium/fast/storage/serialized-script-value.html index 5a8b818..2982753 100644 --- a/third_party/WebKit/LayoutTests/platform/chromium/fast/storage/serialized-script-value.html +++ b/third_party/WebKit/LayoutTests/platform/chromium/fast/storage/serialized-script-value.html @@ -105,6 +105,44 @@ testSerialization(unicodeObject, 0x3f75, 0x5301, 0xce04, 0xceb1, 0x3fb2, 0x5301, 0x6401, 0x013f, 0x5449, 0x037b]); +var arrayObject = []; +arrayObject['a'] = true; +arrayObject['b'] = false; +arrayObject['foo'] = 123; +arrayObject['bar'] = 456; +arrayObject[''] = null; +testSerialization(arrayObject, + [0x02ff, 0x003f, 0x0041, 0x013f, 0x0153, + 0x3f61, 0x5401, 0x013f, 0x0153, 0x3f62, + 0x4601, 0x013f, 0x0353, 0x6f66, 0x3f6f, + 0x4901, 0x01f6, 0x013f, 0x0353, 0x6162, + 0x3f72, 0x4901, 0x0790, 0x013f, 0x0053, + 0x013f, 0x2430, 0x0005], + [0x01ff, 0x003f, 0x0041, 0x013f, 0x0153, + 0x3f61, 0x5401, 0x013f, 0x0153, 0x3f62, + 0x4601, 0x013f, 0x0353, 0x6f66, 0x3f6f, + 0x4901, 0x01f6, 0x013f, 0x0353, 0x6162, + 0x3f72, 0x4901, 0x0790, 0x013f, 0x0053, + 0x013f, 0x2430, 0x0005]); + +arrayObject[0] = 'foo'; +arrayObject[1] = 'bar'; +testSerialization(arrayObject, + [0x02ff, 0x003f, 0x0241, 0x013f, 0x0353, + 0x6f66, 0x3f6f, 0x5301, 0x6203, 0x7261, + 0x013f, 0x0153, 0x3f61, 0x5401, 0x013f, + 0x0153, 0x3f62, 0x4601, 0x013f, 0x0353, + 0x6f66, 0x3f6f, 0x4901, 0x01f6, 0x013f, + 0x0353, 0x6162, 0x3f72, 0x4901, 0x0790, + 0x013f, 0x0053, 0x013f, 0x2430, 0x0205], + [0x01ff, 0x003f, 0x0241, 0x013f, 0x0353, + 0x6f66, 0x3f6f, 0x5301, 0x6203, 0x7261, + 0x013f, 0x0153, 0x3f61, 0x5401, 0x013f, + 0x0153, 0x3f62, 0x4601, 0x013f, 0x0353, + 0x6f66, 0x3f6f, 0x4901, 0x01f6, 0x013f, + 0x0353, 0x6162, 0x3f72, 0x4901, 0x0790, + 0x013f, 0x0053, 0x013f, 0x2430, 0x0205]); + testSerialization(function(){}, [], null, DOMException.DATA_CLONE_ERR); </script> <script src="../../../../fast/js/resources/js-test-post.js"></script> diff --git a/third_party/WebKit/Source/WebCore/ChangeLog b/third_party/WebKit/Source/WebCore/ChangeLog index c756c47..455a938 100644 --- a/third_party/WebKit/Source/WebCore/ChangeLog +++ b/third_party/WebKit/Source/WebCore/ChangeLog @@ -1,3 +1,22 @@ +2013-01-07 Michael Pruett <michael@68k.org> + + [JSC] Copy non-index properties of arrays in SerializedScriptValue + https://bugs.webkit.org/show_bug.cgi?id=105575 + + Reviewed by Oliver Hunt. + + The structured cloning algorithm requires copying all properties of + array objects, including non-index properties. + + Tests: fast/storage/serialized-script-value.html + storage/indexeddb/structured-clone.html + + * bindings/js/SerializedScriptValue.cpp: + (WebCore): + (WebCore::CloneSerializer::serialize): + (WebCore::CloneDeserializer::putProperty): + (WebCore::CloneDeserializer::deserialize): + 2013-01-07 Alec Flett <alecflett@chromium.org> IndexedDB: Stub out async IDBDatabaseBackendInterface::createObjectStore diff --git a/third_party/WebKit/Source/WebCore/bindings/js/SerializedScriptValue.cpp b/third_party/WebKit/Source/WebCore/bindings/js/SerializedScriptValue.cpp index 606d280..6273fd1 100644 --- a/third_party/WebKit/Source/WebCore/bindings/js/SerializedScriptValue.cpp +++ b/third_party/WebKit/Source/WebCore/bindings/js/SerializedScriptValue.cpp @@ -160,10 +160,12 @@ static unsigned typedArrayElementSize(ArrayBufferViewSubtag tag) * Version 2. added the ObjectReferenceTag and support for serialization of cyclic graphs. * Version 3. added the FalseObjectTag, TrueObjectTag, NumberObjectTag, StringObjectTag * and EmptyStringObjectTag for serialization of Boolean, Number and String objects. + * Version 4. added support for serializing non-index properties of arrays. */ -static const unsigned int CurrentVersion = 3; -static const unsigned int TerminatorTag = 0xFFFFFFFF; -static const unsigned int StringPoolTag = 0xFFFFFFFE; +static const unsigned CurrentVersion = 4; +static const unsigned TerminatorTag = 0xFFFFFFFF; +static const unsigned StringPoolTag = 0xFFFFFFFE; +static const unsigned NonIndexPropertiesTag = 0xFFFFFFFD; /* * Object serialization is performed according to the following grammar, all tags @@ -838,8 +840,7 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in) Vector<uint32_t, 16> indexStack; Vector<uint32_t, 16> lengthStack; Vector<PropertyNameArray, 16> propertyStack; - Vector<JSObject*, 16> inputObjectStack; - Vector<JSArray*, 16> inputArrayStack; + Vector<JSObject*, 32> inputObjectStack; Vector<WalkerState, 16> stateStack; WalkerState state = StateUnknown; JSValue inValue = in; @@ -849,14 +850,14 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in) arrayStartState: case ArrayStartState: { ASSERT(isArray(inValue)); - if (inputObjectStack.size() + inputArrayStack.size() > maximumFilterRecursion) + if (inputObjectStack.size() > maximumFilterRecursion) return StackOverflowError; JSArray* inArray = asArray(inValue); unsigned length = inArray->length(); if (!startArray(inArray)) break; - inputArrayStack.append(inArray); + inputObjectStack.append(inArray); indexStack.append(0); lengthStack.append(length); // fallthrough @@ -869,13 +870,23 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in) tickCount = ticksUntilNextCheck(); } - JSArray* array = inputArrayStack.last(); + JSObject* array = inputObjectStack.last(); uint32_t index = indexStack.last(); if (index == lengthStack.last()) { - endObject(); - inputArrayStack.removeLast(); indexStack.removeLast(); lengthStack.removeLast(); + + propertyStack.append(PropertyNameArray(m_exec)); + array->methodTable()->getOwnNonIndexPropertyNames(array, m_exec, propertyStack.last(), ExcludeDontEnumProperties); + if (propertyStack.last().size()) { + write(NonIndexPropertiesTag); + indexStack.append(0); + goto objectStartVisitMember; + } + propertyStack.removeLast(); + + endObject(); + inputObjectStack.removeLast(); break; } inValue = array->getDirectIndex(m_exec, index); @@ -902,7 +913,7 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in) objectStartState: case ObjectStartState: { ASSERT(inValue.isObject()); - if (inputObjectStack.size() + inputArrayStack.size() > maximumFilterRecursion) + if (inputObjectStack.size() > maximumFilterRecursion) return StackOverflowError; JSObject* inObject = asObject(inValue); if (!startObject(inObject)) @@ -1279,9 +1290,9 @@ private: return true; } - void putProperty(JSArray* array, unsigned index, JSValue value) + void putProperty(JSObject* object, unsigned index, JSValue value) { - array->putDirectIndex(m_exec, index, value); + object->putDirectIndex(m_exec, index, value); } void putProperty(JSObject* object, const Identifier& property, JSValue value) @@ -1600,8 +1611,7 @@ DeserializationResult CloneDeserializer::deserialize() { Vector<uint32_t, 16> indexStack; Vector<Identifier, 16> propertyNameStack; - Vector<JSObject*, 16> outputObjectStack; - Vector<JSArray*, 16> outputArrayStack; + Vector<JSObject*, 32> outputObjectStack; Vector<WalkerState, 16> stateStack; WalkerState state = StateUnknown; JSValue outValue; @@ -1618,7 +1628,7 @@ DeserializationResult CloneDeserializer::deserialize() } JSArray* outArray = constructEmptyArray(m_exec, 0, m_globalObject, length); m_gcBuffer.append(outArray); - outputArrayStack.append(outArray); + outputObjectStack.append(outArray); // fallthrough } arrayStartVisitMember: @@ -1635,14 +1645,16 @@ DeserializationResult CloneDeserializer::deserialize() goto error; } if (index == TerminatorTag) { - JSArray* outArray = outputArrayStack.last(); + JSObject* outArray = outputObjectStack.last(); outValue = outArray; - outputArrayStack.removeLast(); + outputObjectStack.removeLast(); break; + } else if (index == NonIndexPropertiesTag) { + goto objectStartVisitMember; } if (JSValue terminal = readTerminal()) { - putProperty(outputArrayStack.last(), index, terminal); + putProperty(outputObjectStack.last(), index, terminal); goto arrayStartVisitMember; } if (m_failed) @@ -1652,14 +1664,14 @@ DeserializationResult CloneDeserializer::deserialize() goto stateUnknown; } case ArrayEndVisitMember: { - JSArray* outArray = outputArrayStack.last(); + JSObject* outArray = outputObjectStack.last(); putProperty(outArray, indexStack.last(), outValue); indexStack.removeLast(); goto arrayStartVisitMember; } objectStartState: case ObjectStartState: { - if (outputObjectStack.size() + outputArrayStack.size() > maximumFilterRecursion) + if (outputObjectStack.size() > maximumFilterRecursion) return make_pair(JSValue(), StackOverflowError); JSObject* outObject = constructEmptyObject(m_exec, m_globalObject); m_gcBuffer.append(outObject); |