msgpackr 1.6.2 → 1.6.3

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/SECURITY.md CHANGED
@@ -1,11 +1,11 @@
1
- # Security Policy
2
-
3
- ## Supported Versions
4
-
5
- | Version | Supported |
6
- | ------- | ------------------ |
7
- | 1.4.x | :white_check_mark: |
8
-
9
- ## Reporting a Vulnerability
10
-
11
- Please report security vulnerabilities to kriszyp@gmail.com.
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ | ------- | ------------------ |
7
+ | 1.4.x | :white_check_mark: |
8
+
9
+ ## Reporting a Vulnerability
10
+
11
+ Please report security vulnerabilities to kriszyp@gmail.com.
package/benchmark.md CHANGED
@@ -1,67 +1,67 @@
1
- Here are more comprehensive benchmarks. This is comparison with the next fastest JS projects using the benchmark tool from `msgpack-lite` (and data is from some clinical research data we use that has a good mix of different value types and structures). It also includes comparison to V8 native JSON functionality, and JavaScript Avro (`avsc`, a very optimized Avro implementation):
2
-
3
- operation | op | ms | op/s
4
- ---------------------------------------------------------- | ------: | ----: | -----:
5
- buf = Buffer(JSON.stringify(obj)); | 82000 | 5004 | 16386
6
- obj = JSON.parse(buf); | 88600 | 5000 | 17720
7
- require("msgpackr").pack(obj); | 161500 | 5002 | 32287
8
- require("msgpackr").unpack(buf); | 94600 | 5004 | 18904
9
- msgpackr w/ shared structures: packr.pack(obj); | 178400 | 5002 | 35665
10
- msgpackr w/ shared structures: packr.unpack(buf); | 376700 | 5000 | 75340
11
- buf = require("msgpack-lite").encode(obj); | 30100 | 5012 | 6005
12
- obj = require("msgpack-lite").decode(buf); | 16200 | 5001 | 3239
13
- buf = require("notepack").encode(obj); | 62600 | 5005 | 12507
14
- obj = require("notepack").decode(buf); | 32400 | 5007 | 6470
15
- require("what-the-pack")... encoder.encode(obj); | 63500 | 5002 | 12694
16
- require("what-the-pack")... encoder.decode(buf); | 32000 | 5001 | 6398
17
- require("avsc")...make schema/type...type.toBuffer(obj); | 84600 | 5003 | 16909
18
- require("avsc")...make schema/type...type.toBuffer(obj); | 99300 | 5001 | 19856
19
-
20
- (`avsc` is schema-based and more comparable in style to msgpackr with shared structures).
21
-
22
- Here is a benchmark of streaming data (again borrowed from `msgpack-lite`'s benchmarking), where msgpackr is able to take advantage of the structured record extension and really pull away from other tools:
23
-
24
- operation (1000000 x 2) | op | ms | op/s
25
- ------------------------------------------------ | ------: | ----: | -----:
26
- new PackrStream().write(obj); | 1000000 | 372 | 2688172
27
- new UnpackrStream().write(buf); | 1000000 | 247 | 4048582
28
- stream.write(msgpack.encode(obj)); | 1000000 | 2898 | 345065
29
- stream.write(msgpack.decode(buf)); | 1000000 | 1969 | 507872
30
- stream.write(notepack.encode(obj)); | 1000000 | 901 | 1109877
31
- stream.write(notepack.decode(buf)); | 1000000 | 1012 | 988142
32
- msgpack.Encoder().on("data",ondata).encode(obj); | 1000000 | 1763 | 567214
33
- msgpack.createDecodeStream().write(buf); | 1000000 | 2222 | 450045
34
- msgpack.createEncodeStream().write(obj); | 1000000 | 1577 | 634115
35
- msgpack.Decoder().on("data",ondata).decode(buf); | 1000000 | 2246 | 445235
36
-
37
-
38
-
39
- These are the benchmarks from notepack package. The larger test data for these benchmarks is very heavily weighted with large binary/buffer data and objects with extreme numbers of keys (much more than I typically see with real-world data, but YMMV):
40
-
41
- node ./benchmarks/encode
42
-
43
- library | tiny | small | medium | large
44
- ---------------- | ----------------: | --------------: | ---------------| -------:
45
- notepack | 2,171,621 ops/sec | 546,905 ops/sec | 29,578 ops/sec | 265 ops/sec
46
- msgpack-js | 967,682 ops/sec | 184,455 ops/sec | 20,556 ops/sec | 259 ops/sec
47
- msgpackr | 2,392,826 ops/sec | 556,915 ops/sec | 70,573 ops/sec | 313 ops/sec
48
- msgpack-lite | 553,143 ops/sec | 132,318 ops/sec | 11,816 ops/sec | 186 ops/sec
49
- @msgpack/msgpack | 2,157,655 ops/sec | 573,236 ops/sec | 25,864 ops/sec | 90.26 ops/sec
50
-
51
-
52
- node ./benchmarks/decode
53
-
54
- library | tiny | small | medium | large
55
- ---------------- | ----------------: | --------------: | --------------- | -------:
56
- notepack | 2,220,904 ops/sec | 560,630 ops/sec | 28,177 ops/sec | 275 ops/sec
57
- msgpack-js | 965,719 ops/sec | 222,047 ops/sec | 21,431 ops/sec | 257 ops/sec
58
- msgpackr | 2,320,046 ops/sec | 589,167 ops/sec | 70,299 ops/sec | 329 ops/sec
59
- msgpackr records | 3,750,547 ops/sec | 912,419 ops/sec | 136,853 ops/sec | 733 ops/sec
60
- msgpack-lite | 569,222 ops/sec | 129,008 ops/sec | 12,424 ops/sec | 180 ops/sec
61
- @msgpack/msgpack | 2,089,697 ops/sec | 557,507 ops/sec | 20,256 ops/sec | 85.03 ops/sec
62
-
63
- This was run by adding the msgpackr to the benchmarks for notepack.
64
-
65
- All benchmarks were performed on Node 14.8.0 (Windows i7-4770 3.4Ghz). They can be run with:
66
- npm install --no-save msgpack msgpack-js @msgpack/msgpack msgpack-lite notepack avsc
67
- node tests/benchmark
1
+ Here are more comprehensive benchmarks. This is comparison with the next fastest JS projects using the benchmark tool from `msgpack-lite` (and data is from some clinical research data we use that has a good mix of different value types and structures). It also includes comparison to V8 native JSON functionality, and JavaScript Avro (`avsc`, a very optimized Avro implementation):
2
+
3
+ operation | op | ms | op/s
4
+ ---------------------------------------------------------- | ------: | ----: | -----:
5
+ buf = Buffer(JSON.stringify(obj)); | 82000 | 5004 | 16386
6
+ obj = JSON.parse(buf); | 88600 | 5000 | 17720
7
+ require("msgpackr").pack(obj); | 161500 | 5002 | 32287
8
+ require("msgpackr").unpack(buf); | 94600 | 5004 | 18904
9
+ msgpackr w/ shared structures: packr.pack(obj); | 178400 | 5002 | 35665
10
+ msgpackr w/ shared structures: packr.unpack(buf); | 376700 | 5000 | 75340
11
+ buf = require("msgpack-lite").encode(obj); | 30100 | 5012 | 6005
12
+ obj = require("msgpack-lite").decode(buf); | 16200 | 5001 | 3239
13
+ buf = require("notepack").encode(obj); | 62600 | 5005 | 12507
14
+ obj = require("notepack").decode(buf); | 32400 | 5007 | 6470
15
+ require("what-the-pack")... encoder.encode(obj); | 63500 | 5002 | 12694
16
+ require("what-the-pack")... encoder.decode(buf); | 32000 | 5001 | 6398
17
+ require("avsc")...make schema/type...type.toBuffer(obj); | 84600 | 5003 | 16909
18
+ require("avsc")...make schema/type...type.toBuffer(obj); | 99300 | 5001 | 19856
19
+
20
+ (`avsc` is schema-based and more comparable in style to msgpackr with shared structures).
21
+
22
+ Here is a benchmark of streaming data (again borrowed from `msgpack-lite`'s benchmarking), where msgpackr is able to take advantage of the structured record extension and really pull away from other tools:
23
+
24
+ operation (1000000 x 2) | op | ms | op/s
25
+ ------------------------------------------------ | ------: | ----: | -----:
26
+ new PackrStream().write(obj); | 1000000 | 372 | 2688172
27
+ new UnpackrStream().write(buf); | 1000000 | 247 | 4048582
28
+ stream.write(msgpack.encode(obj)); | 1000000 | 2898 | 345065
29
+ stream.write(msgpack.decode(buf)); | 1000000 | 1969 | 507872
30
+ stream.write(notepack.encode(obj)); | 1000000 | 901 | 1109877
31
+ stream.write(notepack.decode(buf)); | 1000000 | 1012 | 988142
32
+ msgpack.Encoder().on("data",ondata).encode(obj); | 1000000 | 1763 | 567214
33
+ msgpack.createDecodeStream().write(buf); | 1000000 | 2222 | 450045
34
+ msgpack.createEncodeStream().write(obj); | 1000000 | 1577 | 634115
35
+ msgpack.Decoder().on("data",ondata).decode(buf); | 1000000 | 2246 | 445235
36
+
37
+
38
+
39
+ These are the benchmarks from notepack package. The larger test data for these benchmarks is very heavily weighted with large binary/buffer data and objects with extreme numbers of keys (much more than I typically see with real-world data, but YMMV):
40
+
41
+ node ./benchmarks/encode
42
+
43
+ library | tiny | small | medium | large
44
+ ---------------- | ----------------: | --------------: | ---------------| -------:
45
+ notepack | 2,171,621 ops/sec | 546,905 ops/sec | 29,578 ops/sec | 265 ops/sec
46
+ msgpack-js | 967,682 ops/sec | 184,455 ops/sec | 20,556 ops/sec | 259 ops/sec
47
+ msgpackr | 2,392,826 ops/sec | 556,915 ops/sec | 70,573 ops/sec | 313 ops/sec
48
+ msgpack-lite | 553,143 ops/sec | 132,318 ops/sec | 11,816 ops/sec | 186 ops/sec
49
+ @msgpack/msgpack | 2,157,655 ops/sec | 573,236 ops/sec | 25,864 ops/sec | 90.26 ops/sec
50
+
51
+
52
+ node ./benchmarks/decode
53
+
54
+ library | tiny | small | medium | large
55
+ ---------------- | ----------------: | --------------: | --------------- | -------:
56
+ notepack | 2,220,904 ops/sec | 560,630 ops/sec | 28,177 ops/sec | 275 ops/sec
57
+ msgpack-js | 965,719 ops/sec | 222,047 ops/sec | 21,431 ops/sec | 257 ops/sec
58
+ msgpackr | 2,320,046 ops/sec | 589,167 ops/sec | 70,299 ops/sec | 329 ops/sec
59
+ msgpackr records | 3,750,547 ops/sec | 912,419 ops/sec | 136,853 ops/sec | 733 ops/sec
60
+ msgpack-lite | 569,222 ops/sec | 129,008 ops/sec | 12,424 ops/sec | 180 ops/sec
61
+ @msgpack/msgpack | 2,089,697 ops/sec | 557,507 ops/sec | 20,256 ops/sec | 85.03 ops/sec
62
+
63
+ This was run by adding the msgpackr to the benchmarks for notepack.
64
+
65
+ All benchmarks were performed on Node 14.8.0 (Windows i7-4770 3.4Ghz). They can be run with:
66
+ npm install --no-save msgpack msgpack-js @msgpack/msgpack msgpack-lite notepack avsc
67
+ node tests/benchmark
package/dist/index.js CHANGED
@@ -227,7 +227,10 @@
227
227
  if (currentUnpackr.mapsAsObjects) {
228
228
  let object = {};
229
229
  for (let i = 0; i < token; i++) {
230
- object[readKey()] = read();
230
+ let key = readKey();
231
+ if (key === '__proto__')
232
+ key = '__proto_';
233
+ object[key] = read();
231
234
  }
232
235
  return object
233
236
  } else {
@@ -453,7 +456,8 @@
453
456
  function readObject() {
454
457
  // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
455
458
  if (readObject.count++ > inlineObjectReadThreshold) {
456
- let readObject = structure.read = (new Function('r', 'return function(){return {' + structure.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}}'))(read);
459
+ let readObject = structure.read = (new Function('r', 'return function(){return {' + structure.map(key => key === '__proto__' ? '__proto_:r()' :
460
+ validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}}'))(read);
457
461
  if (structure.highByte === 0)
458
462
  structure.read = createSecondByteReader(firstId, structure.read);
459
463
  return readObject() // second byte is already read, if there is one so immediately read object
@@ -461,6 +465,8 @@
461
465
  let object = {};
462
466
  for (let i = 0, l = structure.length; i < l; i++) {
463
467
  let key = structure[i];
468
+ if (key === '__proto__')
469
+ key = '__proto_';
464
470
  object[key] = read();
465
471
  }
466
472
  return object
@@ -568,7 +574,10 @@
568
574
  if (currentUnpackr.mapsAsObjects) {
569
575
  let object = {};
570
576
  for (let i = 0; i < length; i++) {
571
- object[readKey()] = read();
577
+ let key = readKey();
578
+ if (key === '__proto__')
579
+ key = '__proto_';
580
+ object[key] = read();
572
581
  }
573
582
  return object
574
583
  } else {
@@ -1937,92 +1946,92 @@
1937
1946
  const REUSE_BUFFER_MODE = 512;
1938
1947
  const RESET_BUFFER_MODE = 1024;
1939
1948
 
1940
- /**
1941
- * Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
1942
- * If the argument is only Async Iterable, the return value will be an Async Iterable.
1943
- * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
1944
- * @param {options} [options] - msgpackr pack options
1945
- * @returns {IterableIterator|Promise.<AsyncIterableIterator>}
1946
- */
1947
- function packIter (objectIterator, options = {}) {
1948
- if (!objectIterator || typeof objectIterator !== 'object') {
1949
- throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
1950
- } else if (typeof objectIterator[Symbol.iterator] === 'function') {
1951
- return packIterSync(objectIterator, options)
1952
- } else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
1953
- return packIterAsync(objectIterator, options)
1954
- } else {
1955
- throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
1956
- }
1957
- }
1958
-
1959
- function * packIterSync (objectIterator, options) {
1960
- const packr = new Packr(options);
1961
- for (const value of objectIterator) {
1962
- yield packr.pack(value);
1963
- }
1964
- }
1965
-
1966
- async function * packIterAsync (objectIterator, options) {
1967
- const packr = new Packr(options);
1968
- for await (const value of objectIterator) {
1969
- yield packr.pack(value);
1970
- }
1971
- }
1972
-
1973
- /**
1974
- * Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
1975
- * Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
1976
- * @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
1977
- * @param {object} [options] - unpackr options
1978
- * @returns {IterableIterator|Promise.<AsyncIterableIterator}
1979
- */
1980
- function unpackIter (bufferIterator, options = {}) {
1981
- if (!bufferIterator || typeof bufferIterator !== 'object') {
1982
- throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
1983
- }
1984
-
1985
- const unpackr = new Unpackr(options);
1986
- let incomplete;
1987
- const parser = (chunk) => {
1988
- let yields;
1989
- // if there's incomplete data from previous chunk, concatinate and try again
1990
- if (incomplete) {
1991
- chunk = Buffer.concat([incomplete, chunk]);
1992
- incomplete = undefined;
1993
- }
1994
-
1995
- try {
1996
- yields = unpackr.unpackMultiple(chunk);
1997
- } catch (err) {
1998
- if (err.incomplete) {
1999
- incomplete = chunk.slice(err.lastPosition);
2000
- yields = err.values;
2001
- } else {
2002
- throw err
2003
- }
2004
- }
2005
- return yields
2006
- };
2007
-
2008
- if (typeof bufferIterator[Symbol.iterator] === 'function') {
2009
- return (function * iter () {
2010
- for (const value of bufferIterator) {
2011
- yield * parser(value);
2012
- }
2013
- })()
2014
- } else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
2015
- return (async function * iter () {
2016
- for await (const value of bufferIterator) {
2017
- yield * parser(value);
2018
- }
2019
- })()
2020
- }
2021
- }
2022
- const decodeIter = unpackIter;
1949
+ /**
1950
+ * Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
1951
+ * If the argument is only Async Iterable, the return value will be an Async Iterable.
1952
+ * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
1953
+ * @param {options} [options] - msgpackr pack options
1954
+ * @returns {IterableIterator|Promise.<AsyncIterableIterator>}
1955
+ */
1956
+ function packIter (objectIterator, options = {}) {
1957
+ if (!objectIterator || typeof objectIterator !== 'object') {
1958
+ throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
1959
+ } else if (typeof objectIterator[Symbol.iterator] === 'function') {
1960
+ return packIterSync(objectIterator, options)
1961
+ } else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
1962
+ return packIterAsync(objectIterator, options)
1963
+ } else {
1964
+ throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
1965
+ }
1966
+ }
1967
+
1968
+ function * packIterSync (objectIterator, options) {
1969
+ const packr = new Packr(options);
1970
+ for (const value of objectIterator) {
1971
+ yield packr.pack(value);
1972
+ }
1973
+ }
1974
+
1975
+ async function * packIterAsync (objectIterator, options) {
1976
+ const packr = new Packr(options);
1977
+ for await (const value of objectIterator) {
1978
+ yield packr.pack(value);
1979
+ }
1980
+ }
1981
+
1982
+ /**
1983
+ * Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
1984
+ * Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
1985
+ * @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
1986
+ * @param {object} [options] - unpackr options
1987
+ * @returns {IterableIterator|Promise.<AsyncIterableIterator}
1988
+ */
1989
+ function unpackIter (bufferIterator, options = {}) {
1990
+ if (!bufferIterator || typeof bufferIterator !== 'object') {
1991
+ throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
1992
+ }
1993
+
1994
+ const unpackr = new Unpackr(options);
1995
+ let incomplete;
1996
+ const parser = (chunk) => {
1997
+ let yields;
1998
+ // if there's incomplete data from previous chunk, concatinate and try again
1999
+ if (incomplete) {
2000
+ chunk = Buffer.concat([incomplete, chunk]);
2001
+ incomplete = undefined;
2002
+ }
2003
+
2004
+ try {
2005
+ yields = unpackr.unpackMultiple(chunk);
2006
+ } catch (err) {
2007
+ if (err.incomplete) {
2008
+ incomplete = chunk.slice(err.lastPosition);
2009
+ yields = err.values;
2010
+ } else {
2011
+ throw err
2012
+ }
2013
+ }
2014
+ return yields
2015
+ };
2016
+
2017
+ if (typeof bufferIterator[Symbol.iterator] === 'function') {
2018
+ return (function * iter () {
2019
+ for (const value of bufferIterator) {
2020
+ yield * parser(value);
2021
+ }
2022
+ })()
2023
+ } else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
2024
+ return (async function * iter () {
2025
+ for await (const value of bufferIterator) {
2026
+ yield * parser(value);
2027
+ }
2028
+ })()
2029
+ }
2030
+ }
2031
+ const decodeIter = unpackIter;
2023
2032
  const encodeIter = packIter;
2024
2033
 
2025
- const useRecords = false;
2034
+ const useRecords = false;
2026
2035
  const mapsAsObjects = true;
2027
2036
 
2028
2037
  exports.ALWAYS = ALWAYS;