seroval 1.6.11 → 1.6.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev/index.cjs +45 -10
- package/dist/dev/index.js +45 -10
- package/dist/index.cjs +45 -10
- package/dist/index.js +45 -10
- package/package.json +1 -1
package/dist/dev/index.cjs
CHANGED
|
@@ -1003,11 +1003,18 @@ function parseAsyncIteratorFactory(ctx) {
|
|
|
1003
1003
|
function createObjectNode(id, current, empty, record) {
|
|
1004
1004
|
return createSerovalNode(empty ? 11 : 10, id, void 0, void 0, void 0, record, void 0, void 0, void 0, void 0, getObjectFlag(current), void 0);
|
|
1005
1005
|
}
|
|
1006
|
-
|
|
1006
|
+
/**
|
|
1007
|
+
* Gets the sentinel node for a Map. Call it before parsing the entries, so
|
|
1008
|
+
* that an outer Map declares the sentinel before any Map inside it uses it.
|
|
1009
|
+
*/
|
|
1010
|
+
function parseMapSentinel(ctx) {
|
|
1011
|
+
return parseSpecialReference(ctx, 0);
|
|
1012
|
+
}
|
|
1013
|
+
function createMapNode(id, sentinel, k, v) {
|
|
1007
1014
|
return createSerovalNode(8, id, void 0, void 0, void 0, void 0, {
|
|
1008
1015
|
k,
|
|
1009
1016
|
v
|
|
1010
|
-
}, void 0,
|
|
1017
|
+
}, void 0, sentinel, void 0, void 0, void 0);
|
|
1011
1018
|
}
|
|
1012
1019
|
function createPromiseConstructorNode(ctx, id, resolver) {
|
|
1013
1020
|
return createSerovalNode(22, id, resolver, void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 1), void 0, void 0, void 0);
|
|
@@ -1110,13 +1117,14 @@ async function parseAggregateError$1(ctx, depth, id, current) {
|
|
|
1110
1117
|
return createAggregateErrorNode(id, current, options ? await parseProperties$1(ctx, depth, options) : void 0);
|
|
1111
1118
|
}
|
|
1112
1119
|
async function parseMap$1(ctx, depth, id, current) {
|
|
1120
|
+
const sentinel = parseMapSentinel(ctx.base);
|
|
1113
1121
|
const keyNodes = [];
|
|
1114
1122
|
const valueNodes = [];
|
|
1115
1123
|
for (const [key, value] of current.entries()) {
|
|
1116
1124
|
keyNodes.push(await parseAsync(ctx, depth, key));
|
|
1117
1125
|
valueNodes.push(await parseAsync(ctx, depth, value));
|
|
1118
1126
|
}
|
|
1119
|
-
return createMapNode(
|
|
1127
|
+
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
1120
1128
|
}
|
|
1121
1129
|
async function parseSet$1(ctx, depth, id, current) {
|
|
1122
1130
|
const items = [];
|
|
@@ -1770,30 +1778,36 @@ function getAssignmentExpression(assignment) {
|
|
|
1770
1778
|
case 4: return "Object.defineProperty(" + assignment.s + ",\"__proto__\",{value:" + assignment.k + ",configurable:!0,enumerable:!0,writable:!0})";
|
|
1771
1779
|
}
|
|
1772
1780
|
}
|
|
1781
|
+
const MAX_ASSIGNMENT_CHAIN_LENGTH = 100;
|
|
1773
1782
|
function mergeAssignments(assignments) {
|
|
1774
1783
|
const newAssignments = [];
|
|
1775
1784
|
let current = assignments[0];
|
|
1785
|
+
let chainLength = 1;
|
|
1776
1786
|
for (let i = 1, len = assignments.length, item, prev = current; i < len; i++) {
|
|
1777
1787
|
item = assignments[i];
|
|
1778
|
-
if (
|
|
1788
|
+
if (chainLength === MAX_ASSIGNMENT_CHAIN_LENGTH) {
|
|
1789
|
+
newAssignments.push(current);
|
|
1790
|
+
current = item;
|
|
1791
|
+
chainLength = 0;
|
|
1792
|
+
} else if (item.t === 0 && prev.t === 0 && item.v === prev.v) current = {
|
|
1779
1793
|
t: 0,
|
|
1780
1794
|
s: item.s,
|
|
1781
1795
|
k: void 0,
|
|
1782
1796
|
v: getAssignmentExpression(current)
|
|
1783
1797
|
};
|
|
1784
|
-
else if (item.t === 2 && item.s === prev.s) current = {
|
|
1798
|
+
else if (item.t === 2 && prev.t === 2 && item.s === prev.s) current = {
|
|
1785
1799
|
t: 2,
|
|
1786
1800
|
s: getAssignmentExpression(current),
|
|
1787
1801
|
k: item.k,
|
|
1788
1802
|
v: item.v
|
|
1789
1803
|
};
|
|
1790
|
-
else if (item.t === 1 && item.s === prev.s) current = {
|
|
1804
|
+
else if (item.t === 1 && prev.t === 1 && item.s === prev.s) current = {
|
|
1791
1805
|
t: 1,
|
|
1792
1806
|
s: getAssignmentExpression(current),
|
|
1793
1807
|
k: void 0,
|
|
1794
1808
|
v: item.v
|
|
1795
1809
|
};
|
|
1796
|
-
else if (item.t === 3 && item.s === prev.s) current = {
|
|
1810
|
+
else if (item.t === 3 && prev.t === 2 && item.s === prev.s) current = {
|
|
1797
1811
|
t: 3,
|
|
1798
1812
|
s: getAssignmentExpression(current),
|
|
1799
1813
|
k: item.k,
|
|
@@ -1802,7 +1816,9 @@ function mergeAssignments(assignments) {
|
|
|
1802
1816
|
else {
|
|
1803
1817
|
newAssignments.push(current);
|
|
1804
1818
|
current = item;
|
|
1819
|
+
chainLength = 0;
|
|
1805
1820
|
}
|
|
1821
|
+
chainLength++;
|
|
1806
1822
|
prev = item;
|
|
1807
1823
|
}
|
|
1808
1824
|
newAssignments.push(current);
|
|
@@ -1997,6 +2013,22 @@ function isIndexedValueInStack(ctx, node) {
|
|
|
1997
2013
|
return node.t === 4 && ctx.stack.includes(node.i);
|
|
1998
2014
|
}
|
|
1999
2015
|
/**
|
|
2016
|
+
* Checks if the node, or any node inside it, is read from more than one
|
|
2017
|
+
* place. Such a node must not be created inside a deferred assignment,
|
|
2018
|
+
* because the places that read it may run before the assignment does.
|
|
2019
|
+
*/
|
|
2020
|
+
function hasMarkedNode(ctx, node) {
|
|
2021
|
+
if (Array.isArray(node)) {
|
|
2022
|
+
for (let i = 0, len = node.length; i < len; i++) if (hasMarkedNode(ctx, node[i])) return true;
|
|
2023
|
+
return false;
|
|
2024
|
+
}
|
|
2025
|
+
if (node == null || typeof node !== "object") return false;
|
|
2026
|
+
const current = node;
|
|
2027
|
+
if (current.t !== 4 && typeof current.i === "number" && isSerializerRefMarked(ctx, current.i)) return true;
|
|
2028
|
+
for (const key in current) if (hasMarkedNode(ctx, current[key])) return true;
|
|
2029
|
+
return false;
|
|
2030
|
+
}
|
|
2031
|
+
/**
|
|
2000
2032
|
* Produces an assignment expression. `id` generates a reference
|
|
2001
2033
|
* parameter (through `getRefParam`) and has the option to
|
|
2002
2034
|
* return the reference parameter directly or assign a value to
|
|
@@ -2206,7 +2238,8 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2206
2238
|
createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i));
|
|
2207
2239
|
return "";
|
|
2208
2240
|
}
|
|
2209
|
-
if (val.t !== 4 && val.i != null &&
|
|
2241
|
+
if (val.t !== 4 && val.i != null && hasMarkedNode(base, val)) {
|
|
2242
|
+
markSerializerRef(base, val.i);
|
|
2210
2243
|
const serialized = "(" + serialize$1(ctx, val) + ",[" + sentinel + "," + sentinel + "])";
|
|
2211
2244
|
createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i));
|
|
2212
2245
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2221,7 +2254,8 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2221
2254
|
if (isIndexedValueInStack(base, val)) {
|
|
2222
2255
|
const valueRef = getRefParam(ctx, val.i);
|
|
2223
2256
|
markSerializerRef(base, id);
|
|
2224
|
-
if (key.t !== 4 && key.i != null &&
|
|
2257
|
+
if (key.t !== 4 && key.i != null && hasMarkedNode(base, key)) {
|
|
2258
|
+
markSerializerRef(base, key.i);
|
|
2225
2259
|
const serialized = "(" + serialize$1(ctx, key) + ",[" + sentinel + "," + sentinel + "])";
|
|
2226
2260
|
createSetAssignment(ctx, id, getRefParam(ctx, key.i), valueRef);
|
|
2227
2261
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2617,13 +2651,14 @@ function parseAggregateError(ctx, depth, id, current) {
|
|
|
2617
2651
|
return createAggregateErrorNode(id, current, options ? parseProperties(ctx, depth, options) : void 0);
|
|
2618
2652
|
}
|
|
2619
2653
|
function parseMap(ctx, depth, id, current) {
|
|
2654
|
+
const sentinel = parseMapSentinel(ctx.base);
|
|
2620
2655
|
const keyNodes = [];
|
|
2621
2656
|
const valueNodes = [];
|
|
2622
2657
|
for (const [key, value] of current.entries()) {
|
|
2623
2658
|
keyNodes.push(parseSOS(ctx, depth, key));
|
|
2624
2659
|
valueNodes.push(parseSOS(ctx, depth, value));
|
|
2625
2660
|
}
|
|
2626
|
-
return createMapNode(
|
|
2661
|
+
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
2627
2662
|
}
|
|
2628
2663
|
function parseSet(ctx, depth, id, current) {
|
|
2629
2664
|
const items = [];
|
package/dist/dev/index.js
CHANGED
|
@@ -1002,11 +1002,18 @@ function parseAsyncIteratorFactory(ctx) {
|
|
|
1002
1002
|
function createObjectNode(id, current, empty, record) {
|
|
1003
1003
|
return createSerovalNode(empty ? 11 : 10, id, void 0, void 0, void 0, record, void 0, void 0, void 0, void 0, getObjectFlag(current), void 0);
|
|
1004
1004
|
}
|
|
1005
|
-
|
|
1005
|
+
/**
|
|
1006
|
+
* Gets the sentinel node for a Map. Call it before parsing the entries, so
|
|
1007
|
+
* that an outer Map declares the sentinel before any Map inside it uses it.
|
|
1008
|
+
*/
|
|
1009
|
+
function parseMapSentinel(ctx) {
|
|
1010
|
+
return parseSpecialReference(ctx, 0);
|
|
1011
|
+
}
|
|
1012
|
+
function createMapNode(id, sentinel, k, v) {
|
|
1006
1013
|
return createSerovalNode(8, id, void 0, void 0, void 0, void 0, {
|
|
1007
1014
|
k,
|
|
1008
1015
|
v
|
|
1009
|
-
}, void 0,
|
|
1016
|
+
}, void 0, sentinel, void 0, void 0, void 0);
|
|
1010
1017
|
}
|
|
1011
1018
|
function createPromiseConstructorNode(ctx, id, resolver) {
|
|
1012
1019
|
return createSerovalNode(22, id, resolver, void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 1), void 0, void 0, void 0);
|
|
@@ -1109,13 +1116,14 @@ async function parseAggregateError$1(ctx, depth, id, current) {
|
|
|
1109
1116
|
return createAggregateErrorNode(id, current, options ? await parseProperties$1(ctx, depth, options) : void 0);
|
|
1110
1117
|
}
|
|
1111
1118
|
async function parseMap$1(ctx, depth, id, current) {
|
|
1119
|
+
const sentinel = parseMapSentinel(ctx.base);
|
|
1112
1120
|
const keyNodes = [];
|
|
1113
1121
|
const valueNodes = [];
|
|
1114
1122
|
for (const [key, value] of current.entries()) {
|
|
1115
1123
|
keyNodes.push(await parseAsync(ctx, depth, key));
|
|
1116
1124
|
valueNodes.push(await parseAsync(ctx, depth, value));
|
|
1117
1125
|
}
|
|
1118
|
-
return createMapNode(
|
|
1126
|
+
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
1119
1127
|
}
|
|
1120
1128
|
async function parseSet$1(ctx, depth, id, current) {
|
|
1121
1129
|
const items = [];
|
|
@@ -1769,30 +1777,36 @@ function getAssignmentExpression(assignment) {
|
|
|
1769
1777
|
case 4: return "Object.defineProperty(" + assignment.s + ",\"__proto__\",{value:" + assignment.k + ",configurable:!0,enumerable:!0,writable:!0})";
|
|
1770
1778
|
}
|
|
1771
1779
|
}
|
|
1780
|
+
const MAX_ASSIGNMENT_CHAIN_LENGTH = 100;
|
|
1772
1781
|
function mergeAssignments(assignments) {
|
|
1773
1782
|
const newAssignments = [];
|
|
1774
1783
|
let current = assignments[0];
|
|
1784
|
+
let chainLength = 1;
|
|
1775
1785
|
for (let i = 1, len = assignments.length, item, prev = current; i < len; i++) {
|
|
1776
1786
|
item = assignments[i];
|
|
1777
|
-
if (
|
|
1787
|
+
if (chainLength === MAX_ASSIGNMENT_CHAIN_LENGTH) {
|
|
1788
|
+
newAssignments.push(current);
|
|
1789
|
+
current = item;
|
|
1790
|
+
chainLength = 0;
|
|
1791
|
+
} else if (item.t === 0 && prev.t === 0 && item.v === prev.v) current = {
|
|
1778
1792
|
t: 0,
|
|
1779
1793
|
s: item.s,
|
|
1780
1794
|
k: void 0,
|
|
1781
1795
|
v: getAssignmentExpression(current)
|
|
1782
1796
|
};
|
|
1783
|
-
else if (item.t === 2 && item.s === prev.s) current = {
|
|
1797
|
+
else if (item.t === 2 && prev.t === 2 && item.s === prev.s) current = {
|
|
1784
1798
|
t: 2,
|
|
1785
1799
|
s: getAssignmentExpression(current),
|
|
1786
1800
|
k: item.k,
|
|
1787
1801
|
v: item.v
|
|
1788
1802
|
};
|
|
1789
|
-
else if (item.t === 1 && item.s === prev.s) current = {
|
|
1803
|
+
else if (item.t === 1 && prev.t === 1 && item.s === prev.s) current = {
|
|
1790
1804
|
t: 1,
|
|
1791
1805
|
s: getAssignmentExpression(current),
|
|
1792
1806
|
k: void 0,
|
|
1793
1807
|
v: item.v
|
|
1794
1808
|
};
|
|
1795
|
-
else if (item.t === 3 && item.s === prev.s) current = {
|
|
1809
|
+
else if (item.t === 3 && prev.t === 2 && item.s === prev.s) current = {
|
|
1796
1810
|
t: 3,
|
|
1797
1811
|
s: getAssignmentExpression(current),
|
|
1798
1812
|
k: item.k,
|
|
@@ -1801,7 +1815,9 @@ function mergeAssignments(assignments) {
|
|
|
1801
1815
|
else {
|
|
1802
1816
|
newAssignments.push(current);
|
|
1803
1817
|
current = item;
|
|
1818
|
+
chainLength = 0;
|
|
1804
1819
|
}
|
|
1820
|
+
chainLength++;
|
|
1805
1821
|
prev = item;
|
|
1806
1822
|
}
|
|
1807
1823
|
newAssignments.push(current);
|
|
@@ -1996,6 +2012,22 @@ function isIndexedValueInStack(ctx, node) {
|
|
|
1996
2012
|
return node.t === 4 && ctx.stack.includes(node.i);
|
|
1997
2013
|
}
|
|
1998
2014
|
/**
|
|
2015
|
+
* Checks if the node, or any node inside it, is read from more than one
|
|
2016
|
+
* place. Such a node must not be created inside a deferred assignment,
|
|
2017
|
+
* because the places that read it may run before the assignment does.
|
|
2018
|
+
*/
|
|
2019
|
+
function hasMarkedNode(ctx, node) {
|
|
2020
|
+
if (Array.isArray(node)) {
|
|
2021
|
+
for (let i = 0, len = node.length; i < len; i++) if (hasMarkedNode(ctx, node[i])) return true;
|
|
2022
|
+
return false;
|
|
2023
|
+
}
|
|
2024
|
+
if (node == null || typeof node !== "object") return false;
|
|
2025
|
+
const current = node;
|
|
2026
|
+
if (current.t !== 4 && typeof current.i === "number" && isSerializerRefMarked(ctx, current.i)) return true;
|
|
2027
|
+
for (const key in current) if (hasMarkedNode(ctx, current[key])) return true;
|
|
2028
|
+
return false;
|
|
2029
|
+
}
|
|
2030
|
+
/**
|
|
1999
2031
|
* Produces an assignment expression. `id` generates a reference
|
|
2000
2032
|
* parameter (through `getRefParam`) and has the option to
|
|
2001
2033
|
* return the reference parameter directly or assign a value to
|
|
@@ -2205,7 +2237,8 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2205
2237
|
createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i));
|
|
2206
2238
|
return "";
|
|
2207
2239
|
}
|
|
2208
|
-
if (val.t !== 4 && val.i != null &&
|
|
2240
|
+
if (val.t !== 4 && val.i != null && hasMarkedNode(base, val)) {
|
|
2241
|
+
markSerializerRef(base, val.i);
|
|
2209
2242
|
const serialized = "(" + serialize$1(ctx, val) + ",[" + sentinel + "," + sentinel + "])";
|
|
2210
2243
|
createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i));
|
|
2211
2244
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2220,7 +2253,8 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2220
2253
|
if (isIndexedValueInStack(base, val)) {
|
|
2221
2254
|
const valueRef = getRefParam(ctx, val.i);
|
|
2222
2255
|
markSerializerRef(base, id);
|
|
2223
|
-
if (key.t !== 4 && key.i != null &&
|
|
2256
|
+
if (key.t !== 4 && key.i != null && hasMarkedNode(base, key)) {
|
|
2257
|
+
markSerializerRef(base, key.i);
|
|
2224
2258
|
const serialized = "(" + serialize$1(ctx, key) + ",[" + sentinel + "," + sentinel + "])";
|
|
2225
2259
|
createSetAssignment(ctx, id, getRefParam(ctx, key.i), valueRef);
|
|
2226
2260
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2616,13 +2650,14 @@ function parseAggregateError(ctx, depth, id, current) {
|
|
|
2616
2650
|
return createAggregateErrorNode(id, current, options ? parseProperties(ctx, depth, options) : void 0);
|
|
2617
2651
|
}
|
|
2618
2652
|
function parseMap(ctx, depth, id, current) {
|
|
2653
|
+
const sentinel = parseMapSentinel(ctx.base);
|
|
2619
2654
|
const keyNodes = [];
|
|
2620
2655
|
const valueNodes = [];
|
|
2621
2656
|
for (const [key, value] of current.entries()) {
|
|
2622
2657
|
keyNodes.push(parseSOS(ctx, depth, key));
|
|
2623
2658
|
valueNodes.push(parseSOS(ctx, depth, value));
|
|
2624
2659
|
}
|
|
2625
|
-
return createMapNode(
|
|
2660
|
+
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
2626
2661
|
}
|
|
2627
2662
|
function parseSet(ctx, depth, id, current) {
|
|
2628
2663
|
const items = [];
|
package/dist/index.cjs
CHANGED
|
@@ -996,11 +996,18 @@ function parseAsyncIteratorFactory(ctx) {
|
|
|
996
996
|
function createObjectNode(id, current, empty, record) {
|
|
997
997
|
return createSerovalNode(empty ? 11 : 10, id, void 0, void 0, void 0, record, void 0, void 0, void 0, void 0, getObjectFlag(current), void 0);
|
|
998
998
|
}
|
|
999
|
-
|
|
999
|
+
/**
|
|
1000
|
+
* Gets the sentinel node for a Map. Call it before parsing the entries, so
|
|
1001
|
+
* that an outer Map declares the sentinel before any Map inside it uses it.
|
|
1002
|
+
*/
|
|
1003
|
+
function parseMapSentinel(ctx) {
|
|
1004
|
+
return parseSpecialReference(ctx, 0);
|
|
1005
|
+
}
|
|
1006
|
+
function createMapNode(id, sentinel, k, v) {
|
|
1000
1007
|
return createSerovalNode(8, id, void 0, void 0, void 0, void 0, {
|
|
1001
1008
|
k,
|
|
1002
1009
|
v
|
|
1003
|
-
}, void 0,
|
|
1010
|
+
}, void 0, sentinel, void 0, void 0, void 0);
|
|
1004
1011
|
}
|
|
1005
1012
|
function createPromiseConstructorNode(ctx, id, resolver) {
|
|
1006
1013
|
return createSerovalNode(22, id, resolver, void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 1), void 0, void 0, void 0);
|
|
@@ -1103,13 +1110,14 @@ async function parseAggregateError$1(ctx, depth, id, current) {
|
|
|
1103
1110
|
return createAggregateErrorNode(id, current, options ? await parseProperties$1(ctx, depth, options) : void 0);
|
|
1104
1111
|
}
|
|
1105
1112
|
async function parseMap$1(ctx, depth, id, current) {
|
|
1113
|
+
const sentinel = parseMapSentinel(ctx.base);
|
|
1106
1114
|
const keyNodes = [];
|
|
1107
1115
|
const valueNodes = [];
|
|
1108
1116
|
for (const [key, value] of current.entries()) {
|
|
1109
1117
|
keyNodes.push(await parseAsync(ctx, depth, key));
|
|
1110
1118
|
valueNodes.push(await parseAsync(ctx, depth, value));
|
|
1111
1119
|
}
|
|
1112
|
-
return createMapNode(
|
|
1120
|
+
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
1113
1121
|
}
|
|
1114
1122
|
async function parseSet$1(ctx, depth, id, current) {
|
|
1115
1123
|
const items = [];
|
|
@@ -1763,30 +1771,36 @@ function getAssignmentExpression(assignment) {
|
|
|
1763
1771
|
case 4: return "Object.defineProperty(" + assignment.s + ",\"__proto__\",{value:" + assignment.k + ",configurable:!0,enumerable:!0,writable:!0})";
|
|
1764
1772
|
}
|
|
1765
1773
|
}
|
|
1774
|
+
const MAX_ASSIGNMENT_CHAIN_LENGTH = 100;
|
|
1766
1775
|
function mergeAssignments(assignments) {
|
|
1767
1776
|
const newAssignments = [];
|
|
1768
1777
|
let current = assignments[0];
|
|
1778
|
+
let chainLength = 1;
|
|
1769
1779
|
for (let i = 1, len = assignments.length, item, prev = current; i < len; i++) {
|
|
1770
1780
|
item = assignments[i];
|
|
1771
|
-
if (
|
|
1781
|
+
if (chainLength === MAX_ASSIGNMENT_CHAIN_LENGTH) {
|
|
1782
|
+
newAssignments.push(current);
|
|
1783
|
+
current = item;
|
|
1784
|
+
chainLength = 0;
|
|
1785
|
+
} else if (item.t === 0 && prev.t === 0 && item.v === prev.v) current = {
|
|
1772
1786
|
t: 0,
|
|
1773
1787
|
s: item.s,
|
|
1774
1788
|
k: void 0,
|
|
1775
1789
|
v: getAssignmentExpression(current)
|
|
1776
1790
|
};
|
|
1777
|
-
else if (item.t === 2 && item.s === prev.s) current = {
|
|
1791
|
+
else if (item.t === 2 && prev.t === 2 && item.s === prev.s) current = {
|
|
1778
1792
|
t: 2,
|
|
1779
1793
|
s: getAssignmentExpression(current),
|
|
1780
1794
|
k: item.k,
|
|
1781
1795
|
v: item.v
|
|
1782
1796
|
};
|
|
1783
|
-
else if (item.t === 1 && item.s === prev.s) current = {
|
|
1797
|
+
else if (item.t === 1 && prev.t === 1 && item.s === prev.s) current = {
|
|
1784
1798
|
t: 1,
|
|
1785
1799
|
s: getAssignmentExpression(current),
|
|
1786
1800
|
k: void 0,
|
|
1787
1801
|
v: item.v
|
|
1788
1802
|
};
|
|
1789
|
-
else if (item.t === 3 && item.s === prev.s) current = {
|
|
1803
|
+
else if (item.t === 3 && prev.t === 2 && item.s === prev.s) current = {
|
|
1790
1804
|
t: 3,
|
|
1791
1805
|
s: getAssignmentExpression(current),
|
|
1792
1806
|
k: item.k,
|
|
@@ -1795,7 +1809,9 @@ function mergeAssignments(assignments) {
|
|
|
1795
1809
|
else {
|
|
1796
1810
|
newAssignments.push(current);
|
|
1797
1811
|
current = item;
|
|
1812
|
+
chainLength = 0;
|
|
1798
1813
|
}
|
|
1814
|
+
chainLength++;
|
|
1799
1815
|
prev = item;
|
|
1800
1816
|
}
|
|
1801
1817
|
newAssignments.push(current);
|
|
@@ -1990,6 +2006,22 @@ function isIndexedValueInStack(ctx, node) {
|
|
|
1990
2006
|
return node.t === 4 && ctx.stack.includes(node.i);
|
|
1991
2007
|
}
|
|
1992
2008
|
/**
|
|
2009
|
+
* Checks if the node, or any node inside it, is read from more than one
|
|
2010
|
+
* place. Such a node must not be created inside a deferred assignment,
|
|
2011
|
+
* because the places that read it may run before the assignment does.
|
|
2012
|
+
*/
|
|
2013
|
+
function hasMarkedNode(ctx, node) {
|
|
2014
|
+
if (Array.isArray(node)) {
|
|
2015
|
+
for (let i = 0, len = node.length; i < len; i++) if (hasMarkedNode(ctx, node[i])) return true;
|
|
2016
|
+
return false;
|
|
2017
|
+
}
|
|
2018
|
+
if (node == null || typeof node !== "object") return false;
|
|
2019
|
+
const current = node;
|
|
2020
|
+
if (current.t !== 4 && typeof current.i === "number" && isSerializerRefMarked(ctx, current.i)) return true;
|
|
2021
|
+
for (const key in current) if (hasMarkedNode(ctx, current[key])) return true;
|
|
2022
|
+
return false;
|
|
2023
|
+
}
|
|
2024
|
+
/**
|
|
1993
2025
|
* Produces an assignment expression. `id` generates a reference
|
|
1994
2026
|
* parameter (through `getRefParam`) and has the option to
|
|
1995
2027
|
* return the reference parameter directly or assign a value to
|
|
@@ -2199,7 +2231,8 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2199
2231
|
createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i));
|
|
2200
2232
|
return "";
|
|
2201
2233
|
}
|
|
2202
|
-
if (val.t !== 4 && val.i != null &&
|
|
2234
|
+
if (val.t !== 4 && val.i != null && hasMarkedNode(base, val)) {
|
|
2235
|
+
markSerializerRef(base, val.i);
|
|
2203
2236
|
const serialized = "(" + serialize$1(ctx, val) + ",[" + sentinel + "," + sentinel + "])";
|
|
2204
2237
|
createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i));
|
|
2205
2238
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2214,7 +2247,8 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2214
2247
|
if (isIndexedValueInStack(base, val)) {
|
|
2215
2248
|
const valueRef = getRefParam(ctx, val.i);
|
|
2216
2249
|
markSerializerRef(base, id);
|
|
2217
|
-
if (key.t !== 4 && key.i != null &&
|
|
2250
|
+
if (key.t !== 4 && key.i != null && hasMarkedNode(base, key)) {
|
|
2251
|
+
markSerializerRef(base, key.i);
|
|
2218
2252
|
const serialized = "(" + serialize$1(ctx, key) + ",[" + sentinel + "," + sentinel + "])";
|
|
2219
2253
|
createSetAssignment(ctx, id, getRefParam(ctx, key.i), valueRef);
|
|
2220
2254
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2610,13 +2644,14 @@ function parseAggregateError(ctx, depth, id, current) {
|
|
|
2610
2644
|
return createAggregateErrorNode(id, current, options ? parseProperties(ctx, depth, options) : void 0);
|
|
2611
2645
|
}
|
|
2612
2646
|
function parseMap(ctx, depth, id, current) {
|
|
2647
|
+
const sentinel = parseMapSentinel(ctx.base);
|
|
2613
2648
|
const keyNodes = [];
|
|
2614
2649
|
const valueNodes = [];
|
|
2615
2650
|
for (const [key, value] of current.entries()) {
|
|
2616
2651
|
keyNodes.push(parseSOS(ctx, depth, key));
|
|
2617
2652
|
valueNodes.push(parseSOS(ctx, depth, value));
|
|
2618
2653
|
}
|
|
2619
|
-
return createMapNode(
|
|
2654
|
+
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
2620
2655
|
}
|
|
2621
2656
|
function parseSet(ctx, depth, id, current) {
|
|
2622
2657
|
const items = [];
|
package/dist/index.js
CHANGED
|
@@ -995,11 +995,18 @@ function parseAsyncIteratorFactory(ctx) {
|
|
|
995
995
|
function createObjectNode(id, current, empty, record) {
|
|
996
996
|
return createSerovalNode(empty ? 11 : 10, id, void 0, void 0, void 0, record, void 0, void 0, void 0, void 0, getObjectFlag(current), void 0);
|
|
997
997
|
}
|
|
998
|
-
|
|
998
|
+
/**
|
|
999
|
+
* Gets the sentinel node for a Map. Call it before parsing the entries, so
|
|
1000
|
+
* that an outer Map declares the sentinel before any Map inside it uses it.
|
|
1001
|
+
*/
|
|
1002
|
+
function parseMapSentinel(ctx) {
|
|
1003
|
+
return parseSpecialReference(ctx, 0);
|
|
1004
|
+
}
|
|
1005
|
+
function createMapNode(id, sentinel, k, v) {
|
|
999
1006
|
return createSerovalNode(8, id, void 0, void 0, void 0, void 0, {
|
|
1000
1007
|
k,
|
|
1001
1008
|
v
|
|
1002
|
-
}, void 0,
|
|
1009
|
+
}, void 0, sentinel, void 0, void 0, void 0);
|
|
1003
1010
|
}
|
|
1004
1011
|
function createPromiseConstructorNode(ctx, id, resolver) {
|
|
1005
1012
|
return createSerovalNode(22, id, resolver, void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 1), void 0, void 0, void 0);
|
|
@@ -1102,13 +1109,14 @@ async function parseAggregateError$1(ctx, depth, id, current) {
|
|
|
1102
1109
|
return createAggregateErrorNode(id, current, options ? await parseProperties$1(ctx, depth, options) : void 0);
|
|
1103
1110
|
}
|
|
1104
1111
|
async function parseMap$1(ctx, depth, id, current) {
|
|
1112
|
+
const sentinel = parseMapSentinel(ctx.base);
|
|
1105
1113
|
const keyNodes = [];
|
|
1106
1114
|
const valueNodes = [];
|
|
1107
1115
|
for (const [key, value] of current.entries()) {
|
|
1108
1116
|
keyNodes.push(await parseAsync(ctx, depth, key));
|
|
1109
1117
|
valueNodes.push(await parseAsync(ctx, depth, value));
|
|
1110
1118
|
}
|
|
1111
|
-
return createMapNode(
|
|
1119
|
+
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
1112
1120
|
}
|
|
1113
1121
|
async function parseSet$1(ctx, depth, id, current) {
|
|
1114
1122
|
const items = [];
|
|
@@ -1762,30 +1770,36 @@ function getAssignmentExpression(assignment) {
|
|
|
1762
1770
|
case 4: return "Object.defineProperty(" + assignment.s + ",\"__proto__\",{value:" + assignment.k + ",configurable:!0,enumerable:!0,writable:!0})";
|
|
1763
1771
|
}
|
|
1764
1772
|
}
|
|
1773
|
+
const MAX_ASSIGNMENT_CHAIN_LENGTH = 100;
|
|
1765
1774
|
function mergeAssignments(assignments) {
|
|
1766
1775
|
const newAssignments = [];
|
|
1767
1776
|
let current = assignments[0];
|
|
1777
|
+
let chainLength = 1;
|
|
1768
1778
|
for (let i = 1, len = assignments.length, item, prev = current; i < len; i++) {
|
|
1769
1779
|
item = assignments[i];
|
|
1770
|
-
if (
|
|
1780
|
+
if (chainLength === MAX_ASSIGNMENT_CHAIN_LENGTH) {
|
|
1781
|
+
newAssignments.push(current);
|
|
1782
|
+
current = item;
|
|
1783
|
+
chainLength = 0;
|
|
1784
|
+
} else if (item.t === 0 && prev.t === 0 && item.v === prev.v) current = {
|
|
1771
1785
|
t: 0,
|
|
1772
1786
|
s: item.s,
|
|
1773
1787
|
k: void 0,
|
|
1774
1788
|
v: getAssignmentExpression(current)
|
|
1775
1789
|
};
|
|
1776
|
-
else if (item.t === 2 && item.s === prev.s) current = {
|
|
1790
|
+
else if (item.t === 2 && prev.t === 2 && item.s === prev.s) current = {
|
|
1777
1791
|
t: 2,
|
|
1778
1792
|
s: getAssignmentExpression(current),
|
|
1779
1793
|
k: item.k,
|
|
1780
1794
|
v: item.v
|
|
1781
1795
|
};
|
|
1782
|
-
else if (item.t === 1 && item.s === prev.s) current = {
|
|
1796
|
+
else if (item.t === 1 && prev.t === 1 && item.s === prev.s) current = {
|
|
1783
1797
|
t: 1,
|
|
1784
1798
|
s: getAssignmentExpression(current),
|
|
1785
1799
|
k: void 0,
|
|
1786
1800
|
v: item.v
|
|
1787
1801
|
};
|
|
1788
|
-
else if (item.t === 3 && item.s === prev.s) current = {
|
|
1802
|
+
else if (item.t === 3 && prev.t === 2 && item.s === prev.s) current = {
|
|
1789
1803
|
t: 3,
|
|
1790
1804
|
s: getAssignmentExpression(current),
|
|
1791
1805
|
k: item.k,
|
|
@@ -1794,7 +1808,9 @@ function mergeAssignments(assignments) {
|
|
|
1794
1808
|
else {
|
|
1795
1809
|
newAssignments.push(current);
|
|
1796
1810
|
current = item;
|
|
1811
|
+
chainLength = 0;
|
|
1797
1812
|
}
|
|
1813
|
+
chainLength++;
|
|
1798
1814
|
prev = item;
|
|
1799
1815
|
}
|
|
1800
1816
|
newAssignments.push(current);
|
|
@@ -1989,6 +2005,22 @@ function isIndexedValueInStack(ctx, node) {
|
|
|
1989
2005
|
return node.t === 4 && ctx.stack.includes(node.i);
|
|
1990
2006
|
}
|
|
1991
2007
|
/**
|
|
2008
|
+
* Checks if the node, or any node inside it, is read from more than one
|
|
2009
|
+
* place. Such a node must not be created inside a deferred assignment,
|
|
2010
|
+
* because the places that read it may run before the assignment does.
|
|
2011
|
+
*/
|
|
2012
|
+
function hasMarkedNode(ctx, node) {
|
|
2013
|
+
if (Array.isArray(node)) {
|
|
2014
|
+
for (let i = 0, len = node.length; i < len; i++) if (hasMarkedNode(ctx, node[i])) return true;
|
|
2015
|
+
return false;
|
|
2016
|
+
}
|
|
2017
|
+
if (node == null || typeof node !== "object") return false;
|
|
2018
|
+
const current = node;
|
|
2019
|
+
if (current.t !== 4 && typeof current.i === "number" && isSerializerRefMarked(ctx, current.i)) return true;
|
|
2020
|
+
for (const key in current) if (hasMarkedNode(ctx, current[key])) return true;
|
|
2021
|
+
return false;
|
|
2022
|
+
}
|
|
2023
|
+
/**
|
|
1992
2024
|
* Produces an assignment expression. `id` generates a reference
|
|
1993
2025
|
* parameter (through `getRefParam`) and has the option to
|
|
1994
2026
|
* return the reference parameter directly or assign a value to
|
|
@@ -2198,7 +2230,8 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2198
2230
|
createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i));
|
|
2199
2231
|
return "";
|
|
2200
2232
|
}
|
|
2201
|
-
if (val.t !== 4 && val.i != null &&
|
|
2233
|
+
if (val.t !== 4 && val.i != null && hasMarkedNode(base, val)) {
|
|
2234
|
+
markSerializerRef(base, val.i);
|
|
2202
2235
|
const serialized = "(" + serialize$1(ctx, val) + ",[" + sentinel + "," + sentinel + "])";
|
|
2203
2236
|
createSetAssignment(ctx, id, keyRef, getRefParam(ctx, val.i));
|
|
2204
2237
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2213,7 +2246,8 @@ function serializeMapEntry(ctx, id, key, val, sentinel) {
|
|
|
2213
2246
|
if (isIndexedValueInStack(base, val)) {
|
|
2214
2247
|
const valueRef = getRefParam(ctx, val.i);
|
|
2215
2248
|
markSerializerRef(base, id);
|
|
2216
|
-
if (key.t !== 4 && key.i != null &&
|
|
2249
|
+
if (key.t !== 4 && key.i != null && hasMarkedNode(base, key)) {
|
|
2250
|
+
markSerializerRef(base, key.i);
|
|
2217
2251
|
const serialized = "(" + serialize$1(ctx, key) + ",[" + sentinel + "," + sentinel + "])";
|
|
2218
2252
|
createSetAssignment(ctx, id, getRefParam(ctx, key.i), valueRef);
|
|
2219
2253
|
createDeleteAssignment(ctx, id, sentinel);
|
|
@@ -2609,13 +2643,14 @@ function parseAggregateError(ctx, depth, id, current) {
|
|
|
2609
2643
|
return createAggregateErrorNode(id, current, options ? parseProperties(ctx, depth, options) : void 0);
|
|
2610
2644
|
}
|
|
2611
2645
|
function parseMap(ctx, depth, id, current) {
|
|
2646
|
+
const sentinel = parseMapSentinel(ctx.base);
|
|
2612
2647
|
const keyNodes = [];
|
|
2613
2648
|
const valueNodes = [];
|
|
2614
2649
|
for (const [key, value] of current.entries()) {
|
|
2615
2650
|
keyNodes.push(parseSOS(ctx, depth, key));
|
|
2616
2651
|
valueNodes.push(parseSOS(ctx, depth, value));
|
|
2617
2652
|
}
|
|
2618
|
-
return createMapNode(
|
|
2653
|
+
return createMapNode(id, sentinel, keyNodes, valueNodes);
|
|
2619
2654
|
}
|
|
2620
2655
|
function parseSet(ctx, depth, id, current) {
|
|
2621
2656
|
const items = [];
|