msgpackr 1.7.0-beta1 → 1.7.0
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/index.js +13 -4
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +54 -54
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +66 -30
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +77 -30
- package/dist/test.js.map +1 -1
- package/index.d.ts +62 -14
- package/pack.d.ts +1 -9
- package/pack.js +0 -1
- package/package.json +8 -3
- package/struct.js +53 -26
- package/unpack.d.ts +2 -53
- package/unpack.js +13 -5
package/dist/test.js
CHANGED
|
@@ -179,6 +179,7 @@
|
|
|
179
179
|
let result;
|
|
180
180
|
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
|
|
181
181
|
result = readStruct(src, position, srcEnd, currentUnpackr);
|
|
182
|
+
src = null; // dispose of this so that recursive unpack calls don't save state
|
|
182
183
|
if (!(options && options.lazy) && result)
|
|
183
184
|
result = result.toJSON();
|
|
184
185
|
position = srcEnd;
|
|
@@ -189,7 +190,7 @@
|
|
|
189
190
|
|
|
190
191
|
if (position == srcEnd) {
|
|
191
192
|
// finished reading this source, cleanup references
|
|
192
|
-
if (currentStructures
|
|
193
|
+
if (currentStructures?.restoreStructures)
|
|
193
194
|
restoreStructures();
|
|
194
195
|
currentStructures = null;
|
|
195
196
|
src = null;
|
|
@@ -244,7 +245,10 @@
|
|
|
244
245
|
if (currentUnpackr.mapsAsObjects) {
|
|
245
246
|
let object = {};
|
|
246
247
|
for (let i = 0; i < token; i++) {
|
|
247
|
-
|
|
248
|
+
let key = readKey();
|
|
249
|
+
if (key === '__proto__')
|
|
250
|
+
key = '__proto_';
|
|
251
|
+
object[key] = read();
|
|
248
252
|
}
|
|
249
253
|
return object
|
|
250
254
|
} else {
|
|
@@ -473,7 +477,7 @@
|
|
|
473
477
|
// This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
|
|
474
478
|
if (readObject.count++ > inlineObjectReadThreshold) {
|
|
475
479
|
let readObject = structure.read = (new Function('r', 'return function(){return ' + (currentUnpackr.freezeData ? 'Object.freeze' : '') +
|
|
476
|
-
'({' + structure.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read);
|
|
480
|
+
'({' + structure.map(key => key === '__proto__' ? '__proto_:r()' : validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read);
|
|
477
481
|
if (structure.highByte === 0)
|
|
478
482
|
structure.read = createSecondByteReader(firstId, structure.read);
|
|
479
483
|
return readObject() // second byte is already read, if there is one so immediately read object
|
|
@@ -481,6 +485,8 @@
|
|
|
481
485
|
let object = {};
|
|
482
486
|
for (let i = 0, l = structure.length; i < l; i++) {
|
|
483
487
|
let key = structure[i];
|
|
488
|
+
if (key === '__proto__')
|
|
489
|
+
key = '__proto_';
|
|
484
490
|
object[key] = read();
|
|
485
491
|
}
|
|
486
492
|
if (currentUnpackr.freezeData)
|
|
@@ -601,7 +607,10 @@
|
|
|
601
607
|
if (currentUnpackr.mapsAsObjects) {
|
|
602
608
|
let object = {};
|
|
603
609
|
for (let i = 0; i < length; i++) {
|
|
604
|
-
|
|
610
|
+
let key = readKey();
|
|
611
|
+
if (key === '__proto__')
|
|
612
|
+
key = '__proto_';
|
|
613
|
+
object[key] = read();
|
|
605
614
|
}
|
|
606
615
|
return object
|
|
607
616
|
} else {
|
|
@@ -1997,6 +2006,14 @@
|
|
|
1997
2006
|
const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
|
|
1998
2007
|
TYPE_NAMES[DATE] = 'date';
|
|
1999
2008
|
const float32Headers = [false, true, true, false, false, true, true, false];
|
|
2009
|
+
let evalSupported;
|
|
2010
|
+
try {
|
|
2011
|
+
new Function('');
|
|
2012
|
+
evalSupported = true;
|
|
2013
|
+
} catch(error) {
|
|
2014
|
+
// if eval variants are not supported, do not create inline object readers ever
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2000
2017
|
let updatedPosition;
|
|
2001
2018
|
const hasNodeBuffer$1 = typeof Buffer !== 'undefined';
|
|
2002
2019
|
let textEncoder$1, currentSource;
|
|
@@ -2453,23 +2470,13 @@
|
|
|
2453
2470
|
};
|
|
2454
2471
|
var prototype = construct.prototype;
|
|
2455
2472
|
let properties = [];
|
|
2456
|
-
Object.defineProperty(prototype, 'toJSON', {
|
|
2457
|
-
value() {
|
|
2458
|
-
// return an enumerable object with own properties to JSON stringify
|
|
2459
|
-
let resolved = {};
|
|
2460
|
-
for (let i = 0, l = properties.length; i < l; i++) {
|
|
2461
|
-
let key = properties[i].key;
|
|
2462
|
-
resolved[key] = this[key];
|
|
2463
|
-
}
|
|
2464
|
-
return resolved;
|
|
2465
|
-
},
|
|
2466
|
-
// not enumerable or anything
|
|
2467
|
-
});
|
|
2468
2473
|
let currentOffset = 0;
|
|
2469
2474
|
let lastRefProperty;
|
|
2470
2475
|
for (let i = 0, l = structure.length; i < l; i++) {
|
|
2471
2476
|
let definition = structure[i];
|
|
2472
2477
|
let [ type, size, key, enumerationOffset ] = definition;
|
|
2478
|
+
if (key === '__proto__')
|
|
2479
|
+
key = '__proto_';
|
|
2473
2480
|
let property = {
|
|
2474
2481
|
key,
|
|
2475
2482
|
offset: currentOffset,
|
|
@@ -2513,8 +2520,7 @@
|
|
|
2513
2520
|
lastRefProperty.next = property;
|
|
2514
2521
|
lastRefProperty = property;
|
|
2515
2522
|
property.multiGetCount = 0;
|
|
2516
|
-
get = function() {
|
|
2517
|
-
let source = this[sourceSymbol];
|
|
2523
|
+
get = function(source) {
|
|
2518
2524
|
let src = source.bytes;
|
|
2519
2525
|
let position = source.position;
|
|
2520
2526
|
let refStart = currentOffset + position;
|
|
@@ -2565,8 +2571,7 @@
|
|
|
2565
2571
|
if (lastRefProperty && !lastRefProperty.next)
|
|
2566
2572
|
lastRefProperty.next = property;
|
|
2567
2573
|
lastRefProperty = property;
|
|
2568
|
-
get = function() {
|
|
2569
|
-
let source = this[sourceSymbol];
|
|
2574
|
+
get = function(source) {
|
|
2570
2575
|
let position = source.position;
|
|
2571
2576
|
let refStart = currentOffset + position;
|
|
2572
2577
|
let ref = getRef(source, position);
|
|
@@ -2598,8 +2603,7 @@
|
|
|
2598
2603
|
case NUMBER:
|
|
2599
2604
|
switch(size) {
|
|
2600
2605
|
case 4:
|
|
2601
|
-
get = function () {
|
|
2602
|
-
let source = this[sourceSymbol];
|
|
2606
|
+
get = function (source) {
|
|
2603
2607
|
let src = source.bytes;
|
|
2604
2608
|
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2605
2609
|
let position = source.position + property.offset;
|
|
@@ -2617,8 +2621,7 @@
|
|
|
2617
2621
|
};
|
|
2618
2622
|
break;
|
|
2619
2623
|
case 8:
|
|
2620
|
-
get = function () {
|
|
2621
|
-
let source = this[sourceSymbol];
|
|
2624
|
+
get = function (source) {
|
|
2622
2625
|
let src = source.bytes;
|
|
2623
2626
|
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2624
2627
|
let value = dataView.getFloat64(source.position + property.offset, true);
|
|
@@ -2631,8 +2634,7 @@
|
|
|
2631
2634
|
};
|
|
2632
2635
|
break;
|
|
2633
2636
|
case 1:
|
|
2634
|
-
get = function () {
|
|
2635
|
-
let source = this[sourceSymbol];
|
|
2637
|
+
get = function (source) {
|
|
2636
2638
|
let src = source.bytes;
|
|
2637
2639
|
let value = src[source.position + property.offset];
|
|
2638
2640
|
return value < 0xf6 ? value : toConstant(value);
|
|
@@ -2641,8 +2643,7 @@
|
|
|
2641
2643
|
}
|
|
2642
2644
|
break;
|
|
2643
2645
|
case DATE:
|
|
2644
|
-
get = function () {
|
|
2645
|
-
let source = this[sourceSymbol];
|
|
2646
|
+
get = function (source) {
|
|
2646
2647
|
let src = source.bytes;
|
|
2647
2648
|
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2648
2649
|
return new Date(dataView.getFloat64(source.position + property.offset, true));
|
|
@@ -2652,8 +2653,38 @@
|
|
|
2652
2653
|
}
|
|
2653
2654
|
property.get = get;
|
|
2654
2655
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2656
|
+
// TODO: load the srcString for faster string decoding on toJSON
|
|
2657
|
+
if (evalSupported) {
|
|
2658
|
+
let objectLiteralProperties = [];
|
|
2659
|
+
let args = [];
|
|
2660
|
+
let i = 0;
|
|
2661
|
+
for (let property of properties) { // assign in enumeration order
|
|
2662
|
+
Object.defineProperty(prototype, property.key, { get: withSource(property.get), enumerable: true });
|
|
2663
|
+
let valueFunction = 'v' + i++;
|
|
2664
|
+
args.push(valueFunction);
|
|
2665
|
+
objectLiteralProperties.push('[' + JSON.stringify(property.key) + ']:' + valueFunction + '(s)');
|
|
2666
|
+
}
|
|
2667
|
+
let toObject = (new Function(...args, 'return function(s){return{' + objectLiteralProperties.join(',') + '}}')).apply(null, properties.map(prop => prop.get));
|
|
2668
|
+
Object.defineProperty(prototype, 'toJSON', {
|
|
2669
|
+
value() {
|
|
2670
|
+
return toObject(this[sourceSymbol]);
|
|
2671
|
+
}
|
|
2672
|
+
});
|
|
2673
|
+
} else {
|
|
2674
|
+
Object.defineProperty(prototype, 'toJSON', {
|
|
2675
|
+
value() {
|
|
2676
|
+
// return an enumerable object with own properties to JSON stringify
|
|
2677
|
+
let resolved = {};
|
|
2678
|
+
for (let i = 0, l = properties.length; i < l; i++) {
|
|
2679
|
+
let key = properties[i].key;
|
|
2680
|
+
|
|
2681
|
+
resolved[key] = this[key];
|
|
2682
|
+
}
|
|
2683
|
+
return resolved;
|
|
2684
|
+
},
|
|
2685
|
+
// not enumerable or anything
|
|
2686
|
+
});
|
|
2687
|
+
}
|
|
2657
2688
|
}
|
|
2658
2689
|
var instance = new construct();
|
|
2659
2690
|
instance[sourceSymbol] = {
|
|
@@ -2673,6 +2704,11 @@
|
|
|
2673
2704
|
}
|
|
2674
2705
|
throw new Error('Unknown constant');
|
|
2675
2706
|
}
|
|
2707
|
+
function withSource(get) {
|
|
2708
|
+
return function() {
|
|
2709
|
+
return get(this[sourceSymbol]);
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2676
2712
|
|
|
2677
2713
|
function saveState$1() {
|
|
2678
2714
|
if (currentSource) {
|
|
@@ -3045,6 +3081,17 @@
|
|
|
3045
3081
|
assert.deepEqual(data, deserialized);
|
|
3046
3082
|
assert.equal(deserialized.extendedInstance.getDouble(), 8);
|
|
3047
3083
|
});
|
|
3084
|
+
test('proto handling', function() {
|
|
3085
|
+
var objectWithProto = JSON.parse('{"__proto__":{"foo":3}}');
|
|
3086
|
+
var decoded = unpack(pack(objectWithProto));
|
|
3087
|
+
assert(!decoded.foo);
|
|
3088
|
+
var objectsWithProto = [objectWithProto, objectWithProto, objectWithProto, objectWithProto, objectWithProto, objectWithProto];
|
|
3089
|
+
let packr = new Packr$1();
|
|
3090
|
+
var decoded = packr.unpack(packr.pack(objectsWithProto));
|
|
3091
|
+
for (let object of decoded) {
|
|
3092
|
+
assert(!decoded.foo);
|
|
3093
|
+
}
|
|
3094
|
+
});
|
|
3048
3095
|
|
|
3049
3096
|
test.skip('text decoder', function() {
|
|
3050
3097
|
let td = new TextDecoder('ISO-8859-15');
|