@node-red/util 5.0.7 → 5.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/util.js +62 -3
  2. package/package.json +3 -3
package/lib/util.js CHANGED
@@ -470,6 +470,10 @@ function setObjectProperty(msg,prop,value,createMissing) {
470
470
  var obj = msg;
471
471
  var key;
472
472
  for (var i=0;i<length-1;i++) {
473
+ if (obj === null || (typeof obj !== "object" && typeof obj !== "function")) {
474
+ // Cannot traverse a property beneath a non-object/array
475
+ return false;
476
+ }
473
477
  key = msgPropParts[i];
474
478
  if (typeof key === 'string' || (typeof key === 'number' && !Array.isArray(obj))) {
475
479
  if (Object.hasOwn(obj, key)) {
@@ -507,6 +511,10 @@ function setObjectProperty(msg,prop,value,createMissing) {
507
511
  }
508
512
  }
509
513
  }
514
+ if (obj === null || (typeof obj !== "object" && typeof obj !== "function")) {
515
+ // Cannot set or delete a property beneath a non-object/array
516
+ return false;
517
+ }
510
518
  key = msgPropParts[length-1];
511
519
  if (typeof value === "undefined") {
512
520
  if (typeof key === 'number' && Array.isArray(obj)) {
@@ -858,6 +866,56 @@ function normaliseNodeTypeName(name) {
858
866
  return result;
859
867
  }
860
868
 
869
+ /**
870
+ * Full length of a Buffer whose toJSON data was truncated by
871
+ * stringifyWithTruncatedBuffers
872
+ */
873
+ const truncatedBufferLength = Symbol("truncatedBufferLength");
874
+
875
+ /**
876
+ * Stringify an object like safeJSONStringify, but only convert the first
877
+ * `maxLength` bytes of any Buffer that is longer than that.
878
+ *
879
+ * JSON.stringify calls Buffer's toJSON, which copies every byte into an
880
+ * array, before the replacer gets to see the value. For large Buffers that
881
+ * can take a long time or exhaust the heap, so a truncating toJSON is used
882
+ * for the duration of the call.
883
+ * @param {Object} obj - the object to stringify
884
+ * @param {Number} maxLength - the number of bytes to keep of each Buffer
885
+ * @param {Function} replacer - the replacer for safeJSONStringify
886
+ * @return {String} the JSON string
887
+ */
888
+ function stringifyWithTruncatedBuffers(obj, maxLength, replacer) {
889
+ if (!(maxLength >= 0)) {
890
+ return safeJSONStringify(obj, replacer);
891
+ }
892
+ const bufferToJSON = Buffer.prototype.toJSON;
893
+ const truncatingToJSON = function() {
894
+ if (this.length <= maxLength) {
895
+ return bufferToJSON.call(this);
896
+ }
897
+ const value = {
898
+ type: "Buffer",
899
+ data: Array.from(this.subarray(0,maxLength))
900
+ };
901
+ value[truncatedBufferLength] = this.length;
902
+ return value;
903
+ };
904
+ Buffer.prototype.toJSON = truncatingToJSON;
905
+ // The finally block is skipped if execution is terminated while
906
+ // stringifying, e.g. by the timeout of a Function node calling node.warn
907
+ process.nextTick(function() {
908
+ if (Buffer.prototype.toJSON === truncatingToJSON) {
909
+ Buffer.prototype.toJSON = bufferToJSON;
910
+ }
911
+ });
912
+ try {
913
+ return safeJSONStringify(obj, replacer);
914
+ } finally {
915
+ Buffer.prototype.toJSON = bufferToJSON;
916
+ }
917
+ }
918
+
861
919
  /**
862
920
  * Encode an object to JSON without losing information about non-JSON types
863
921
  * such as Buffer and Function.
@@ -903,7 +961,8 @@ function encodeObject(msg,opts) {
903
961
  msg.msg = JSON.stringify(value);
904
962
  } else if (msg.msg instanceof Buffer) {
905
963
  msg.format = "buffer["+msg.msg.length+"]";
906
- msg.msg = msg.msg.toString('hex');
964
+ // Only hex encode the bytes that will be shown
965
+ msg.msg = msg.msg.toString('hex', 0, debuglength >= 0 ? Math.ceil(debuglength/2) : undefined);
907
966
  if (msg.msg.length > debuglength) {
908
967
  msg.msg = msg.msg.substring(0,debuglength);
909
968
  }
@@ -962,7 +1021,7 @@ function encodeObject(msg,opts) {
962
1021
  msg.msg = msg.msg.toString();
963
1022
  }
964
1023
  if (needsStringify || (msg.format === "Object")) {
965
- msg.msg = safeJSONStringify(msg.msg, function(key, value) {
1024
+ msg.msg = stringifyWithTruncatedBuffers(msg.msg, debuglength, function(key, value) {
966
1025
  if (key === '_req' || key === '_res') {
967
1026
  value = {
968
1027
  __enc__: true,
@@ -1034,7 +1093,7 @@ function encodeObject(msg,opts) {
1034
1093
  } else if (value && value.constructor) {
1035
1094
  if (value.type === "Buffer") {
1036
1095
  value.__enc__ = true;
1037
- value.length = value.data.length;
1096
+ value.length = value[truncatedBufferLength] ?? value.data.length;
1038
1097
  if (value.length > debuglength) {
1039
1098
  value.data = value.data.slice(0,debuglength);
1040
1099
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-red/util",
3
- "version": "5.0.7",
3
+ "version": "5.0.8",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,11 +16,11 @@
16
16
  ],
17
17
  "dependencies": {
18
18
  "chalk": "^4.1.2",
19
- "fs-extra": "11.4.0",
19
+ "fs-extra": "11.4.1",
20
20
  "i18next": "25.8.14",
21
21
  "json-stringify-safe": "5.0.1",
22
22
  "lodash.clonedeep": "^4.5.0",
23
- "moment": "2.30.1",
23
+ "moment": "2.31.0",
24
24
  "moment-timezone": "0.5.48"
25
25
  }
26
26
  }