compact-encoding 3.2.0 → 3.3.1

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.
Files changed (2) hide show
  1. package/index.js +46 -12
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -2,6 +2,11 @@ const b4a = require('b4a')
2
2
 
3
3
  const { BE } = require('./endian')
4
4
 
5
+ // Zig-zag doubles the magnitude of a value before it is written as a uint, so
6
+ // an int only reaches half as far as a uint of the same width does.
7
+ const MAX_SAFE_INT = 2 ** 52 - 1
8
+ const MIN_SAFE_INT = -(2 ** 52)
9
+
5
10
  exports.state = function (start = 0, end = 0, buffer = null) {
6
11
  return { start, end, buffer }
7
12
  }
@@ -171,7 +176,9 @@ const uint56 = (exports.uint56 = {
171
176
  },
172
177
  decode(state) {
173
178
  if (state.end - state.start < 7) throw new Error('Out of bounds')
174
- return uint24.decode(state) + 0x1000000 * uint32.decode(state)
179
+ return validateSafeUint(
180
+ uint24.decode(state) + 0x1000000 * uint32.decode(state)
181
+ )
175
182
  }
176
183
  })
177
184
 
@@ -187,7 +194,9 @@ const uint64 = (exports.uint64 = {
187
194
  },
188
195
  decode(state) {
189
196
  if (state.end - state.start < 8) throw new Error('Out of bounds')
190
- return uint32.decode(state) + 0x100000000 * uint32.decode(state)
197
+ return validateSafeUint(
198
+ uint32.decode(state) + 0x100000000 * uint32.decode(state)
199
+ )
191
200
  }
192
201
  })
193
202
 
@@ -203,7 +212,9 @@ exports.uint64be = {
203
212
  },
204
213
  decode(state) {
205
214
  if (state.end - state.start < 8) throw new Error('Out of bounds')
206
- return 0x100000000 * uint32be.decode(state) + uint32be.decode(state)
215
+ return validateSafeUint(
216
+ 0x100000000 * uint32be.decode(state) + uint32be.decode(state)
217
+ )
207
218
  }
208
219
  }
209
220
 
@@ -1058,6 +1069,7 @@ function zigZagDecodeInt(n) {
1058
1069
  }
1059
1070
 
1060
1071
  function zigZagEncodeInt(n) {
1072
+ validateInt(n)
1061
1073
  // 0, -1, 1, -2, 2, ...
1062
1074
  return n < 0 ? 2 * -n - 1 : n === 0 ? 0 : 2 * n
1063
1075
  }
@@ -1085,14 +1097,36 @@ function zigZagEncodeBigInt(n) {
1085
1097
  return n < 0n ? 2n * -n - 1n : n === 0n ? 0n : 2n * n
1086
1098
  }
1087
1099
 
1100
+ function validateSafeUint(n) {
1101
+ if (n <= Number.MAX_SAFE_INTEGER) return n // Handles NaN as well
1102
+
1103
+ throw outsideUintRange()
1104
+ }
1105
+
1088
1106
  function validateUint(n) {
1089
- if (n >= 0 === false /* Handles NaN as well */)
1090
- throw new Error('uint must be positive')
1091
- // Beyond this, Number arithmetic loses precision and silently corrupts the
1092
- // encoding. The zig-zag int codecs route through here too, so this also
1093
- // guards int values whose doubled magnitude exceeds the safe range.
1094
- if (n > Number.MAX_SAFE_INTEGER)
1095
- throw new Error(
1096
- 'integer is greater than the maximum safe integer, use biguint/bigint'
1097
- )
1107
+ if (n >= 0 && n <= Number.MAX_SAFE_INTEGER) return n // Handles NaN as well
1108
+
1109
+ throw outsideUintRange()
1110
+ }
1111
+
1112
+ function validateInt(n) {
1113
+ if (n >= MIN_SAFE_INT && n <= MAX_SAFE_INT) return n // Handles NaN as well
1114
+
1115
+ throw outsideIntRange()
1116
+ }
1117
+
1118
+ // The validations above sit on the hottest paths in the library and are small
1119
+ // enough to be inlined, which building a message inline would put a stop to.
1120
+ // Kept out here, the message costs nothing until it is actually thrown.
1121
+
1122
+ function outsideUintRange() {
1123
+ return new Error(
1124
+ `uint must be between 0 and ${Number.MAX_SAFE_INTEGER}, use biguint`
1125
+ )
1126
+ }
1127
+
1128
+ function outsideIntRange() {
1129
+ return new Error(
1130
+ `int must be between ${MIN_SAFE_INT} and ${MAX_SAFE_INT}, use bigint`
1131
+ )
1098
1132
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compact-encoding",
3
- "version": "3.2.0",
3
+ "version": "3.3.1",
4
4
  "description": "A series of compact encoding schemes for building small and fast parsers and serializers",
5
5
  "main": "index.js",
6
6
  "files": [