protobufjs 8.3.0 → 8.4.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.
package/index.d.ts CHANGED
@@ -340,6 +340,9 @@ export class FieldBase extends ReflectionObject {
340
340
  */
341
341
  constructor(name: string, id: number, type: string, rule?: (string|{ [k: string]: any }), extend?: (string|{ [k: string]: any }), options?: { [k: string]: any }, comment?: string);
342
342
 
343
+ /** Field rule, if any. */
344
+ rule?: string;
345
+
343
346
  /** Field type. */
344
347
  type: string;
345
348
 
@@ -578,7 +581,7 @@ export class Message<T extends object = object> {
578
581
  * @param [properties] Properties to set
579
582
  * @returns Message instance
580
583
  */
581
- static create<T extends Message<T>>(this: Constructor<T>, properties?: { [k: string]: any }): Message<T>;
584
+ static create<T extends Message<T>>(this: Constructor<T>, properties?: { [k: string]: any }): T;
582
585
 
583
586
  /**
584
587
  * Encodes a message of this type.
@@ -1740,7 +1743,7 @@ export class Type extends NamespaceBase {
1740
1743
  * @param [properties] Properties to set
1741
1744
  * @returns Message instance
1742
1745
  */
1743
- create(properties?: { [k: string]: any }): Message<{}>;
1746
+ create(properties?: { [k: string]: any }): ReflectedMessage;
1744
1747
 
1745
1748
  /**
1746
1749
  * Sets up {@link Type#encode|encode}, {@link Type#decode|decode} and {@link Type#verify|verify}.
@@ -1772,7 +1775,7 @@ export class Type extends NamespaceBase {
1772
1775
  * @throws {Error} If the payload is not a reader or valid buffer
1773
1776
  * @throws {util.ProtocolError<{}>} If required fields are missing
1774
1777
  */
1775
- decode(reader: (Reader|Uint8Array), length?: number): Message<{}>;
1778
+ decode(reader: (Reader|Uint8Array), length?: number): ReflectedMessage;
1776
1779
 
1777
1780
  /**
1778
1781
  * Decodes a message of this type preceeded by its byte length as a varint.
@@ -1781,7 +1784,7 @@ export class Type extends NamespaceBase {
1781
1784
  * @throws {Error} If the payload is not a reader or valid buffer
1782
1785
  * @throws {util.ProtocolError} If required fields are missing
1783
1786
  */
1784
- decodeDelimited(reader: (Reader|Uint8Array)): Message<{}>;
1787
+ decodeDelimited(reader: (Reader|Uint8Array)): ReflectedMessage;
1785
1788
 
1786
1789
  /**
1787
1790
  * Verifies that field values are valid and that required fields are present.
@@ -1795,7 +1798,7 @@ export class Type extends NamespaceBase {
1795
1798
  * @param object Plain object to convert
1796
1799
  * @returns Message instance
1797
1800
  */
1798
- fromObject(object: { [k: string]: any }): Message<{}>;
1801
+ fromObject(object: { [k: string]: any }): ReflectedMessage;
1799
1802
 
1800
1803
  /**
1801
1804
  * Creates a plain object from a message of this type. Also converts values to other types if specified.
@@ -1851,7 +1854,7 @@ export interface IConversionOptions {
1851
1854
 
1852
1855
  /**
1853
1856
  * Long conversion type.
1854
- * Valid values are `String` and `Number` (the global types).
1857
+ * Valid values are `BigInt`, `String` and `Number` (the global types).
1855
1858
  * Defaults to copy the present value, which is a possibly unsafe number without and a {@link Long} with a long library.
1856
1859
  */
1857
1860
  longs?: Function;
@@ -1984,6 +1987,9 @@ export type Constructor<T> = Function & { new(...params: any[]): T; prototype: T
1984
1987
  /** Properties type. */
1985
1988
  export type Properties<T> = { [P in keyof T]?: T[P] };
1986
1989
 
1990
+ /** Dynamically reflected message type. */
1991
+ export type ReflectedMessage = Message<{}> & { [k: string]: any };
1992
+
1987
1993
  /**
1988
1994
  * Callback as used by {@link util.asPromise}.
1989
1995
  * @param error Error, if any
@@ -2356,6 +2362,13 @@ export namespace util {
2356
2362
  length(): number;
2357
2363
  }
2358
2364
 
2365
+ /**
2366
+ * Tests if the specified key can affect object prototypes.
2367
+ * @param key Key to test
2368
+ * @returns `true` if the key is unsafe
2369
+ */
2370
+ function isUnsafeProperty(key: string): boolean;
2371
+
2359
2372
  /** Whether running within node or not. */
2360
2373
  let isNode: boolean;
2361
2374
 
@@ -2464,11 +2477,10 @@ export namespace util {
2464
2477
  /**
2465
2478
  * Merges the properties of the source object into the destination object.
2466
2479
  * @param dst Destination object
2467
- * @param src Source object
2468
- * @param [ifNotSet=false] Merges only if the key is not already set
2480
+ * @param src Source objects, optionally followed by an `ifNotSet` flag
2469
2481
  * @returns Destination object
2470
2482
  */
2471
- function merge(dst: { [k: string]: any }, src: { [k: string]: any }, ifNotSet?: boolean): { [k: string]: any };
2483
+ function merge(dst: { [k: string]: any }, ...src: any[]): { [k: string]: any };
2472
2484
 
2473
2485
  /** Schema declaration nesting limit. */
2474
2486
  let nestingLimit: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "protobufjs",
3
- "version": "8.3.0",
3
+ "version": "8.4.1",
4
4
  "versionScheme": "~",
5
5
  "description": "Protocol Buffers for JavaScript & TypeScript.",
6
6
  "author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
@@ -46,7 +46,7 @@
46
46
  "make": "npm run lint:sources && npm run build && npm run lint:types && node ./scripts/gentests.js && npm test"
47
47
  },
48
48
  "dependencies": {
49
- "long": "^5.0.0"
49
+ "long": "^5.3.2"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@eslint/js": "^10.0.0",
package/src/converter.js CHANGED
@@ -62,14 +62,14 @@ function genValuePartial_fromObject(gen, field, fieldIndex, prop) {
62
62
  ("m%s=d%s|0", prop, prop);
63
63
  break;
64
64
  case "uint64":
65
+ case "fixed64":
65
66
  isUnsigned = true;
66
67
  // eslint-disable-next-line no-fallthrough
67
68
  case "int64":
68
69
  case "sint64":
69
- case "fixed64":
70
70
  case "sfixed64": gen
71
71
  ("if(util.Long)")
72
- ("(m%s=util.Long.fromValue(d%s)).unsigned=%j", prop, prop, isUnsigned)
72
+ ("m%s=util.Long.fromValue(d%s,%j)", prop, prop, isUnsigned)
73
73
  ("else if(typeof d%s===\"string\")", prop)
74
74
  ("m%s=parseInt(d%s,10)", prop, prop)
75
75
  ("else if(typeof d%s===\"number\")", prop)
@@ -194,7 +194,7 @@ function genValuePartial_toObject(gen, field, fieldIndex, dstProp, srcProp) {
194
194
  if (field.resolvedType instanceof Enum) gen
195
195
  ("d%s=o.enums===String?(types[%i].values[m%s]===undefined?m%s:types[%i].values[m%s]):m%s", dstProp, fieldIndex, srcProp, srcProp, fieldIndex, srcProp, srcProp);
196
196
  else gen
197
- ("d%s=types[%i].toObject(m%s,o)", dstProp, fieldIndex, srcProp);
197
+ ("d%s=types[%i].toObject(m%s,o,q+1)", dstProp, fieldIndex, srcProp);
198
198
  } else {
199
199
  var isUnsigned = false;
200
200
  switch (field.type) {
@@ -203,13 +203,15 @@ function genValuePartial_toObject(gen, field, fieldIndex, dstProp, srcProp) {
203
203
  ("d%s=o.json&&!isFinite(m%s)?String(m%s):m%s", dstProp, srcProp, srcProp, srcProp);
204
204
  break;
205
205
  case "uint64":
206
+ case "fixed64":
206
207
  isUnsigned = true;
207
208
  // eslint-disable-next-line no-fallthrough
208
209
  case "int64":
209
210
  case "sint64":
210
- case "fixed64":
211
211
  case "sfixed64": gen
212
- ("if(typeof m%s===\"number\")", srcProp)
212
+ ("if(typeof BigInt!==\"undefined\"&&o.longs===BigInt)")
213
+ ("d%s=typeof m%s===\"number\"?BigInt(m%s):util.Long.fromBits(m%s.low>>>0,m%s.high>>>0,%j).toBigInt()", dstProp, srcProp, srcProp, srcProp, srcProp, isUnsigned)
214
+ ("else if(typeof m%s===\"number\")", srcProp)
213
215
  ("d%s=o.longs===String?String(m%s):m%s", dstProp, srcProp, srcProp)
214
216
  ("else") // Long-like
215
217
  ("d%s=o.longs===String?util.Long.prototype.toString.call(m%s):o.longs===Number?new util.LongBits(m%s.low>>>0,m%s.high>>>0).toNumber(%s):m%s", dstProp, srcProp, srcProp, srcProp, isUnsigned ? "true": "", srcProp);
@@ -236,9 +238,12 @@ converter.toObject = function toObject(mtype) {
236
238
  var fields = mtype.fieldsArray.slice().sort(util.compareFieldsById);
237
239
  if (!fields.length)
238
240
  return util.codegen()("return {}");
239
- var gen = util.codegen(["m", "o"], mtype.name + "$toObject")
241
+ var gen = util.codegen(["m", "o", "q"], mtype.name + "$toObject")
240
242
  ("if(!o)")
241
243
  ("o={}")
244
+ ("if(q===undefined)q=0")
245
+ ("if(q>util.recursionLimit)")
246
+ ("throw Error(\"max depth exceeded\")")
242
247
  ("var d={}");
243
248
 
244
249
  var repeatedFields = [],
@@ -277,9 +282,9 @@ converter.toObject = function toObject(mtype) {
277
282
  else if (field.long) gen
278
283
  ("if(util.Long){")
279
284
  ("var n=new util.Long(%i,%i,%j)", field.typeDefault.low, field.typeDefault.high, field.typeDefault.unsigned)
280
- ("d%s=o.longs===String?n.toString():o.longs===Number?n.toNumber():n", prop)
285
+ ("d%s=o.longs===String?n.toString():o.longs===Number?n.toNumber():typeof BigInt!==\"undefined\"&&o.longs===BigInt?n.toBigInt():n", prop)
281
286
  ("}else")
282
- ("d%s=o.longs===String?%j:%i", prop, field.typeDefault.toString(), field.typeDefault.toNumber());
287
+ ("d%s=o.longs===String?%j:typeof BigInt!==\"undefined\"&&o.longs===BigInt?BigInt(%j):%i", prop, field.typeDefault.toString(), field.typeDefault.toString(), field.typeDefault.toNumber());
283
288
  else if (field.bytes) {
284
289
  var arrayDefault = Array.prototype.slice.call(field.typeDefault);
285
290
  gen
@@ -324,7 +329,7 @@ converter.toObject = function toObject(mtype) {
324
329
  } else { gen
325
330
  ("if(m%s!=null&&m.hasOwnProperty(%j)){", prop, field.name); // !== undefined && !== null
326
331
  genValuePartial_toObject(gen, field, /* sorted */ index, prop);
327
- if (field.partOf) gen
332
+ if (field.partOf && !field.partOf.isProto3Optional) gen
328
333
  ("if(o.oneofs)")
329
334
  ("d%s=%j", util.safeProp(field.partOf.name), field.name);
330
335
  }
package/src/decoder.js CHANGED
@@ -63,7 +63,9 @@ function decoder(mtype) {
63
63
  else gen
64
64
  ("k=null");
65
65
 
66
- if (types.defaults[type] !== undefined) gen
66
+ if (types.long[type] !== undefined) gen
67
+ ("v=util.Long?util.Long.fromNumber(0,%j):0", type === "uint64" || type === "fixed64");
68
+ else if (types.defaults[type] !== undefined) gen
67
69
  ("v=%j", types.defaults[type]);
68
70
  else gen
69
71
  ("v=null");
package/src/encoder.js CHANGED
@@ -16,8 +16,8 @@ var Enum = require("./enum"),
16
16
  */
17
17
  function genTypePartial(gen, field, fieldIndex, ref) {
18
18
  return field.delimited
19
- ? gen("types[%i].encode(%s,w.uint32(%i)).uint32(%i)", fieldIndex, ref, (field.id << 3 | 3) >>> 0, (field.id << 3 | 4) >>> 0)
20
- : gen("types[%i].encode(%s,w.uint32(%i).fork()).ldelim()", fieldIndex, ref, (field.id << 3 | 2) >>> 0);
19
+ ? gen("types[%i].encode(%s,w.uint32(%i),q+1).uint32(%i)", fieldIndex, ref, (field.id << 3 | 3) >>> 0, (field.id << 3 | 4) >>> 0)
20
+ : gen("types[%i].encode(%s,w.uint32(%i).fork(),q+1).ldelim()", fieldIndex, ref, (field.id << 3 | 2) >>> 0);
21
21
  }
22
22
 
23
23
  /**
@@ -27,9 +27,12 @@ function genTypePartial(gen, field, fieldIndex, ref) {
27
27
  */
28
28
  function encoder(mtype) {
29
29
  /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
30
- var gen = util.codegen(["m", "w"], mtype.name + "$encode")
30
+ var gen = util.codegen(["m", "w", "q"], mtype.name + "$encode")
31
31
  ("if(!w)")
32
- ("w=Writer.create()");
32
+ ("w=Writer.create()")
33
+ ("if(q===undefined)q=0")
34
+ ("if(q>util.recursionLimit)")
35
+ ("throw Error(\"max depth exceeded\")");
33
36
 
34
37
  var i, ref;
35
38
 
@@ -55,7 +58,7 @@ function encoder(mtype) {
55
58
  else gen
56
59
  ("w.uint32(%i).fork().uint32(%i).%s(ks[i])", (field.id << 3 | 2) >>> 0, 8 | types.mapKey[field.keyType], field.keyType);
57
60
  if (wireType === undefined) gen
58
- ("types[%i].encode(%s[ks[i]],w.uint32(18).fork()).ldelim().ldelim()", index, ref); // can't be groups
61
+ ("types[%i].encode(%s[ks[i]],w.uint32(18).fork(),q+1).ldelim().ldelim()", index, ref); // can't be groups
59
62
  else gen
60
63
  (".uint32(%i).%s(%s[ks[i]]).ldelim()", 16 | wireType, type, ref);
61
64
  gen
package/src/enum.js CHANGED
@@ -86,8 +86,8 @@ Enum.prototype._resolveFeatures = function _resolveFeatures(edition) {
86
86
  ReflectionObject.prototype._resolveFeatures.call(this, edition);
87
87
 
88
88
  Object.keys(this.values).forEach(key => {
89
- var parentFeaturesCopy = Object.assign({}, this._features);
90
- this._valuesFeatures[key] = Object.assign(parentFeaturesCopy, this.valuesOptions && this.valuesOptions[key] && this.valuesOptions[key].features);
89
+ var parentFeaturesCopy = util.merge({}, this._features);
90
+ this._valuesFeatures[key] = util.merge(parentFeaturesCopy, this.valuesOptions && this.valuesOptions[key] && this.valuesOptions[key].features || {});
91
91
  });
92
92
 
93
93
  return this;
package/src/field.js CHANGED
@@ -11,7 +11,7 @@ var Enum = require("./enum"),
11
11
 
12
12
  var Type; // cyclic
13
13
 
14
- var ruleRe = /^required|optional|repeated$/;
14
+ var ruleRe = /^(?:required|optional|repeated)$/;
15
15
 
16
16
  /**
17
17
  * Constructs a new message field instance. Note that {@link MapField|map fields} have their own class.
@@ -86,9 +86,6 @@ function Field(name, id, type, rule, extend, options, comment) {
86
86
  * Field rule, if any.
87
87
  * @type {string|undefined}
88
88
  */
89
- if (rule === "proto3_optional") {
90
- rule = "optional";
91
- }
92
89
  this.rule = rule && rule !== "optional" ? rule : undefined; // toJSON
93
90
 
94
91
  /**
@@ -330,7 +327,7 @@ Field.prototype.resolve = function resolve() {
330
327
 
331
328
  // convert to internal data type if necesssary
332
329
  if (this.long) {
333
- this.typeDefault = util.Long.fromNumber(this.typeDefault, this.type.charAt(0) === "u");
330
+ this.typeDefault = util.Long.fromNumber(this.typeDefault, this.type === "uint64" || this.type === "fixed64");
334
331
 
335
332
  /* istanbul ignore else */
336
333
  if (Object.freeze)
@@ -100,5 +100,5 @@ protobuf.util = require("./util");
100
100
  // Set up possibly cyclic reflection dependencies
101
101
  protobuf.ReflectionObject._configure(protobuf.Root);
102
102
  protobuf.Namespace._configure(protobuf.Type, protobuf.Service, protobuf.Enum);
103
- protobuf.Root._configure(protobuf.Type);
103
+ protobuf.Root._configure(protobuf.Type, undefined, {});
104
104
  protobuf.Field._configure(protobuf.Type);
package/src/message.js CHANGED
@@ -36,7 +36,7 @@ function Message(properties) {
36
36
  /**
37
37
  * Creates a new message of this type using the specified properties.
38
38
  * @param {Object.<string,*>} [properties] Properties to set
39
- * @returns {Message<T>} Message instance
39
+ * @returns {T} Message instance
40
40
  * @template T extends Message<T>
41
41
  * @this Constructor<T>
42
42
  */
package/src/object.js CHANGED
@@ -213,7 +213,7 @@ ReflectionObject.prototype._resolveFeatures = function _resolveFeatures(edition)
213
213
  throw new Error("Unknown edition for " + this.fullName);
214
214
  }
215
215
 
216
- var protoFeatures = Object.assign(this.options ? Object.assign({}, this.options.features) : {},
216
+ var protoFeatures = util.merge({}, this.options && this.options.features,
217
217
  this._inferLegacyProtoFeatures(edition));
218
218
 
219
219
  if (this._edition) {
@@ -230,19 +230,19 @@ ReflectionObject.prototype._resolveFeatures = function _resolveFeatures(edition)
230
230
  } else {
231
231
  throw new Error("Unknown edition: " + edition);
232
232
  }
233
- this._features = Object.assign(defaults, protoFeatures || {});
233
+ this._features = util.merge(defaults, protoFeatures);
234
234
  } else {
235
235
  // fields in Oneofs aren't actually children of them, so we have to
236
236
  // special-case it
237
237
  /* istanbul ignore else */
238
238
  if (this.partOf instanceof OneOf) {
239
- var lexicalParentFeaturesCopy = Object.assign({}, this.partOf._features);
240
- this._features = Object.assign(lexicalParentFeaturesCopy, protoFeatures || {});
239
+ var lexicalParentFeaturesCopy = util.merge({}, this.partOf._features);
240
+ this._features = util.merge(lexicalParentFeaturesCopy, protoFeatures);
241
241
  } else if (this.declaringField) {
242
242
  // Skip feature resolution of sister fields.
243
243
  } else if (this.parent) {
244
- var parentFeaturesCopy = Object.assign({}, this.parent._features);
245
- this._features = Object.assign(parentFeaturesCopy, protoFeatures || {});
244
+ var parentFeaturesCopy = util.merge({}, this.parent._features);
245
+ this._features = util.merge(parentFeaturesCopy, protoFeatures);
246
246
  } else {
247
247
  throw new Error("Unable to find a parent for " + this.fullName);
248
248
  }
package/src/parse.js CHANGED
@@ -482,7 +482,7 @@ function parse(source, root, options) {
482
482
  name = applyCase(name);
483
483
  skip("=");
484
484
 
485
- var field = new Field(name, parseId(next()), type, rule, extend);
485
+ var field = new Field(name, parseId(next()), type, rule === "proto3_optional" ? "optional" : rule, extend);
486
486
 
487
487
  ifBlock(field, function parseField_block(token) {
488
488
 
package/src/root.js CHANGED
@@ -142,8 +142,12 @@ Root.prototype.load = function load(filename, options, callback) {
142
142
  }
143
143
 
144
144
  // Processes a single file
145
- function process(filename, source) {
145
+ function process(filename, source, depth) {
146
+ if (depth === undefined)
147
+ depth = 0;
146
148
  try {
149
+ if (depth > util.recursionLimit)
150
+ throw Error("max depth exceeded");
147
151
  if (util.isString(source) && source.charAt(0) === "{")
148
152
  source = JSON.parse(source);
149
153
  if (!util.isString(source))
@@ -156,11 +160,11 @@ Root.prototype.load = function load(filename, options, callback) {
156
160
  if (parsed.imports)
157
161
  for (; i < parsed.imports.length; ++i)
158
162
  if (resolved = getBundledFileName(parsed.imports[i]) || self.resolvePath(filename, parsed.imports[i]))
159
- fetch(resolved);
163
+ fetch(resolved, false, depth + 1);
160
164
  if (parsed.weakImports)
161
165
  for (i = 0; i < parsed.weakImports.length; ++i)
162
166
  if (resolved = getBundledFileName(parsed.weakImports[i]) || self.resolvePath(filename, parsed.weakImports[i]))
163
- fetch(resolved, true);
167
+ fetch(resolved, true, depth + 1);
164
168
  }
165
169
  } catch (err) {
166
170
  finish(err);
@@ -171,7 +175,9 @@ Root.prototype.load = function load(filename, options, callback) {
171
175
  }
172
176
 
173
177
  // Fetches a single file
174
- function fetch(filename, weak) {
178
+ function fetch(filename, weak, depth) {
179
+ if (depth === undefined)
180
+ depth = 0;
175
181
  filename = getBundledFileName(filename) || filename;
176
182
 
177
183
  // Skip if already loaded / attempted
@@ -183,12 +189,12 @@ Root.prototype.load = function load(filename, options, callback) {
183
189
  // Shortcut bundled definitions
184
190
  if (Object.prototype.hasOwnProperty.call(common, filename)) {
185
191
  if (sync) {
186
- process(filename, common[filename]);
192
+ process(filename, common[filename], depth);
187
193
  } else {
188
194
  ++queued;
189
195
  setTimeout(function() {
190
196
  --queued;
191
- process(filename, common[filename]);
197
+ process(filename, common[filename], depth);
192
198
  });
193
199
  }
194
200
  return;
@@ -204,7 +210,7 @@ Root.prototype.load = function load(filename, options, callback) {
204
210
  finish(err);
205
211
  return;
206
212
  }
207
- process(filename, source);
213
+ process(filename, source, depth);
208
214
  } else {
209
215
  ++queued;
210
216
  self.fetch(filename, function(err, source) {
@@ -221,7 +227,7 @@ Root.prototype.load = function load(filename, options, callback) {
221
227
  finish(null, self);
222
228
  return;
223
229
  }
224
- process(filename, source);
230
+ process(filename, source, depth);
225
231
  });
226
232
  }
227
233
  }
package/src/type.js CHANGED
@@ -458,7 +458,7 @@ Type.prototype.isReservedName = function isReservedName(name) {
458
458
  /**
459
459
  * Creates a new message of this type using the specified properties.
460
460
  * @param {Object.<string,*>} [properties] Properties to set
461
- * @returns {Message<{}>} Message instance
461
+ * @returns {ReflectedMessage} Message instance
462
462
  */
463
463
  Type.prototype.create = function create(properties) {
464
464
  return new this.ctor(properties);
@@ -524,8 +524,8 @@ Type.prototype.setup = function setup() {
524
524
  * @param {Writer} [writer] Writer to encode to
525
525
  * @returns {Writer} writer
526
526
  */
527
- Type.prototype.encode = function encode_setup(message, writer) {
528
- return this.setup().encode(message, writer); // overrides this method
527
+ Type.prototype.encode = function encode_setup(message, writer) { // eslint-disable-line no-unused-vars
528
+ return this.setup().encode.apply(this, arguments); // overrides this method
529
529
  };
530
530
 
531
531
  /**
@@ -542,7 +542,7 @@ Type.prototype.encodeDelimited = function encodeDelimited(message, writer) {
542
542
  * Decodes a message of this type.
543
543
  * @param {Reader|Uint8Array} reader Reader or buffer to decode from
544
544
  * @param {number} [length] Length of the message, if known beforehand
545
- * @returns {Message<{}>} Decoded message
545
+ * @returns {ReflectedMessage} Decoded message
546
546
  * @throws {Error} If the payload is not a reader or valid buffer
547
547
  * @throws {util.ProtocolError<{}>} If required fields are missing
548
548
  */
@@ -553,7 +553,7 @@ Type.prototype.decode = function decode_setup(reader, length) { // eslint-disabl
553
553
  /**
554
554
  * Decodes a message of this type preceeded by its byte length as a varint.
555
555
  * @param {Reader|Uint8Array} reader Reader or buffer to decode from
556
- * @returns {Message<{}>} Decoded message
556
+ * @returns {ReflectedMessage} Decoded message
557
557
  * @throws {Error} If the payload is not a reader or valid buffer
558
558
  * @throws {util.ProtocolError} If required fields are missing
559
559
  */
@@ -575,7 +575,7 @@ Type.prototype.verify = function verify_setup(message) { // eslint-disable-line
575
575
  /**
576
576
  * Creates a new message of this type from a plain object. Also converts values to their respective internal types.
577
577
  * @param {Object.<string,*>} object Plain object to convert
578
- * @returns {Message<{}>} Message instance
578
+ * @returns {ReflectedMessage} Message instance
579
579
  */
580
580
  Type.prototype.fromObject = function fromObject(object) { // eslint-disable-line no-unused-vars
581
581
  return this.setup().fromObject.apply(this, arguments);
@@ -585,7 +585,7 @@ Type.prototype.fromObject = function fromObject(object) { // eslint-disable-line
585
585
  * Conversion options as used by {@link Type#toObject} and {@link Message.toObject}.
586
586
  * @interface IConversionOptions
587
587
  * @property {Function} [longs] Long conversion type.
588
- * Valid values are `String` and `Number` (the global types).
588
+ * Valid values are `BigInt`, `String` and `Number` (the global types).
589
589
  * Defaults to copy the present value, which is a possibly unsafe number without and a {@link Long} with a long library.
590
590
  * @property {Function} [enums] Enum value conversion type.
591
591
  * Only valid value is `String` (the global type).
@@ -606,8 +606,8 @@ Type.prototype.fromObject = function fromObject(object) { // eslint-disable-line
606
606
  * @param {IConversionOptions} [options] Conversion options
607
607
  * @returns {Object.<string,*>} Plain object
608
608
  */
609
- Type.prototype.toObject = function toObject(message, options) {
610
- return this.setup().toObject(message, options);
609
+ Type.prototype.toObject = function toObject(message, options) { // eslint-disable-line no-unused-vars
610
+ return this.setup().toObject.apply(this, arguments);
611
611
  };
612
612
 
613
613
  /**
package/src/typescript.js CHANGED
@@ -17,3 +17,9 @@ var Constructor;
17
17
  * @typedef {{ [P in keyof T]?: T[P] }} Properties
18
18
  */
19
19
  var Properties;
20
+
21
+ /**
22
+ * Dynamically reflected message type.
23
+ * @typedef {Message<{}> & { [k: string]: any }} ReflectedMessage
24
+ */
25
+ var ReflectedMessage;
@@ -14,7 +14,7 @@ function EventEmitter() {
14
14
  * @type {Object.<string,*>}
15
15
  * @private
16
16
  */
17
- this._listeners = {};
17
+ this._listeners = Object.create(null);
18
18
  }
19
19
 
20
20
  /**
@@ -48,12 +48,14 @@ EventEmitter.prototype.on = function on(evt, fn, ctx) {
48
48
  */
49
49
  EventEmitter.prototype.off = function off(evt, fn) {
50
50
  if (evt === undefined)
51
- this._listeners = {};
51
+ this._listeners = Object.create(null);
52
52
  else {
53
53
  if (fn === undefined)
54
54
  this._listeners[evt] = [];
55
55
  else {
56
56
  var listeners = this._listeners[evt];
57
+ if (!listeners)
58
+ return this;
57
59
  for (var i = 0; i < listeners.length;)
58
60
  if (listeners[i].fn === fn)
59
61
  listeners.splice(i, 1);
@@ -25,6 +25,18 @@ util.pool = require("./pool");
25
25
  // utility to work with the low and high bits of a 64 bit value
26
26
  util.LongBits = require("./longbits");
27
27
 
28
+ /**
29
+ * Tests if the specified key can affect object prototypes.
30
+ * @memberof util
31
+ * @param {string} key Key to test
32
+ * @returns {boolean} `true` if the key is unsafe
33
+ */
34
+ function isUnsafeProperty(key) {
35
+ return key === "__proto__" || key === "prototype" || key === "constructor";
36
+ }
37
+
38
+ util.isUnsafeProperty = isUnsafeProperty;
39
+
28
40
  /**
29
41
  * Whether running within node or not.
30
42
  * @memberof util
@@ -259,15 +271,21 @@ util.boolFromKey = function boolFromKey(key) {
259
271
  * Merges the properties of the source object into the destination object.
260
272
  * @memberof util
261
273
  * @param {Object.<string,*>} dst Destination object
262
- * @param {Object.<string,*>} src Source object
263
- * @param {boolean} [ifNotSet=false] Merges only if the key is not already set
274
+ * @param {...(Object.<string,*>|boolean)} src Source objects, optionally followed by an `ifNotSet` flag
264
275
  * @returns {Object.<string,*>} Destination object
265
276
  */
266
- function merge(dst, src, ifNotSet) { // used by converters
267
- for (var keys = Object.keys(src), i = 0; i < keys.length; ++i)
268
- if (dst[keys[i]] === undefined || !ifNotSet)
269
- if (keys[i] !== "__proto__")
277
+ function merge(dst) { // used by converters
278
+ var ifNotSet = typeof arguments[arguments.length - 1] === "boolean",
279
+ limit = ifNotSet ? arguments.length - 1 : arguments.length;
280
+ ifNotSet = ifNotSet && arguments[arguments.length - 1];
281
+ for (var a = 1; a < limit; ++a) {
282
+ var src = arguments[a];
283
+ if (!src)
284
+ continue;
285
+ for (var keys = Object.keys(src), i = 0; i < keys.length; ++i)
286
+ if (!isUnsafeProperty(keys[i]) && (dst[keys[i]] === undefined || !ifNotSet))
270
287
  dst[keys[i]] = src[keys[i]];
288
+ }
271
289
  return dst;
272
290
  }
273
291
 
@@ -5,4 +5,3 @@ var patterns = exports;
5
5
  patterns.numberRe = /^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/;
6
6
  patterns.typeRefRe = /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/;
7
7
  patterns.reservedRe = /^(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$/;
8
- patterns.unsafePropertyRe = /^(?:__proto__|prototype|constructor)$/;
package/src/util/pool.js CHANGED
@@ -16,7 +16,7 @@ module.exports = pool;
16
16
  * @param {number} start Start offset
17
17
  * @param {number} end End offset
18
18
  * @returns {Uint8Array} Buffer slice
19
- * @this {Uint8Array}
19
+ * @this Uint8Array
20
20
  */
21
21
 
22
22
  /**
package/src/util.js CHANGED
@@ -16,8 +16,7 @@ util.fetch = require("./util/fetch");
16
16
  util.path = require("./util/path");
17
17
  util.patterns = require("./util/patterns");
18
18
 
19
- var reservedRe = util.patterns.reservedRe,
20
- unsafePropertyRe = util.patterns.unsafePropertyRe;
19
+ var reservedRe = util.patterns.reservedRe;
21
20
 
22
21
  /**
23
22
  * Node's fs module if available.
@@ -180,7 +179,7 @@ util.decorateEnum = function decorateEnum(object) {
180
179
  util.setProperty = function setProperty(dst, path, value, ifNotSet) {
181
180
  function setProp(dst, path, value) {
182
181
  var part = path.shift();
183
- if (unsafePropertyRe.test(part))
182
+ if (util.isUnsafeProperty(part))
184
183
  return dst;
185
184
  if (path.length > 0) {
186
185
  dst[part] = setProp(dst[part] || {}, path, value);