protobufjs 8.2.0 → 8.2.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.
@@ -1 +1,2 @@
1
- export * from "../descriptor";
1
+ import * as $protobuf from "../..";
2
+ import Long = require("long");
package/ext/descriptor.js CHANGED
@@ -221,9 +221,14 @@ var unnamedMessageIndex = 0;
221
221
  * @param {IDescriptorProto|Reader|Uint8Array} descriptor Descriptor
222
222
  * @param {string} [edition="proto2"] The syntax or edition to use
223
223
  * @param {boolean} [nested=false] Whether or not this is a nested object
224
+ * @param {number} [depth] Current nesting depth, defaults to `0`
224
225
  * @returns {Type} Type instance
225
226
  */
226
- Type.fromDescriptor = function fromDescriptor(descriptor, edition, nested) {
227
+ Type.fromDescriptor = function fromDescriptor(descriptor, edition, nested, depth) {
228
+ if (depth === undefined)
229
+ depth = 0;
230
+ if (depth > $protobuf.util.nestingLimit)
231
+ throw Error("max depth exceeded");
227
232
  descriptor = decodeDescriptor(descriptor, exports.DescriptorProto);
228
233
 
229
234
  var type = new Type(descriptor.name.length ? descriptor.name : "Type" + unnamedMessageIndex++, fromDescriptorOptions(descriptor.options, exports.MessageOptions)),
@@ -255,7 +260,7 @@ Type.fromDescriptor = function fromDescriptor(descriptor, edition, nested) {
255
260
  for (i = 0; i < descriptor.nestedType.length; ++i) {
256
261
  if (descriptor.nestedType[i].options && descriptor.nestedType[i].options.mapEntry)
257
262
  continue;
258
- type.add(Type.fromDescriptor(descriptor.nestedType[i], edition, true));
263
+ type.add(Type.fromDescriptor(descriptor.nestedType[i], edition, true, depth + 1));
259
264
  }
260
265
  /* Nested enums */ if (descriptor.enumType)
261
266
  for (i = 0; i < descriptor.enumType.length; ++i)
@@ -5,17 +5,11 @@ export interface ITextFormatOptions {
5
5
  unknowns?: boolean;
6
6
  }
7
7
 
8
- /** Maximum recursion depth for text format parsing and formatting. Defaults to util.recursionLimit. */
9
- export let recursionLimit: number;
10
-
11
8
  /** Maximum recursion depth for formatting length-delimited unknown fields. */
12
9
  export let unknownRecursionLimit: number;
13
10
 
14
11
  declare module ".." {
15
12
  namespace textformat {
16
- /** Maximum recursion depth for text format parsing and formatting. Defaults to util.recursionLimit. */
17
- let recursionLimit: number;
18
-
19
13
  /** Maximum recursion depth for formatting length-delimited unknown fields. */
20
14
  let unknownRecursionLimit: number;
21
15
  }
package/ext/textformat.js CHANGED
@@ -10,21 +10,6 @@ var Type = protobuf.Type,
10
10
 
11
11
  var textformat = protobuf.textformat = module.exports = {};
12
12
 
13
- var recursionLimit;
14
-
15
- /**
16
- * Maximum recursion depth for text format parsing and formatting. Defaults to util.recursionLimit.
17
- * @type {number}
18
- */
19
- Object.defineProperty(textformat, "recursionLimit", {
20
- get: function get() {
21
- return recursionLimit === undefined ? util.recursionLimit : recursionLimit;
22
- },
23
- set: function set(value) {
24
- recursionLimit = value == null ? undefined : value;
25
- }
26
- });
27
-
28
13
  /**
29
14
  * Maximum recursion depth for formatting length-delimited unknown fields.
30
15
  * @type {number}
@@ -88,7 +73,7 @@ function formatText(type, message, options) {
88
73
  throw TypeError("type must be a Type");
89
74
  type.root.resolveAll();
90
75
  var lines = [];
91
- writeMessage(type, message, lines, 0, options || {}, 0, textformat.recursionLimit);
76
+ writeMessage(type, message, lines, 0, options || {}, 0);
92
77
  return lines.join("\n");
93
78
  }
94
79
 
@@ -318,7 +303,6 @@ Tokenizer.prototype.readCodePoint = function readCodePoint(size) {
318
303
 
319
304
  function Parser(source) {
320
305
  this.tn = new Tokenizer(source);
321
- this.recursionLimit = textformat.recursionLimit;
322
306
  }
323
307
 
324
308
  Parser.prototype.error = function error(message) {
@@ -331,13 +315,9 @@ Parser.prototype.expectEnd = function expectEnd() {
331
315
  this.error("unexpected token '" + token.value + "'");
332
316
  };
333
317
 
334
- Parser.prototype.checkRecursion = function checkRecursion(depth) {
335
- if (depth > this.recursionLimit)
336
- this.error("max depth exceeded");
337
- };
338
-
339
318
  Parser.prototype.parseMessage = function parseMessage(type, end, depth) {
340
- this.checkRecursion(depth);
319
+ if (depth > util.recursionLimit)
320
+ this.error("max depth exceeded");
341
321
  var object = {},
342
322
  seen = {};
343
323
  for (;;) {
@@ -473,7 +453,8 @@ Parser.prototype.parseMessageFieldDelimiter = function parseMessageFieldDelimite
473
453
  };
474
454
 
475
455
  Parser.prototype.parseMapEntry = function parseMapEntry(field, depth) {
476
- this.checkRecursion(depth);
456
+ if (depth > util.recursionLimit)
457
+ this.error("max depth exceeded");
477
458
  var end;
478
459
  if (this.tn.skip("{"))
479
460
  end = "}";
@@ -617,7 +598,7 @@ Parser.prototype.skipBalanced = function skipBalanced(open, close, depth) {
617
598
  if (!token)
618
599
  this.error("expected '" + close + "'");
619
600
  if (token.value === open) {
620
- if (depth + ++balance > this.recursionLimit)
601
+ if (depth + ++balance > util.recursionLimit)
621
602
  this.error("max depth exceeded");
622
603
  }
623
604
  else if (token.value === close)
@@ -855,13 +836,9 @@ function parseIntegerBigInt(digits, radix, sign, unsigned, bits) {
855
836
  return Number(value);
856
837
  }
857
838
 
858
- function checkRecursion(depth, recursionLimit) {
859
- if (depth > recursionLimit)
839
+ function writeMessage(type, message, lines, indent, options, depth) {
840
+ if (depth > util.recursionLimit)
860
841
  throw Error("max depth exceeded");
861
- }
862
-
863
- function writeMessage(type, message, lines, indent, options, depth, recursionLimit) {
864
- checkRecursion(depth, recursionLimit);
865
842
  var fields = type.fieldsArray.slice().sort(util.compareFieldsById);
866
843
  for (var i = 0; i < fields.length; ++i) {
867
844
  var field = fields[i].resolve(),
@@ -869,25 +846,26 @@ function writeMessage(type, message, lines, indent, options, depth, recursionLim
869
846
  if (value == null || !Object.prototype.hasOwnProperty.call(message, field.name))
870
847
  continue;
871
848
  if (field.map)
872
- writeMapField(field, value, lines, indent, options, depth, recursionLimit);
849
+ writeMapField(field, value, lines, indent, options, depth);
873
850
  else if (field.repeated)
874
851
  for (var j = 0; j < value.length; ++j)
875
- writeField(field, value[j], lines, indent, options, depth, recursionLimit);
852
+ writeField(field, value[j], lines, indent, options, depth);
876
853
  else
877
- writeField(field, value, lines, indent, options, depth, recursionLimit);
854
+ writeField(field, value, lines, indent, options, depth);
878
855
  }
879
856
  if (options.unknowns && message.$unknowns != null && Object.prototype.hasOwnProperty.call(message, "$unknowns"))
880
857
  writeUnknowns(message.$unknowns, lines, indent);
881
858
  }
882
859
 
883
- function writeMapField(field, map, lines, indent, options, depth, recursionLimit) {
860
+ function writeMapField(field, map, lines, indent, options, depth) {
884
861
  var keys = Object.keys(map).sort(),
885
862
  keyField = mapKeyField(field),
886
863
  valueField = mapValueField(field),
887
864
  name = formatFieldName(field),
888
865
  sp = spaces(indent);
889
866
  for (var i = 0; i < keys.length; ++i) {
890
- checkRecursion(depth + 1, recursionLimit);
867
+ if (depth + 1 > util.recursionLimit)
868
+ throw Error("max depth exceeded");
891
869
  var key = keyField.long ? util.longFromKey(keys[i], keyField.type === "uint64" || keyField.type === "fixed64") : keys[i];
892
870
  if (keyField.type === "bool")
893
871
  key = util.boolFromKey(keys[i]);
@@ -895,7 +873,7 @@ function writeMapField(field, map, lines, indent, options, depth, recursionLimit
895
873
  lines.push(spaces(indent + 2) + "key: " + formatScalar(keyField, key));
896
874
  if (valueField.resolvedType instanceof Type) {
897
875
  lines.push(spaces(indent + 2) + "value {");
898
- writeMessage(valueField.resolvedType, map[keys[i]], lines, indent + 4, options, depth + 2, recursionLimit);
876
+ writeMessage(valueField.resolvedType, map[keys[i]], lines, indent + 4, options, depth + 2);
899
877
  lines.push(spaces(indent + 2) + "}");
900
878
  } else
901
879
  lines.push(spaces(indent + 2) + "value: " + formatScalar(valueField, map[keys[i]]));
@@ -903,12 +881,12 @@ function writeMapField(field, map, lines, indent, options, depth, recursionLimit
903
881
  }
904
882
  }
905
883
 
906
- function writeField(field, value, lines, indent, options, depth, recursionLimit) {
884
+ function writeField(field, value, lines, indent, options, depth) {
907
885
  var name = formatFieldName(field),
908
886
  sp = spaces(indent);
909
887
  if (field.resolvedType instanceof Type) {
910
888
  lines.push(sp + name + " {");
911
- writeMessage(field.resolvedType, value, lines, indent + 2, options, depth + 1, recursionLimit);
889
+ writeMessage(field.resolvedType, value, lines, indent + 2, options, depth + 1);
912
890
  lines.push(sp + "}");
913
891
  } else
914
892
  lines.push(sp + name + ": " + formatScalar(field, value));
package/index.d.ts CHANGED
@@ -2436,6 +2436,9 @@ export namespace util {
2436
2436
  */
2437
2437
  function merge(dst: { [k: string]: any }, src: { [k: string]: any }, ifNotSet?: boolean): { [k: string]: any };
2438
2438
 
2439
+ /** Schema declaration nesting limit. */
2440
+ let nestingLimit: number;
2441
+
2439
2442
  /** Recursion limit. */
2440
2443
  let recursionLimit: number;
2441
2444
 
@@ -2574,14 +2577,6 @@ export namespace util {
2574
2577
  /** Node's fs module if available. */
2575
2578
  let fs: { [k: string]: any };
2576
2579
 
2577
- /**
2578
- * Checks a recursion depth.
2579
- * @param depth Depth of recursion
2580
- * @returns Depth of recursion
2581
- * @throws {Error} If depth exceeds util.recursionLimit
2582
- */
2583
- function checkDepth(depth: (number|undefined)): number;
2584
-
2585
2580
  /**
2586
2581
  * Converts an object's values to an array.
2587
2582
  * @param object Object to convert
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "protobufjs",
3
- "version": "8.2.0",
3
+ "version": "8.2.1",
4
4
  "versionScheme": "~",
5
5
  "description": "Protocol Buffers for JavaScript & TypeScript.",
6
6
  "author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
@@ -51,11 +51,9 @@
51
51
  },
52
52
  "devDependencies": {
53
53
  "@eslint/js": "^10.0.0",
54
- "benchmark": "^2.1.4",
55
54
  "browserify": "^17.0.0",
56
55
  "browserify-wrap": "^1.0.2",
57
56
  "bundle-collapser": "^1.3.0",
58
- "chalk": "^4.0.0",
59
57
  "escodegen": "^1.13.0",
60
58
  "eslint": "^10.0.0",
61
59
  "eslint-plugin-jsdoc": "^62.9.0",
@@ -63,7 +61,6 @@
63
61
  "estraverse": "^5.1.0",
64
62
  "gh-pages": "^6.0.0",
65
63
  "globals": "^17.0.0",
66
- "google-protobuf": "^4.0.0",
67
64
  "gulp": "^5.0.0",
68
65
  "gulp-header": "^2.0.9",
69
66
  "gulp-if": "^3.0.0",
package/src/converter.js CHANGED
@@ -107,15 +107,15 @@ converter.fromObject = function fromObject(mtype) {
107
107
  /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
108
108
  var fields = mtype.fieldsArray;
109
109
  var gen = util.codegen(["d", "q"], mtype.name + "$fromObject")
110
- ("if(d instanceof this.ctor)")
110
+ ("if(d instanceof C)")
111
111
  ("return d")
112
112
  ("if(q===undefined)q=0")
113
113
  ("if(q>util.recursionLimit)")
114
114
  ("throw Error(\"max depth exceeded\")");
115
115
  if (!fields.length) return gen
116
- ("return new this.ctor");
116
+ ("return new C");
117
117
  gen
118
- ("var m=new this.ctor");
118
+ ("var m=new C");
119
119
  for (var i = 0; i < fields.length; ++i) {
120
120
  var field = fields[i].resolve(),
121
121
  prop = util.safeProp(field.name),
package/src/decoder.js CHANGED
@@ -32,7 +32,7 @@ function decoder(mtype) {
32
32
  ("if(q===undefined)q=0")
33
33
  ("if(q>Reader.recursionLimit)")
34
34
  ("throw Error(\"max depth exceeded\")")
35
- ("var c=l===undefined?r.len:r.pos+l,m=g||new this.ctor" + (hasMapField ? ",k,v" : hasImplicitPresenceField ? ",v" : ""))
35
+ ("var c=l===undefined?r.len:r.pos+l,m=g||new C" + (hasMapField ? ",k,v" : hasImplicitPresenceField ? ",v" : ""))
36
36
  ("while(r.pos<c){")
37
37
  ("var s=r.pos")
38
38
  ("var t=r.tag()")
@@ -156,7 +156,11 @@ function decoder(mtype) {
156
156
  ("case %i:{", field.id)
157
157
  ("if(u!==%i)", types.basic[type])
158
158
  ("break");
159
- if (type === "string" || type === "bytes") gen
159
+ if (field.resolvedType instanceof Enum && field.typeDefault !== 0) gen
160
+ // TODO: Protoc rejects open enums whose first value is not zero.
161
+ // We should do the same, but for v8 this would be a regression.
162
+ ("if((v=r.%s())!==%j)", type, field.typeDefault);
163
+ else if (type === "string" || type === "bytes") gen
160
164
  ("if((v=r.%s()).length)", type);
161
165
  else if (types.long[type] !== undefined) gen
162
166
  ("if(typeof(v=r.%s())===\"object\"?v.low||v.high:v!==0)", type);
package/src/namespace.js CHANGED
@@ -34,7 +34,10 @@ var Type, // cyclic
34
34
  * @throws {TypeError} If arguments are invalid
35
35
  */
36
36
  Namespace.fromJSON = function fromJSON(name, json, depth) {
37
- depth = util.checkDepth(depth);
37
+ if (depth === undefined)
38
+ depth = 0;
39
+ if (depth > util.recursionLimit)
40
+ throw Error("max depth exceeded");
38
41
  return new Namespace(name, json.options).addJSON(json.nested, depth);
39
42
  };
40
43
 
@@ -197,7 +200,10 @@ Namespace.prototype.toJSON = function toJSON(toJSONOptions) {
197
200
  * @returns {Namespace} `this`
198
201
  */
199
202
  Namespace.prototype.addJSON = function addJSON(nestedJson, depth) {
200
- depth = util.checkDepth(depth);
203
+ if (depth === undefined)
204
+ depth = 0;
205
+ if (depth > util.recursionLimit)
206
+ throw Error("max depth exceeded");
201
207
  var ns = this;
202
208
  /* istanbul ignore else */
203
209
  if (nestedJson) {
@@ -337,6 +343,8 @@ Namespace.prototype.define = function define(path, json) {
337
343
  throw TypeError("illegal path");
338
344
  if (path && path.length && path[0] === "")
339
345
  throw Error("path must be relative");
346
+ if (path.length > util.recursionLimit)
347
+ throw Error("max depth exceeded");
340
348
 
341
349
  var ptr = this;
342
350
  while (path.length > 0) {
package/src/parse.js CHANGED
@@ -312,7 +312,9 @@ function parse(source, root, options) {
312
312
 
313
313
 
314
314
  function parseCommon(parent, token, depth) {
315
- depth = util.checkDepth(depth);
315
+ if (depth === undefined)
316
+ depth = 0;
317
+ // depth is checked by dispatched functions
316
318
  switch (token) {
317
319
 
318
320
  case "option":
@@ -378,7 +380,10 @@ function parse(source, root, options) {
378
380
  }
379
381
 
380
382
  function parseType(parent, token, depth) {
381
- depth = util.checkDepth(depth);
383
+ if (depth === undefined)
384
+ depth = 0;
385
+ if (depth > util.nestingLimit)
386
+ throw Error("max depth exceeded");
382
387
 
383
388
  /* istanbul ignore if */
384
389
  if (!nameRe.test(token = next()))
@@ -507,7 +512,10 @@ function parse(source, root, options) {
507
512
  }
508
513
 
509
514
  function parseGroup(parent, rule, extend, depth) {
510
- depth = util.checkDepth(depth);
515
+ if (depth === undefined)
516
+ depth = 0;
517
+ if (depth > util.nestingLimit)
518
+ throw Error("max depth exceeded");
511
519
  if (edition >= 2023) {
512
520
  throw illegal("group");
513
521
  }
@@ -754,7 +762,10 @@ function parse(source, root, options) {
754
762
  }
755
763
 
756
764
  function parseOptionValue(parent, name, depth) {
757
- depth = util.checkDepth(depth);
765
+ if (depth === undefined)
766
+ depth = 0;
767
+ if (depth > util.recursionLimit)
768
+ throw Error("max depth exceeded");
758
769
  // { a: "foo" b { c: "bar" } }
759
770
  if (skip("{", true)) {
760
771
  var objectResult = {};
@@ -845,7 +856,10 @@ function parse(source, root, options) {
845
856
  }
846
857
 
847
858
  function parseService(parent, token, depth) {
848
- depth = util.checkDepth(depth);
859
+ if (depth === undefined)
860
+ depth = 0;
861
+ if (depth > util.recursionLimit)
862
+ throw Error("max depth exceeded");
849
863
 
850
864
  /* istanbul ignore if */
851
865
  if (!nameRe.test(token = next()))
package/src/root.js CHANGED
@@ -59,7 +59,10 @@ function Root(options) {
59
59
  * @returns {Root} Root namespace
60
60
  */
61
61
  Root.fromJSON = function fromJSON(json, root, depth) {
62
- depth = util.checkDepth(depth);
62
+ if (depth === undefined)
63
+ depth = 0;
64
+ if (depth > util.recursionLimit)
65
+ throw Error("max depth exceeded");
63
66
  if (!root)
64
67
  root = new Root();
65
68
  if (json.options)
package/src/service.js CHANGED
@@ -53,7 +53,10 @@ function Service(name, options) {
53
53
  * @throws {TypeError} If arguments are invalid
54
54
  */
55
55
  Service.fromJSON = function fromJSON(name, json, depth) {
56
- depth = util.checkDepth(depth);
56
+ if (depth === undefined)
57
+ depth = 0;
58
+ if (depth > util.recursionLimit)
59
+ throw Error("max depth exceeded");
57
60
  var service = new Service(name, json.options);
58
61
  /* istanbul ignore else */
59
62
  if (json.methods)
package/src/type.js CHANGED
@@ -171,6 +171,8 @@ Object.defineProperties(Type.prototype, {
171
171
  util.merge(ctor, Message, true);
172
172
 
173
173
  this._ctor = ctor;
174
+ delete this.decode;
175
+ delete this.fromObject;
174
176
 
175
177
  // Messages have non-enumerable default values on their prototype
176
178
  var i = 0;
@@ -239,7 +241,10 @@ function clearCache(type) {
239
241
  * @returns {Type} Created message type
240
242
  */
241
243
  Type.fromJSON = function fromJSON(name, json, depth) {
242
- depth = util.checkDepth(depth);
244
+ if (depth === undefined)
245
+ depth = 0;
246
+ if (depth > util.nestingLimit)
247
+ throw Error("max depth exceeded");
243
248
  var type = new Type(name, json.options);
244
249
  type.extensions = json.extensions;
245
250
  type.reserved = json.reserved;
@@ -479,7 +484,8 @@ Type.prototype.setup = function setup() {
479
484
  this.decode = decoder(this)({
480
485
  Reader : Reader,
481
486
  types : types,
482
- util : util
487
+ util : util,
488
+ C : this.ctor
483
489
  });
484
490
  this.verify = verifier(this)({
485
491
  types : types,
@@ -487,7 +493,8 @@ Type.prototype.setup = function setup() {
487
493
  });
488
494
  this.fromObject = converter.fromObject(this)({
489
495
  types : types,
490
- util : util
496
+ util : util,
497
+ C : this.ctor
491
498
  });
492
499
  this.toObject = converter.toObject(this)({
493
500
  types : types,
@@ -273,12 +273,19 @@ function merge(dst, src, ifNotSet) { // used by converters
273
273
 
274
274
  util.merge = merge;
275
275
 
276
+ /**
277
+ * Schema declaration nesting limit.
278
+ * @memberof util
279
+ * @type {number}
280
+ */
281
+ util.nestingLimit = 32; // protoc: MaxMessageDeclarationNestingDepth
282
+
276
283
  /**
277
284
  * Recursion limit.
278
285
  * @memberof util
279
286
  * @type {number}
280
287
  */
281
- util.recursionLimit = 100;
288
+ util.recursionLimit = 100; // protoc: CodedInputStream::default_recursion_limit_
282
289
 
283
290
  /**
284
291
  * Makes a property safe for assignment as an own property.
package/src/util/utf8.js CHANGED
@@ -31,19 +31,7 @@ utf8.length = function utf8_length(string) {
31
31
  return len;
32
32
  };
33
33
 
34
- /**
35
- * Reads UTF8 bytes as a string.
36
- * @param {Uint8Array} buffer Source buffer
37
- * @param {number} start Source start
38
- * @param {number} end Source end
39
- * @returns {string} String read
40
- */
41
- utf8.read = function utf8_read(buffer, start, end) {
42
- if (end - start < 1) {
43
- return "";
44
- }
45
-
46
- var str = "";
34
+ function utf8_read_js(buffer, start, end, str) {
47
35
  for (var i = start; i < end;) {
48
36
  var t = buffer[i++];
49
37
  if (t <= 0x7F) {
@@ -65,6 +53,44 @@ utf8.read = function utf8_read(buffer, start, end) {
65
53
  }
66
54
  }
67
55
  }
56
+ return str;
57
+ }
58
+
59
+ /**
60
+ * Reads UTF8 bytes as a string.
61
+ * @param {Uint8Array} buffer Source buffer
62
+ * @param {number} start Source start
63
+ * @param {number} end Source end
64
+ * @returns {string} String read
65
+ */
66
+ utf8.read = function utf8_read_ascii(buffer, start, end) {
67
+ if (end - start < 1)
68
+ return "";
69
+
70
+ var str = "",
71
+ i = start,
72
+ c1, c2, c3, c4, c5, c6, c7, c8;
73
+
74
+ for (; i + 7 < end; i += 8) {
75
+ c1 = buffer[i];
76
+ c2 = buffer[i + 1];
77
+ c3 = buffer[i + 2];
78
+ c4 = buffer[i + 3];
79
+ c5 = buffer[i + 4];
80
+ c6 = buffer[i + 5];
81
+ c7 = buffer[i + 6];
82
+ c8 = buffer[i + 7];
83
+ if ((c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8) & 0x80)
84
+ return utf8_read_js(buffer, i, end, str);
85
+ str += String.fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8);
86
+ }
87
+
88
+ for (; i < end; ++i) {
89
+ c1 = buffer[i];
90
+ if (c1 & 0x80)
91
+ return utf8_read_js(buffer, i, end, str);
92
+ str += String.fromCharCode(c1);
93
+ }
68
94
 
69
95
  return str;
70
96
  };
package/src/util.js CHANGED
@@ -25,20 +25,6 @@ var reservedRe = util.patterns.reservedRe,
25
25
  */
26
26
  util.fs = require("./util/fs");
27
27
 
28
- /**
29
- * Checks a recursion depth.
30
- * @param {number|undefined} depth Depth of recursion
31
- * @returns {number} Depth of recursion
32
- * @throws {Error} If depth exceeds util.recursionLimit
33
- */
34
- util.checkDepth = function checkDepth(depth) {
35
- if (depth === undefined)
36
- depth = 0;
37
- if (depth > util.recursionLimit)
38
- throw Error("max depth exceeded");
39
- return depth;
40
- };
41
-
42
28
  /**
43
29
  * Converts an object's values to an array.
44
30
  * @param {Object.<string,*>} object Object to convert
@@ -215,6 +201,8 @@ util.setProperty = function setProperty(dst, path, value, ifNotSet) {
215
201
  throw TypeError("path must be specified");
216
202
 
217
203
  path = path.split(".");
204
+ if (path.length > util.recursionLimit)
205
+ throw Error("max depth exceeded");
218
206
  return setProp(dst, path, value);
219
207
  };
220
208
 
package/src/writer.js CHANGED
@@ -173,6 +173,11 @@ function writeByte(val, buf, pos) {
173
173
  buf[pos] = val & 255;
174
174
  }
175
175
 
176
+ function writeStringAscii(val, buf, pos) {
177
+ for (var i = 0; i < val.length;)
178
+ buf[pos++] = val.charCodeAt(i++);
179
+ }
180
+
176
181
  function writeVarint32(val, buf, pos) {
177
182
  while (val > 127) {
178
183
  buf[pos++] = val & 127 | 128;
@@ -401,7 +406,7 @@ Writer.prototype.raw = function write_raw(value) {
401
406
  Writer.prototype.string = function write_string(value) {
402
407
  var len = utf8.length(value);
403
408
  return len
404
- ? this.uint32(len)._push(utf8.write, len, value)
409
+ ? this.uint32(len)._push(len === value.length ? writeStringAscii : utf8.write, len, value)
405
410
  : this._push(writeByte, 1, 0);
406
411
  };
407
412
 
@@ -66,6 +66,11 @@ BufferWriter.prototype.raw = function write_raw_buffer(value) {
66
66
  return len ? this._push(BufferWriter.writeBytesBuffer, len, value) : this;
67
67
  };
68
68
 
69
+ function writeStringBufferAscii(val, buf, pos) {
70
+ for (var i = 0; i < val.length;)
71
+ buf[pos++] = val.charCodeAt(i++);
72
+ }
73
+
69
74
  function writeStringBuffer(val, buf, pos) {
70
75
  if (val.length < 40) // plain js is faster for short strings (probably due to redundant assertions)
71
76
  util.utf8.write(val, buf, pos);
@@ -82,7 +87,7 @@ BufferWriter.prototype.string = function write_string_buffer(value) {
82
87
  var len = util.Buffer.byteLength(value);
83
88
  this.uint32(len);
84
89
  if (len)
85
- this._push(writeStringBuffer, len, value);
90
+ this._push(len === value.length && len < 40 ? writeStringBufferAscii : writeStringBuffer, len, value);
86
91
  return this;
87
92
  };
88
93