Skip to content

Commit

Permalink
Fix conversion of Uint8Array to object (node-config#761)
Browse files Browse the repository at this point in the history
  • Loading branch information
Maia-Everett committed Apr 20, 2024
1 parent fb5033d commit 0efbb5a
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
34 changes: 32 additions & 2 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,12 @@ util.makeImmutable = function(object, property, value) {
if (Buffer.isBuffer(object)) {
return object;
}

if (util.isTypedArray(object)) {
Object.preventExtensions(object);
return object;
}

let properties = null;

// Backwards compatibility mode where property/value can be specified
Expand Down Expand Up @@ -1014,6 +1020,18 @@ util.cloneDeep = function cloneDeep(parent, depth, circular, prototype) {
child = Buffer.alloc(parent.length);
parent.copy(child);
return child;
} else if (util.isTypedArray(parent)) {
if (parent.slice) {
// Note that Buffer's slice() semantics return a view of the original buffer,
// but we've checked for Buffer already
child = parent.slice();
} else if (DataView && parent instanceof DataView) {
child = new DataView(parent.buffer.slice());
} else {
// Unknown kind of typed array - shouldn't happen
child = new Uint8Array(parent.buffer.slice());
}
return child;
} else {
if (typeof prototype === 'undefined') child = Object.create(Object.getPrototypeOf(parent));
else child = Object.create(prototype);
Expand Down Expand Up @@ -1340,15 +1358,15 @@ util.extendDeep = function(mergeInto) {
/**
* Is the specified argument a regular javascript object?
*
* The argument is an object if it's a JS object, but not an array.
* The argument is an object if it's a JS object, but not an array or a typed array.
*
* @protected
* @method isObject
* @param obj {*} An argument of any type.
* @return {boolean} TRUE if the arg is an object, FALSE if not
*/
util.isObject = function(obj) {
return (obj !== null) && (typeof obj === 'object') && !(Array.isArray(obj));
return (obj !== null) && (typeof obj === 'object') && !(Array.isArray(obj)) && !(util.isTypedArray(obj));
};

/**
Expand All @@ -1363,6 +1381,18 @@ util.isPromise = function(obj) {
return Object.prototype.toString.call(obj) === '[object Promise]';
};

/**
* Is the specified argument a TypedArray?
*
* @protected
* @method isTypedArray
* @param obj {*} An argument of any type.
* @return {boolean} TRUE if the arg is a TypedArray, FALSE if not
*/
util.isTypedArray = function(obj) {
return ArrayBuffer.isView(obj);
};

/**
* <p>Initialize a parameter from the command line or process environment</p>
*
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"coffeescript": "2.2.4",
"cson": "^3.0.1",
"hjson": "^1.2.0",
"js-yaml": "^3.2.2",
"js-yaml": "^4.1.0",
"properties": "~1.2.1",
"semver": "5.3.0",
"toml": "^2.0.6",
Expand Down
23 changes: 23 additions & 0 deletions test/22-binary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var requireUncached = require('./_utils/requireUncached');
require('../parser');

'use strict';

var vows = require('vows'),
assert = require('assert');

vows.describe('Tests for parsing binary data')
.addBatch({
'Using the YAML parser - Uint8Array': {
topic: function() {
process.env.NODE_CONFIG_DIR = __dirname + '/22-binary';
return requireUncached(__dirname + '/../lib/config');
},
'reading !!binary returns a real Uint8Array': function(CONFIG) {
assert.deepStrictEqual(CONFIG.get('auth'), {
secret: new Uint8Array([0x10, 0x11, 0x12, 0x13, 0x14, 0x15])
});
},
}
})
.export(module);
2 changes: 2 additions & 0 deletions test/22-binary/default.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
auth:
secret: !!binary 'EBESExQV'

0 comments on commit 0efbb5a

Please sign in to comment.