protobufjs 8.7.1 → 8.8.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/src/parse.js CHANGED
@@ -23,6 +23,8 @@ var base10Re = /^[1-9][0-9]*$/,
23
23
  base16NegRe = /^-?0[x][0-9a-fA-F]+$/,
24
24
  base8Re = /^0[0-7]+$/,
25
25
  base8NegRe = /^-?0[0-7]+$/,
26
+ integerTypeRe = /^(?:u?int|sint|s?fixed)(?:32|64)$/,
27
+ unsignedTypeRe = /^(?:uint|fixed)(?:32|64)$/,
26
28
  numberRe = util.patterns.numberRe,
27
29
  nameRe = /^[a-zA-Z_][a-zA-Z_0-9]*$/,
28
30
  typeRefRe = util.patterns.typeRefRe;
@@ -202,7 +204,7 @@ function parse(source, root, options) {
202
204
  case "nan": case "NAN": case "Nan": case "NaN":
203
205
  return NaN;
204
206
  case "0":
205
- return 0;
207
+ return sign * 0;
206
208
  }
207
209
  if (base10Re.test(token))
208
210
  return sign * parseInt(token, 10);
@@ -219,32 +221,31 @@ function parse(source, root, options) {
219
221
  throw illegal(token, "number", insideTryCatch);
220
222
  }
221
223
 
222
- function parseId(token, acceptNegative, max) {
223
- if (token === null) {
224
+ function parseInteger(token, acceptNegative, name) {
225
+ if (token === null)
224
226
  throw illegal(token, "end of input");
225
- }
227
+ if (!acceptNegative && token.charAt(0) === "-")
228
+ throw illegal(token, name || "integer");
229
+ if (token === "0" || token === "-0")
230
+ return 0;
231
+ var value;
232
+ if (base10NegRe.test(token))
233
+ value = parseInt(token, 10);
234
+ else if (base16NegRe.test(token))
235
+ value = parseInt(token, 16);
236
+ else if (base8NegRe.test(token))
237
+ value = parseInt(token, 8);
238
+ else
239
+ throw illegal(token, name || "integer");
240
+ return value || 0;
241
+ }
242
+
243
+ function parseId(token, acceptNegative, max) {
226
244
  switch (token) {
227
245
  case "max": case "MAX": case "Max":
228
246
  return max || maxFieldId;
229
- case "0":
230
- return 0;
231
247
  }
232
-
233
- /* istanbul ignore if */
234
- if (!acceptNegative && token.charAt(0) === "-")
235
- throw illegal(token, "id");
236
-
237
- if (base10NegRe.test(token))
238
- return parseInt(token, 10);
239
- if (base16NegRe.test(token))
240
- return parseInt(token, 16);
241
-
242
- /* istanbul ignore else */
243
- if (base8NegRe.test(token))
244
- return parseInt(token, 8);
245
-
246
- /* istanbul ignore next */
247
- throw illegal(token, "id");
248
+ return parseInteger(token, acceptNegative, "id");
248
249
  }
249
250
 
250
251
  function parsePackage() {
@@ -307,7 +308,7 @@ function parse(source, root, options) {
307
308
  function parseEdition() {
308
309
  skip("=");
309
310
  edition = readString();
310
- const supportedEditions = ["2023", "2024"];
311
+ const supportedEditions = ["2023", "2024", "2026"];
311
312
 
312
313
  /* istanbul ignore if */
313
314
  if (!supportedEditions.includes(edition))
@@ -341,6 +342,7 @@ function parse(source, root, options) {
341
342
  if (edition < "2024") {
342
343
  return false;
343
344
  }
345
+ var visibility = token;
344
346
  token = next();
345
347
  if (token === "export" || token === "local") {
346
348
  return false;
@@ -348,9 +350,11 @@ function parse(source, root, options) {
348
350
  if (token !== "message" && token !== "enum") {
349
351
  return false;
350
352
  }
351
- /* eslint-disable no-warning-comments */
352
- // TODO: actually enforce visiblity modifiers like protoc does.
353
- return parseCommon(parent, token, depth);
353
+ (token === "message"
354
+ ? parseType(parent, token, depth + 1)
355
+ : parseEnum(parent, token)
356
+ ).visibility = visibility;
357
+ return true;
354
358
 
355
359
  case "service":
356
360
  parseService(parent, token, depth + 1);
@@ -455,6 +459,7 @@ function parse(source, root, options) {
455
459
  if (parent === ptr) {
456
460
  topLevelObjects.push(type);
457
461
  }
462
+ return type;
458
463
  }
459
464
 
460
465
  function parseField(parent, rule, extend, depth) {
@@ -719,6 +724,7 @@ function parse(source, root, options) {
719
724
  if (parent === ptr) {
720
725
  topLevelObjects.push(enm);
721
726
  }
727
+ return enm;
722
728
  }
723
729
 
724
730
  function parseEnumValue(token) {
@@ -881,7 +887,9 @@ function parse(source, root, options) {
881
887
  return objectResult;
882
888
  }
883
889
 
884
- var simpleValue = readValue(true);
890
+ var simpleValue = name === "default" && parent instanceof Field && integerTypeRe.test(parent.type)
891
+ ? parseInteger(next(), !unsignedTypeRe.test(parent.type))
892
+ : readValue(true);
885
893
  setOption(parent, name, simpleValue);
886
894
  return simpleValue;
887
895
  // Does not enforce a delimiter to be universal
package/src/reader.js CHANGED
@@ -94,12 +94,32 @@ Reader.prototype.raw = function read_raw(start, end) {
94
94
  return this.buf.subarray(start, end);
95
95
  };
96
96
 
97
+ function readVarint32NearEnd(reader) {
98
+ // Safely read up to four bytes of a varint32 near the reader limit
99
+ var value = 0;
100
+ for (var i = 0; i < 4; ++i) {
101
+ if (reader.pos >= reader.len)
102
+ throw indexOutOfRange(reader);
103
+ var b = reader.buf[reader.pos++];
104
+ value = (value | (b & 127) << i * 7) >>> 0;
105
+ if (b < 128)
106
+ return value;
107
+ }
108
+ throw indexOutOfRange(reader);
109
+ }
110
+
97
111
  /**
98
112
  * Reads a varint as an unsigned 32 bit value.
99
113
  * @function
100
114
  * @returns {number} Value read
101
115
  */
102
116
  Reader.prototype.uint32 = function read_uint32() {
117
+ if (this.len - this.pos < 5) {
118
+ if (this.pos >= this.len)
119
+ throw indexOutOfRange(this);
120
+ if (this.buf[this.pos] >= 128)
121
+ return readVarint32NearEnd(this);
122
+ }
103
123
  var buf = this.buf,
104
124
  pos = this.pos,
105
125
  value = (buf[pos] & 127) >>> 0;
@@ -150,6 +170,12 @@ Reader.prototype.uint32 = function read_uint32() {
150
170
  * @returns {number} Tag read
151
171
  */
152
172
  Reader.prototype.tag = function read_tag() {
173
+ if (this.len - this.pos < 5) {
174
+ if (this.pos >= this.len)
175
+ throw indexOutOfRange(this);
176
+ if (this.buf[this.pos] >= 128)
177
+ return readVarint32NearEnd(this);
178
+ }
153
179
  var buf = this.buf,
154
180
  pos = this.pos,
155
181
  value = (buf[pos] & 127) >>> 0;
@@ -395,9 +421,22 @@ Reader.prototype.double = function read_double() {
395
421
  */
396
422
  Reader.prototype.uint32s = function read_uint32s(array) {
397
423
  if (array === undefined) array = [];
398
- var end = this.uint32() + this.pos;
399
- while (this.pos < end)
400
- array.push(this.uint32());
424
+ var end = this.uint32() + this.pos, len = this.len, buf = this.buf, pos = this.pos, value;
425
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
426
+ this.len = end;
427
+ while (pos < end) {
428
+ value = buf[pos++];
429
+ if (value < 128)
430
+ array.push(value);
431
+ else {
432
+ this.pos = pos - 1;
433
+ array.push(this.uint32());
434
+ pos = this.pos;
435
+ }
436
+ }
437
+ this.pos = pos;
438
+ if (pos !== end) throw RangeError("index out of range");
439
+ this.len = len;
401
440
  return array;
402
441
  };
403
442
 
@@ -408,9 +447,22 @@ Reader.prototype.uint32s = function read_uint32s(array) {
408
447
  */
409
448
  Reader.prototype.int32s = function read_int32s(array) {
410
449
  if (array === undefined) array = [];
411
- var end = this.uint32() + this.pos;
412
- while (this.pos < end)
413
- array.push(this.int32());
450
+ var end = this.uint32() + this.pos, len = this.len, buf = this.buf, pos = this.pos, value;
451
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
452
+ this.len = end;
453
+ while (pos < end) {
454
+ value = buf[pos++];
455
+ if (value < 128)
456
+ array.push(value);
457
+ else {
458
+ this.pos = pos - 1;
459
+ array.push(this.int32());
460
+ pos = this.pos;
461
+ }
462
+ }
463
+ this.pos = pos;
464
+ if (pos !== end) throw RangeError("index out of range");
465
+ this.len = len;
414
466
  return array;
415
467
  };
416
468
 
@@ -421,9 +473,13 @@ Reader.prototype.int32s = function read_int32s(array) {
421
473
  */
422
474
  Reader.prototype.sint32s = function read_sint32s(array) {
423
475
  if (array === undefined) array = [];
424
- var end = this.uint32() + this.pos;
476
+ var end = this.uint32() + this.pos, len = this.len;
477
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
478
+ this.len = end;
425
479
  while (this.pos < end)
426
480
  array.push(this.sint32());
481
+ if (this.pos !== end) throw RangeError("index out of range");
482
+ this.len = len;
427
483
  return array;
428
484
  };
429
485
 
@@ -434,9 +490,22 @@ Reader.prototype.sint32s = function read_sint32s(array) {
434
490
  */
435
491
  Reader.prototype.bools = function read_bools(array) {
436
492
  if (array === undefined) array = [];
437
- var end = this.uint32() + this.pos;
438
- while (this.pos < end)
439
- array.push(this.bool());
493
+ var end = this.uint32() + this.pos, len = this.len, buf = this.buf, pos = this.pos, value;
494
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
495
+ this.len = end;
496
+ while (pos < end) {
497
+ value = buf[pos++];
498
+ if (value < 128)
499
+ array.push(value !== 0);
500
+ else {
501
+ this.pos = pos - 1;
502
+ array.push(this.bool());
503
+ pos = this.pos;
504
+ }
505
+ }
506
+ this.pos = pos;
507
+ if (pos !== end) throw RangeError("index out of range");
508
+ this.len = len;
440
509
  return array;
441
510
  };
442
511
 
@@ -555,9 +624,13 @@ Reader.prototype.doubles = function read_doubles(array) {
555
624
  */
556
625
  Reader.prototype.uint64s = function read_uint64s(array) {
557
626
  if (array === undefined) array = [];
558
- var end = this.uint32() + this.pos;
627
+ var end = this.uint32() + this.pos, len = this.len;
628
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
629
+ this.len = end;
559
630
  while (this.pos < end)
560
631
  array.push(this.uint64());
632
+ if (this.pos !== end) throw RangeError("index out of range");
633
+ this.len = len;
561
634
  return array;
562
635
  };
563
636
 
@@ -568,9 +641,13 @@ Reader.prototype.uint64s = function read_uint64s(array) {
568
641
  */
569
642
  Reader.prototype.int64s = function read_int64s(array) {
570
643
  if (array === undefined) array = [];
571
- var end = this.uint32() + this.pos;
644
+ var end = this.uint32() + this.pos, len = this.len;
645
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
646
+ this.len = end;
572
647
  while (this.pos < end)
573
648
  array.push(this.int64());
649
+ if (this.pos !== end) throw RangeError("index out of range");
650
+ this.len = len;
574
651
  return array;
575
652
  };
576
653
 
@@ -581,9 +658,13 @@ Reader.prototype.int64s = function read_int64s(array) {
581
658
  */
582
659
  Reader.prototype.sint64s = function read_sint64s(array) {
583
660
  if (array === undefined) array = [];
584
- var end = this.uint32() + this.pos;
661
+ var end = this.uint32() + this.pos, len = this.len;
662
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
663
+ this.len = end;
585
664
  while (this.pos < end)
586
665
  array.push(this.sint64());
666
+ if (this.pos !== end) throw RangeError("index out of range");
667
+ this.len = len;
587
668
  return array;
588
669
  };
589
670
 
package/src/type.js CHANGED
@@ -70,6 +70,12 @@ function Type(name, options) {
70
70
  */
71
71
  this.group = undefined; // toJSON
72
72
 
73
+ /**
74
+ * Declared symbol visibility, if any.
75
+ * @type {"local"|"export"|undefined}
76
+ */
77
+ this.visibility = undefined; // toJSON
78
+
73
79
  /**
74
80
  * Cached fields by id.
75
81
  * @type {Object.<number,Field>|null}
@@ -254,6 +260,7 @@ function clearCache(type) {
254
260
  * @property {number[][]} [extensions] Extension ranges
255
261
  * @property {Array.<number[]|string>} [reserved] Reserved ranges
256
262
  * @property {boolean} [group=false] Whether a legacy group or not
263
+ * @property {"local"|"export"} [visibility] Declared symbol visibility
257
264
  * @property {string|null} [comment] Message type comment
258
265
  */
259
266
 
@@ -304,6 +311,8 @@ Type.fromJSON = function fromJSON(name, json, depth) {
304
311
  type.reserved = json.reserved;
305
312
  if (json.group)
306
313
  type.group = true;
314
+ if (json.visibility)
315
+ type.visibility = json.visibility;
307
316
  if (json.comment)
308
317
  type.comment = json.comment;
309
318
  if (json.edition)
@@ -328,6 +337,7 @@ Type.prototype.toJSON = function toJSON(toJSONOptions) {
328
337
  "extensions" , this.extensions && this.extensions.length ? this.extensions : undefined,
329
338
  "reserved" , this.reserved && this.reserved.length ? this.reserved : undefined,
330
339
  "group" , this.group || undefined,
340
+ "visibility" , this.visibility,
331
341
  "nested" , inherited && inherited.nested || undefined,
332
342
  "comment" , keepComments ? this.comment : undefined
333
343
  ]);
@@ -64,7 +64,9 @@ function codegen(functionParams, functionName) {
64
64
  formatStringOrScope = formatStringOrScope.replace(/%([%dfijs])/g, function replace($0, $1) {
65
65
  var value = formatParams[formatOffset++];
66
66
  switch ($1) {
67
- case "d": case "f": return String(Number(value));
67
+ case "d": case "f":
68
+ value = Number(value);
69
+ return Object.is(value, -0) ? "-0" : String(value);
68
70
  case "i": return String(Math.floor(value));
69
71
  case "j": return JSON.stringify(value);
70
72
  case "s": return String(value);
package/src/util/utf8.js CHANGED
@@ -6,7 +6,6 @@
6
6
  * @namespace
7
7
  */
8
8
  var utf8 = exports,
9
- replacementChar = "\ufffd",
10
9
  looseDecoder = new TextDecoder("utf-8", { ignoreBOM: true }),
11
10
  strictDecoder;
12
11
  var TEXT_DECODER_MIN_LENGTH = 64;
@@ -41,31 +40,6 @@ utf8.length = function utf8_length(string) {
41
40
  return len;
42
41
  };
43
42
 
44
- function utf8_read_js(buffer, start, end, str) {
45
- for (var i = start; i < end;) {
46
- var t = buffer[i++];
47
- if (t <= 0x7F) {
48
- str += String.fromCharCode(t);
49
- } else if (t >= 0xC0 && t < 0xE0) {
50
- var c2 = (t & 0x1F) << 6 | buffer[i++] & 0x3F;
51
- str += c2 >= 0x80 ? String.fromCharCode(c2) : replacementChar;
52
- } else if (t >= 0xE0 && t < 0xF0) {
53
- var c3 = (t & 0xF) << 12 | (buffer[i++] & 0x3F) << 6 | buffer[i++] & 0x3F;
54
- str += c3 >= 0x800 ? String.fromCharCode(c3) : replacementChar;
55
- } else if (t >= 0xF0) {
56
- var t2 = (t & 7) << 18 | (buffer[i++] & 0x3F) << 12 | (buffer[i++] & 0x3F) << 6 | buffer[i++] & 0x3F;
57
- if (t2 < 0x10000 || t2 > 0x10FFFF)
58
- str += replacementChar;
59
- else {
60
- t2 -= 0x10000;
61
- str += String.fromCharCode(0xD800 + (t2 >> 10));
62
- str += String.fromCharCode(0xDC00 + (t2 & 0x3FF));
63
- }
64
- }
65
- }
66
- return str;
67
- }
68
-
69
43
  function utf8_read_decoder(decoder, buffer, start, end) {
70
44
  var source = start === 0 && end === buffer.length
71
45
  ? buffer
@@ -100,14 +74,14 @@ utf8.read = function utf8_read_loose(buffer, start, end) {
100
74
  c7 = buffer[i + 6];
101
75
  c8 = buffer[i + 7];
102
76
  if ((c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8) & 0x80)
103
- return utf8_read_js(buffer, i, end, str);
77
+ return str + utf8_read_decoder(looseDecoder, buffer, i, end);
104
78
  str += String.fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8);
105
79
  }
106
80
 
107
81
  for (; i < end; ++i) {
108
82
  c1 = buffer[i];
109
83
  if (c1 & 0x80)
110
- return utf8_read_js(buffer, i, end, str);
84
+ return str + utf8_read_decoder(looseDecoder, buffer, i, end);
111
85
  str += String.fromCharCode(c1);
112
86
  }
113
87
 
package/src/wrappers.js CHANGED
@@ -40,6 +40,10 @@ var Message = require("./message"),
40
40
  wrappers[".google.protobuf.Any"] = {
41
41
 
42
42
  fromObject: function(object, depth) {
43
+ if (depth === undefined)
44
+ depth = 0;
45
+ if (depth > util.recursionLimit)
46
+ throw Error("max depth exceeded");
43
47
 
44
48
  // unwrap value type if mapped
45
49
  if (object && object["@type"]) {
@@ -57,7 +61,7 @@ wrappers[".google.protobuf.Any"] = {
57
61
  }
58
62
  return this.create({
59
63
  type_url: type_url,
60
- value: type.encode(type.fromObject(object, depth === undefined ? 1 : depth + 1)).finish()
64
+ value: type.encode(type.fromObject(object, depth + 1)).finish()
61
65
  });
62
66
  }
63
67
  }
package/src/writer.js CHANGED
@@ -26,7 +26,7 @@ function Writer() {
26
26
  * Backing buffer.
27
27
  * @type {Uint8Array}
28
28
  */
29
- this.buf = this.constructor.alloc(64);
29
+ this.buf = this.constructor.alloc(Writer.initialBufferSize);
30
30
 
31
31
  /**
32
32
  * Cached DataView over {@link Writer#buf}.
@@ -41,6 +41,12 @@ function Writer() {
41
41
  this.states = null;
42
42
  }
43
43
 
44
+ /**
45
+ * Initial backing buffer size in bytes. Defaults to 128.
46
+ * @type {number}
47
+ */
48
+ Writer.initialBufferSize = 128;
49
+
44
50
  /**
45
51
  * Current write position.
46
52
  * @name Writer#len