Skip to content

Commit

Permalink
Add support for Error object (yahoo#135)
Browse files Browse the repository at this point in the history
  • Loading branch information
SidStraw committed Dec 16, 2021
1 parent f60bab5 commit aa250b8
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@ serialize({
fn : function echo(arg) { return arg; },
re : /([^\s]+)/g,
big : BigInt(10),
err : new Error('Error message.'),
});
```

The above will produce the following string output:

```js
'{"str":"string","num":0,"obj":{"foo":"foo"},"arr":[1,2,3],"bool":true,"nil":null,"undef":undefined,"inf":Infinity,"date":new Date("2016-04-28T22:02:17.000Z"),"map":new Map([["hello","world"]]),"set":new Set([123,456]),"fn":function echo(arg) { return arg; },"re":new RegExp("([^\\\\s]+)", "g"),"big":BigInt("10")}'
'{"str":"string","num":0,"obj":{"foo":"foo"},"arr":[1,2,3],"bool":true,"nil":null,"undef":undefined,"inf":Infinity,"date":new Date("2016-04-28T22:02:17.000Z"),"map":new Map([["hello","world"]]),"set":new Set([123,456]),"fn":function echo(arg) { return arg; },"re":new RegExp("([^\\\\s]+)", "g"),"big":BigInt("10"),"err":new Error("Error message.")}'
```

Note: to produced a beautified string, you can pass an optional second argument to `serialize()` to define the number of spaces to be used for the indentation.
Expand Down
13 changes: 11 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var randomBytes = require('randombytes');
// Generate an internal UID to make the regexp pattern harder to guess.
var UID_LENGTH = 16;
var UID = generateUID();
var PLACE_HOLDER_REGEXP = new RegExp('(\\\\)?"@__(F|R|D|M|S|A|U|I|B|L)-' + UID + '-(\\d+)__@"', 'g');
var PLACE_HOLDER_REGEXP = new RegExp('(\\\\)?"@__(F|R|D|M|S|A|U|I|B|L|E)-' + UID + '-(\\d+)__@"', 'g');

var IS_NATIVE_CODE_REGEXP = /\{\s*\[native code\]\s*\}/g;
var IS_PURE_FUNCTION = /function.*?\(/;
Expand Down Expand Up @@ -73,6 +73,7 @@ module.exports = function serialize(obj, options) {
var infinities= [];
var bigInts = [];
var urls = [];
var errors = [];

// Returns placeholders for functions and regexps (identified by index)
// which are later replaced by their string representation.
Expand Down Expand Up @@ -119,6 +120,10 @@ module.exports = function serialize(obj, options) {
if(origValue instanceof URL) {
return '@__L-' + UID + '-' + (urls.push(origValue) - 1) + '__@';
}

if(origValue instanceof Error) {
return '@__E-' + UID + '-' + (errors.push(origValue) - 1) + '__@';
}
}

if (type === 'function') {
Expand Down Expand Up @@ -210,7 +215,7 @@ module.exports = function serialize(obj, options) {
str = str.replace(UNSAFE_CHARS_REGEXP, escapeUnsafeChars);
}

if (functions.length === 0 && regexps.length === 0 && dates.length === 0 && maps.length === 0 && sets.length === 0 && arrays.length === 0 && undefs.length === 0 && infinities.length === 0 && bigInts.length === 0 && urls.length === 0) {
if (functions.length === 0 && regexps.length === 0 && dates.length === 0 && maps.length === 0 && sets.length === 0 && arrays.length === 0 && undefs.length === 0 && infinities.length === 0 && bigInts.length === 0 && urls.length === 0 && errors.length === 0) {
return str;
}

Expand Down Expand Up @@ -261,6 +266,10 @@ module.exports = function serialize(obj, options) {
return "new URL(\"" + urls[valueIndex].toString() + "\")";
}

if (type === 'E') {
return "new Error(\"" + errors[valueIndex].message + "\")";
}

var fn = functions[valueIndex];

return serializeFunc(fn);
Expand Down
14 changes: 14 additions & 0 deletions test/unit/serialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,20 @@ describe('serialize( obj )', function () {
});
});

describe('Error', function () {
it('should serialize Error', function () {
var e = new Error('Error message.')
expect(serialize(e)).to.equal('new Error("Error message.")');
expect(serialize({t: [e]})).to.be.a('string').equal('{"t":[new Error("Error message.")]}');
});

it('should deserialize Error', function () {
var d = eval(serialize(new Error('Error message.')));
expect(d).to.be.a('Error');
expect(d.message).to.equal('Error message.');
});
});

describe('XSS', function () {
it('should encode unsafe HTML chars to Unicode', function () {
expect(serialize('</script>')).to.equal('"\\u003C\\u002Fscript\\u003E"');
Expand Down

0 comments on commit aa250b8

Please sign in to comment.