protobufjs 8.7.2 → 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/README.md CHANGED
@@ -316,26 +316,32 @@ protobuf.js is validated against the official Protocol Buffers conformance suite
316
316
  | ↳ Proto2 | 100.00% (707/707) | 100.00% (489/489) | 100.00% (218/218) |
317
317
  | ↳ Proto3 | 100.00% (707/707) | 100.00% (486/486) | 100.00% (221/221) |
318
318
  | ↳ Editions | 100.00% (1421/1421) | 100.00% (983/983) | 100.00% (438/438) |
319
- | ProtoJSON | 100.00% (2796/2796) | 100.00% (2362/2362) | 100.00% (434/434) |
319
+ | ProtoJSON | 100.00% (2814/2814) | 100.00% (2362/2362) | 100.00% (452/452) |
320
320
  | TextFormat | 100.00% (909/909) | 100.00% (845/845) | 100.00% (64/64) |
321
- | Overall | 100.00% (6540/6540) | 100.00% (5165/5165) | 100.00% (1375/1375) |
321
+ | Overall | 100.00% (6558/6558) | 100.00% (5165/5165) | 100.00% (1393/1393) |
322
322
 
323
323
  <!-- END CONFORMANCE DATA -->
324
324
 
325
+ | Edition | Supported since
326
+ |---------|----------------
327
+ | 2023 | v7.5.0
328
+ | 2024 | v8.0.0
329
+ | 2026 | v8.8.0
330
+
325
331
  [Structured results](https://github.com/protobufjs/protobuf.js/actions/workflows/test.yml?query=branch%3Amaster+event%3Apush) of the conformance tests are also available as CI artifacts.
326
332
 
327
333
  ## Performance
328
334
 
329
- Both reflection and static modes use specialized encoders and decoders backed by the same hand-tuned reader and writer primitives.
335
+ protobuf.js's reflection and static modes share the same code-generation backend and underlying hand-tuned reader and writer primitives. Reflection mode emits specialized encoders and decoders just in time, while static mode emits equivalent code ahead of time.
330
336
 
331
- The repository includes a [benchmark suite](./bench) you can run yourself. It compares protobuf.js with other general-purpose JavaScript implementations across three substantially different cases: our classic common message shape and two unmodified, structurally distinct fixtures sourced externally. The suite measures each library's recommended serialization and deserialization path using identical schemas and inputs, with JSON included as an additional baseline. Across these cases, protobuf.js is a clear upgrade over using JSON and consistently the fastest Protobuf implementation by a considerable margin.
337
+ To see how this architecture compares in practice, the repository includes a reproducible [benchmark suite](./bench) measuring both modes alongside other general-purpose JavaScript implementations across three cases: our classic common message shape and two unmodified, structurally distinct fixtures sourced from other implementations. Each library is tested through its recommended serialization and deserialization path using identical schemas and message contents.
332
338
 
333
339
  <!-- BEGIN BENCHMARK DATA -->
334
340
 
335
341
  <picture>
336
342
  <source media="(prefers-color-scheme: dark)" srcset="./bench/results/encode-dark.svg">
337
343
  <source media="(prefers-color-scheme: light)" srcset="./bench/results/encode-light.svg">
338
- <img alt="Encode benchmark" src="./bench/results/encode.svg">
344
+ <img alt="Encode Throughput" src="./bench/results/encode.svg">
339
345
  </picture>
340
346
 
341
347
  <details>
@@ -343,18 +349,18 @@ The repository includes a [benchmark suite](./bench) you can run yourself. It co
343
349
 
344
350
  | Implementation | Common | Vector tile | Buf perf |
345
351
  | --- | ---: | ---: | ---: |
346
- | protobuf.js static | **5.34M ops/s** &nbsp; <small>1.0x</small> | **3.09K ops/s** &nbsp; <small>1.0x</small> | 43.1K ops/s &nbsp; <small>1.0x</small> |
347
- | protobuf.js reflect | 4.89M ops/s &nbsp; <small>1.1x</small> | 3.03K ops/s &nbsp; <small>1.0x</small> | **43.3K ops/s** &nbsp; <small>1.0x</small> |
348
- | JSON | 2.09M ops/s &nbsp; <small>2.6x</small> | 897 ops/s &nbsp; <small>3.4x</small> | 6.70K ops/s &nbsp; <small>6.5x</small> |
349
- | protoc-gen-js | 1.03M ops/s &nbsp; <small>5.2x</small> | 700 ops/s &nbsp; <small>4.4x</small> | 13.9K ops/s &nbsp; <small>3.1x</small> |
350
- | protoc-gen-es | 402K ops/s &nbsp; <small>13.3x</small> | 235 ops/s &nbsp; <small>13.2x</small> | 8.22K ops/s &nbsp; <small>5.3x</small> |
352
+ | protobuf.js static | **5.28M ops/s** &nbsp; <small>1.0x</small> | 3.06K ops/s &nbsp; <small>1.0x</small> | **49.2K ops/s** &nbsp; <small>1.0x</small> |
353
+ | protobuf.js reflect | 5.16M ops/s &nbsp; <small>1.0x</small> | **3.08K ops/s** &nbsp; <small>1.0x</small> | 47.5K ops/s &nbsp; <small>1.0x</small> |
354
+ | JSON | 3.44M ops/s &nbsp; <small>1.5x</small> | 1.50K ops/s &nbsp; <small>2.1x</small> | 7.13K ops/s &nbsp; <small>6.9x</small> |
355
+ | protoc-gen-js | 1.05M ops/s &nbsp; <small>5.0x</small> | 691 ops/s &nbsp; <small>4.5x</small> | 15.0K ops/s &nbsp; <small>3.3x</small> |
356
+ | protoc-gen-es | 1.22M ops/s &nbsp; <small>4.3x</small> | 1.14K ops/s &nbsp; <small>2.7x</small> | 35.8K ops/s &nbsp; <small>1.4x</small> |
351
357
 
352
358
  </details>
353
359
 
354
360
  <picture>
355
361
  <source media="(prefers-color-scheme: dark)" srcset="./bench/results/decode-dark.svg">
356
362
  <source media="(prefers-color-scheme: light)" srcset="./bench/results/decode-light.svg">
357
- <img alt="Decode benchmark" src="./bench/results/decode.svg">
363
+ <img alt="Decode Throughput" src="./bench/results/decode.svg">
358
364
  </picture>
359
365
 
360
366
  <details>
@@ -362,22 +368,23 @@ The repository includes a [benchmark suite](./bench) you can run yourself. It co
362
368
 
363
369
  | Implementation | Common | Vector tile | Buf perf |
364
370
  | --- | ---: | ---: | ---: |
365
- | protobuf.js static | 6.45M ops/s &nbsp; <small>1.1x</small> | 2.70K ops/s &nbsp; <small>1.1x</small> | **81.7K ops/s** &nbsp; <small>1.0x</small> |
366
- | protobuf.js reflect | **6.93M ops/s** &nbsp; <small>1.0x</small> | **2.99K ops/s** &nbsp; <small>1.0x</small> | 80.3K ops/s &nbsp; <small>1.0x</small> |
367
- | JSON | 1.37M ops/s &nbsp; <small>5.0x</small> | 1.06K ops/s &nbsp; <small>2.8x</small> | 19.5K ops/s &nbsp; <small>4.2x</small> |
368
- | protoc-gen-js | 811K ops/s &nbsp; <small>8.5x</small> | 851 ops/s &nbsp; <small>3.5x</small> | 21.7K ops/s &nbsp; <small>3.8x</small> |
369
- | protoc-gen-es | 691K ops/s &nbsp; <small>10.0x</small> | 376 ops/s &nbsp; <small>8.0x</small> | 14.3K ops/s &nbsp; <small>5.7x</small> |
371
+ | protobuf.js static | 5.84M ops/s &nbsp; <small>1.1x</small> | 2.45K ops/s &nbsp; <small>1.1x</small> | **78.9K ops/s** &nbsp; <small>1.0x</small> |
372
+ | protobuf.js reflect | **6.54M ops/s** &nbsp; <small>1.0x</small> | **2.66K ops/s** &nbsp; <small>1.0x</small> | 77.0K ops/s &nbsp; <small>1.0x</small> |
373
+ | JSON | 1.58M ops/s &nbsp; <small>4.1x</small> | 1.21K ops/s &nbsp; <small>2.2x</small> | 21.0K ops/s &nbsp; <small>3.8x</small> |
374
+ | protoc-gen-js | 701K ops/s &nbsp; <small>9.3x</small> | 946 ops/s &nbsp; <small>2.8x</small> | 21.5K ops/s &nbsp; <small>3.7x</small> |
375
+ | protoc-gen-es | 1.67M ops/s &nbsp; <small>3.9x</small> | 1.19K ops/s &nbsp; <small>2.2x</small> | 31.0K ops/s &nbsp; <small>2.5x</small> |
370
376
 
371
377
  </details>
372
378
 
373
379
  <!-- END BENCHMARK DATA -->
374
380
 
375
- [Structured results](./bench/results/latest.json) and environment details for this run are also available as committed artifacts.
381
+ [Structured results](./bench/results/latest.json) include environment details for this run and are committed alongside the charts. The suite also runs in CI.
376
382
 
377
383
  To run the benchmark on your own hardware:
378
384
 
379
385
  ```sh
380
386
  npm --prefix bench install
387
+ npm --prefix bench run generate
381
388
  npm run bench
382
389
  ```
383
390
 
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * protobuf.js v8.7.2 (c) 2016, daniel wirtz
3
- * compiled sat, 08 aug 2026 13:15:56 utc
2
+ * protobuf.js v8.8.0 (c) 2016, daniel wirtz
3
+ * compiled thu, 27 aug 2026 00:01:05 utc
4
4
  * licensed under the bsd-3-clause license
5
5
  * see: https://github.com/dcodeio/protobuf.js for details
6
6
  */
@@ -446,7 +446,17 @@ function decoder(mtype) {
446
446
  ("if(q===undefined)q=0")
447
447
  ("if(q>Reader.recursionLimit)")
448
448
  ("throw Error(\"max depth exceeded\")")
449
- ("var c=l===undefined?r.len:r.pos+l,m=g||new C" + (hasMapField ? ",k,v" : needsValueVar ? ",v" : ""))
449
+ ("var c,m" + (hasMapField ? ",k,v" : needsValueVar ? ",v" : ""))
450
+ ("if(l===undefined)")
451
+ ("c=r.len")
452
+ ("else{")
453
+ ("c=r.pos+l")
454
+ ("if(c>r.len)")
455
+ ("throw RangeError(\"index out of range\")")
456
+ ("l=r.len")
457
+ ("r.len=c")
458
+ ("}")
459
+ ("m=g||new C")
450
460
  ("while(r.pos<c){")
451
461
  ("var s=r.pos")
452
462
  ("var t=r.tag()")
@@ -473,7 +483,10 @@ function decoder(mtype) {
473
483
  ("if(%s===util.emptyObject)", ref)
474
484
  ("%s={}", ref);
475
485
  gen
476
- ("var c2=r.uint32()+r.pos");
486
+ ("var c2=r.uint32()+r.pos")
487
+ ("if(c2>r.len)")
488
+ ("throw RangeError(\"index out of range\")")
489
+ ("r.len=c2");
477
490
 
478
491
  if (types.defaults[field.keyType] !== undefined) gen
479
492
  ("k=%j", types.defaults[field.keyType]);
@@ -511,6 +524,10 @@ function decoder(mtype) {
511
524
  ("}")
512
525
  ("r.skipType(u,q,t2)")
513
526
  ("}");
527
+ gen
528
+ ("if(r.pos!==c2)")
529
+ ("throw RangeError(\"index out of range\")")
530
+ ("r.len=c");
514
531
 
515
532
  if (closed) { gen
516
533
  ("if(types[%i].valuesById[v]===undefined){", i);
@@ -544,6 +561,9 @@ function decoder(mtype) {
544
561
  if (closed) {
545
562
  gen
546
563
  ("var c2=r.uint32()+r.pos")
564
+ ("if(c2>r.len)")
565
+ ("throw RangeError(\"index out of range\")")
566
+ ("r.len=c2")
547
567
  ("while(r.pos<c2){")
548
568
  ("s=r.pos")
549
569
  ("v=r.%s()", type)
@@ -554,6 +574,10 @@ function decoder(mtype) {
554
574
  ("}else");
555
575
  genPreserveUnknown(gen, "util.rawField(" + field.id + ",0,r.raw(s,r.pos))")
556
576
  ("}");
577
+ gen
578
+ ("if(r.pos!==c2)")
579
+ ("throw RangeError(\"index out of range\")")
580
+ ("r.len=c");
557
581
  } else gen
558
582
  ("if(!(%s&&%s.length))", ref, ref)
559
583
  ("%s=[]", ref)
@@ -662,6 +686,11 @@ function decoder(mtype) {
662
686
  ("r.skipType(%s,q,t)", i ? "u" : "t&7");
663
687
  genPreserveUnknown(gen, "r.raw(s,r.pos)")
664
688
  ("}")
689
+ ("if(l!==undefined){")
690
+ ("if(r.pos!==c)")
691
+ ("throw RangeError(\"index out of range\")")
692
+ ("r.len=l")
693
+ ("}")
665
694
  ("if(z!==undefined)")
666
695
  ("throw Error(\"missing end group\")");
667
696
 
@@ -882,6 +911,12 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
882
911
  */
883
912
  this.reserved = undefined; // toJSON
884
913
 
914
+ /**
915
+ * Declared symbol visibility, if any.
916
+ * @type {"local"|"export"|undefined}
917
+ */
918
+ this.visibility = undefined; // toJSON
919
+
885
920
  // Note that values inherit valuesById on their prototype which makes them a TypeScript-
886
921
  // compatible enum. This is used by pbts to write actual enum definitions that work for
887
922
  // static and reflection code alike instead of emitting generic object definitions.
@@ -918,6 +953,7 @@ Enum.prototype._resolveFeatures = function _resolveFeatures(edition) {
918
953
  * @property {Object.<string,*>} [options] Enum options
919
954
  * @property {Object.<string,Object.<string,*>>} [valuesOptions] Enum value options
920
955
  * @property {Array.<number[]|string>} [reserved] Reserved ranges
956
+ * @property {"local"|"export"} [visibility] Declared symbol visibility
921
957
  * @property {string|null} [comment] Enum comment
922
958
  * @property {Object.<string,string|null>} [comments] Value comments
923
959
  */
@@ -932,6 +968,8 @@ Enum.prototype._resolveFeatures = function _resolveFeatures(edition) {
932
968
  Enum.fromJSON = function fromJSON(name, json) {
933
969
  var enm = new Enum(name, json.values, json.options, json.comment, json.comments, json.valuesOptions);
934
970
  enm.reserved = json.reserved;
971
+ if (json.visibility)
972
+ enm.visibility = json.visibility;
935
973
  if (json.edition)
936
974
  enm._edition = json.edition;
937
975
  enm._defaultEdition = "proto3"; // For backwards-compatibility.
@@ -951,6 +989,7 @@ Enum.prototype.toJSON = function toJSON(toJSONOptions) {
951
989
  "valuesOptions" , this.valuesOptions,
952
990
  "values" , this.values,
953
991
  "reserved" , this.reserved && this.reserved.length ? this.reserved : undefined,
992
+ "visibility" , this.visibility,
954
993
  "comment" , keepComments ? this.comment : undefined,
955
994
  "comments" , keepComments ? this.comments : undefined
956
995
  ]);
@@ -2761,10 +2800,11 @@ var Root; // cyclic
2761
2800
 
2762
2801
  /* eslint-disable no-warning-comments */
2763
2802
  // TODO: Replace with embedded proto.
2764
- var editions2024Defaults = {enum_type: "OPEN", field_presence: "EXPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY", enforce_naming_style: "STYLE2024", default_symbol_visibility: "EXPORT_TOP_LEVEL" };
2765
- var editions2023Defaults = {enum_type: "OPEN", field_presence: "EXPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY", enforce_naming_style: "STYLE_LEGACY", default_symbol_visibility: "EXPORT_ALL" };
2766
2803
  var proto2Defaults = {enum_type: "CLOSED", field_presence: "EXPLICIT", json_format: "LEGACY_BEST_EFFORT", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "EXPANDED", utf8_validation: "NONE", enforce_naming_style: "STYLE_LEGACY", default_symbol_visibility: "EXPORT_ALL" };
2767
2804
  var proto3Defaults = {enum_type: "OPEN", field_presence: "IMPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY", enforce_naming_style: "STYLE_LEGACY", default_symbol_visibility: "EXPORT_ALL" };
2805
+ var editions2023Defaults = {enum_type: "OPEN", field_presence: "EXPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY", enforce_naming_style: "STYLE_LEGACY", default_symbol_visibility: "EXPORT_ALL" };
2806
+ var editions2024Defaults = {enum_type: "OPEN", field_presence: "EXPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY", enforce_naming_style: "STYLE2024", default_symbol_visibility: "EXPORT_TOP_LEVEL" };
2807
+ var editions2026Defaults = {enum_type: "OPEN", field_presence: "EXPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY", enforce_naming_style: "STYLE2026", default_symbol_visibility: "STRICT", enforce_proto_limits: "PROTO_LIMITS2026" };
2768
2808
 
2769
2809
  /**
2770
2810
  * Constructs a new reflection object instance.
@@ -2978,6 +3018,8 @@ ReflectionObject.prototype._resolveFeatures = function _resolveFeatures(edition)
2978
3018
  defaults = Object.assign({}, editions2023Defaults);
2979
3019
  } else if (edition === "2024") {
2980
3020
  defaults = Object.assign({}, editions2024Defaults);
3021
+ } else if (edition === "2026") {
3022
+ defaults = Object.assign({}, editions2026Defaults);
2981
3023
  } else {
2982
3024
  throw new Error("Unknown edition: " + edition);
2983
3025
  }
@@ -3474,12 +3516,32 @@ Reader.prototype.raw = function read_raw(start, end) {
3474
3516
  return this.buf.subarray(start, end);
3475
3517
  };
3476
3518
 
3519
+ function readVarint32NearEnd(reader) {
3520
+ // Safely read up to four bytes of a varint32 near the reader limit
3521
+ var value = 0;
3522
+ for (var i = 0; i < 4; ++i) {
3523
+ if (reader.pos >= reader.len)
3524
+ throw indexOutOfRange(reader);
3525
+ var b = reader.buf[reader.pos++];
3526
+ value = (value | (b & 127) << i * 7) >>> 0;
3527
+ if (b < 128)
3528
+ return value;
3529
+ }
3530
+ throw indexOutOfRange(reader);
3531
+ }
3532
+
3477
3533
  /**
3478
3534
  * Reads a varint as an unsigned 32 bit value.
3479
3535
  * @function
3480
3536
  * @returns {number} Value read
3481
3537
  */
3482
3538
  Reader.prototype.uint32 = function read_uint32() {
3539
+ if (this.len - this.pos < 5) {
3540
+ if (this.pos >= this.len)
3541
+ throw indexOutOfRange(this);
3542
+ if (this.buf[this.pos] >= 128)
3543
+ return readVarint32NearEnd(this);
3544
+ }
3483
3545
  var buf = this.buf,
3484
3546
  pos = this.pos,
3485
3547
  value = (buf[pos] & 127) >>> 0;
@@ -3530,6 +3592,12 @@ Reader.prototype.uint32 = function read_uint32() {
3530
3592
  * @returns {number} Tag read
3531
3593
  */
3532
3594
  Reader.prototype.tag = function read_tag() {
3595
+ if (this.len - this.pos < 5) {
3596
+ if (this.pos >= this.len)
3597
+ throw indexOutOfRange(this);
3598
+ if (this.buf[this.pos] >= 128)
3599
+ return readVarint32NearEnd(this);
3600
+ }
3533
3601
  var buf = this.buf,
3534
3602
  pos = this.pos,
3535
3603
  value = (buf[pos] & 127) >>> 0;
@@ -3775,7 +3843,9 @@ Reader.prototype.double = function read_double() {
3775
3843
  */
3776
3844
  Reader.prototype.uint32s = function read_uint32s(array) {
3777
3845
  if (array === undefined) array = [];
3778
- var end = this.uint32() + this.pos, buf = this.buf, pos = this.pos, value;
3846
+ var end = this.uint32() + this.pos, len = this.len, buf = this.buf, pos = this.pos, value;
3847
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
3848
+ this.len = end;
3779
3849
  while (pos < end) {
3780
3850
  value = buf[pos++];
3781
3851
  if (value < 128)
@@ -3787,6 +3857,8 @@ Reader.prototype.uint32s = function read_uint32s(array) {
3787
3857
  }
3788
3858
  }
3789
3859
  this.pos = pos;
3860
+ if (pos !== end) throw RangeError("index out of range");
3861
+ this.len = len;
3790
3862
  return array;
3791
3863
  };
3792
3864
 
@@ -3797,7 +3869,9 @@ Reader.prototype.uint32s = function read_uint32s(array) {
3797
3869
  */
3798
3870
  Reader.prototype.int32s = function read_int32s(array) {
3799
3871
  if (array === undefined) array = [];
3800
- var end = this.uint32() + this.pos, buf = this.buf, pos = this.pos, value;
3872
+ var end = this.uint32() + this.pos, len = this.len, buf = this.buf, pos = this.pos, value;
3873
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
3874
+ this.len = end;
3801
3875
  while (pos < end) {
3802
3876
  value = buf[pos++];
3803
3877
  if (value < 128)
@@ -3809,6 +3883,8 @@ Reader.prototype.int32s = function read_int32s(array) {
3809
3883
  }
3810
3884
  }
3811
3885
  this.pos = pos;
3886
+ if (pos !== end) throw RangeError("index out of range");
3887
+ this.len = len;
3812
3888
  return array;
3813
3889
  };
3814
3890
 
@@ -3819,9 +3895,13 @@ Reader.prototype.int32s = function read_int32s(array) {
3819
3895
  */
3820
3896
  Reader.prototype.sint32s = function read_sint32s(array) {
3821
3897
  if (array === undefined) array = [];
3822
- var end = this.uint32() + this.pos;
3898
+ var end = this.uint32() + this.pos, len = this.len;
3899
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
3900
+ this.len = end;
3823
3901
  while (this.pos < end)
3824
3902
  array.push(this.sint32());
3903
+ if (this.pos !== end) throw RangeError("index out of range");
3904
+ this.len = len;
3825
3905
  return array;
3826
3906
  };
3827
3907
 
@@ -3832,7 +3912,9 @@ Reader.prototype.sint32s = function read_sint32s(array) {
3832
3912
  */
3833
3913
  Reader.prototype.bools = function read_bools(array) {
3834
3914
  if (array === undefined) array = [];
3835
- var end = this.uint32() + this.pos, buf = this.buf, pos = this.pos, value;
3915
+ var end = this.uint32() + this.pos, len = this.len, buf = this.buf, pos = this.pos, value;
3916
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
3917
+ this.len = end;
3836
3918
  while (pos < end) {
3837
3919
  value = buf[pos++];
3838
3920
  if (value < 128)
@@ -3844,6 +3926,8 @@ Reader.prototype.bools = function read_bools(array) {
3844
3926
  }
3845
3927
  }
3846
3928
  this.pos = pos;
3929
+ if (pos !== end) throw RangeError("index out of range");
3930
+ this.len = len;
3847
3931
  return array;
3848
3932
  };
3849
3933
 
@@ -3962,9 +4046,13 @@ Reader.prototype.doubles = function read_doubles(array) {
3962
4046
  */
3963
4047
  Reader.prototype.uint64s = function read_uint64s(array) {
3964
4048
  if (array === undefined) array = [];
3965
- var end = this.uint32() + this.pos;
4049
+ var end = this.uint32() + this.pos, len = this.len;
4050
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
4051
+ this.len = end;
3966
4052
  while (this.pos < end)
3967
4053
  array.push(this.uint64());
4054
+ if (this.pos !== end) throw RangeError("index out of range");
4055
+ this.len = len;
3968
4056
  return array;
3969
4057
  };
3970
4058
 
@@ -3975,9 +4063,13 @@ Reader.prototype.uint64s = function read_uint64s(array) {
3975
4063
  */
3976
4064
  Reader.prototype.int64s = function read_int64s(array) {
3977
4065
  if (array === undefined) array = [];
3978
- var end = this.uint32() + this.pos;
4066
+ var end = this.uint32() + this.pos, len = this.len;
4067
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
4068
+ this.len = end;
3979
4069
  while (this.pos < end)
3980
4070
  array.push(this.int64());
4071
+ if (this.pos !== end) throw RangeError("index out of range");
4072
+ this.len = len;
3981
4073
  return array;
3982
4074
  };
3983
4075
 
@@ -3988,9 +4080,13 @@ Reader.prototype.int64s = function read_int64s(array) {
3988
4080
  */
3989
4081
  Reader.prototype.sint64s = function read_sint64s(array) {
3990
4082
  if (array === undefined) array = [];
3991
- var end = this.uint32() + this.pos;
4083
+ var end = this.uint32() + this.pos, len = this.len;
4084
+ if (end > len) throw indexOutOfRange(this, end - this.pos);
4085
+ this.len = end;
3992
4086
  while (this.pos < end)
3993
4087
  array.push(this.sint64());
4088
+ if (this.pos !== end) throw RangeError("index out of range");
4089
+ this.len = len;
3994
4090
  return array;
3995
4091
  };
3996
4092
 
@@ -5195,6 +5291,12 @@ function Type(name, options) {
5195
5291
  */
5196
5292
  this.group = undefined; // toJSON
5197
5293
 
5294
+ /**
5295
+ * Declared symbol visibility, if any.
5296
+ * @type {"local"|"export"|undefined}
5297
+ */
5298
+ this.visibility = undefined; // toJSON
5299
+
5198
5300
  /**
5199
5301
  * Cached fields by id.
5200
5302
  * @type {Object.<number,Field>|null}
@@ -5379,6 +5481,7 @@ function clearCache(type) {
5379
5481
  * @property {number[][]} [extensions] Extension ranges
5380
5482
  * @property {Array.<number[]|string>} [reserved] Reserved ranges
5381
5483
  * @property {boolean} [group=false] Whether a legacy group or not
5484
+ * @property {"local"|"export"} [visibility] Declared symbol visibility
5382
5485
  * @property {string|null} [comment] Message type comment
5383
5486
  */
5384
5487
 
@@ -5429,6 +5532,8 @@ Type.fromJSON = function fromJSON(name, json, depth) {
5429
5532
  type.reserved = json.reserved;
5430
5533
  if (json.group)
5431
5534
  type.group = true;
5535
+ if (json.visibility)
5536
+ type.visibility = json.visibility;
5432
5537
  if (json.comment)
5433
5538
  type.comment = json.comment;
5434
5539
  if (json.edition)
@@ -5453,6 +5558,7 @@ Type.prototype.toJSON = function toJSON(toJSONOptions) {
5453
5558
  "extensions" , this.extensions && this.extensions.length ? this.extensions : undefined,
5454
5559
  "reserved" , this.reserved && this.reserved.length ? this.reserved : undefined,
5455
5560
  "group" , this.group || undefined,
5561
+ "visibility" , this.visibility,
5456
5562
  "nested" , inherited && inherited.nested || undefined,
5457
5563
  "comment" , keepComments ? this.comment : undefined
5458
5564
  ]);
@@ -8416,6 +8522,10 @@ var Message = require(10),
8416
8522
  wrappers[".google.protobuf.Any"] = {
8417
8523
 
8418
8524
  fromObject: function(object, depth) {
8525
+ if (depth === undefined)
8526
+ depth = 0;
8527
+ if (depth > util.recursionLimit)
8528
+ throw Error("max depth exceeded");
8419
8529
 
8420
8530
  // unwrap value type if mapped
8421
8531
  if (object && object["@type"]) {
@@ -8433,7 +8543,7 @@ wrappers[".google.protobuf.Any"] = {
8433
8543
  }
8434
8544
  return this.create({
8435
8545
  type_url: type_url,
8436
- value: type.encode(type.fromObject(object, depth === undefined ? 1 : depth + 1)).finish()
8546
+ value: type.encode(type.fromObject(object, depth + 1)).finish()
8437
8547
  });
8438
8548
  }
8439
8549
  }