diff --git a/benchmarks/throw.js b/benchmarks/throw.js index 235da29..c84ba6a 100755 --- a/benchmarks/throw.js +++ b/benchmarks/throw.js @@ -11,7 +11,7 @@ const internals = { const suite = new Benchmark.Suite() suite - .add('JSON.parse', () => { + .add('JSON.parse valid', () => { JSON.parse(internals.text) }) .add('JSON.parse error', () => { @@ -21,15 +21,15 @@ suite }) .add('secure-json-parse parse', () => { try { - sjson.parse(internals.text) + sjson.parse(internals.invalid) } catch (ignoreErr) { } }) .add('secure-json-parse safeParse', () => { - sjson.safeParse(internals.text) + sjson.safeParse(internals.invalid) }) .add('reviver', () => { try { - JSON.parse(internals.text, internals.reviver) + JSON.parse(internals.invalid, internals.reviver) } catch (ignoreErr) { } }) .on('cycle', (event) => { diff --git a/index.js b/index.js index 99113a1..6d2fcc9 100755 --- a/index.js +++ b/index.js @@ -4,7 +4,7 @@ const hasBuffer = typeof Buffer !== 'undefined' const suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/ const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/ -function parse (text, reviver, options) { +function _parse (text, reviver, options) { // Normalize arguments if (options == null) { if (reviver !== null && typeof reviver === 'object') { @@ -97,11 +97,25 @@ function filter (obj, { protoAction = 'error', constructorAction = 'error', safe return obj } +function parse (text, reviver, options) { + const stackTraceLimit = Error.stackTraceLimit + Error.stackTraceLimit = 0 + try { + return _parse(text, reviver, options) + } finally { + Error.stackTraceLimit = stackTraceLimit + } +} + function safeParse (text, reviver) { + const stackTraceLimit = Error.stackTraceLimit + Error.stackTraceLimit = 0 try { - return parse(text, reviver, { safe: true }) - } catch (ignoreError) { + return _parse(text, reviver, { safe: true }) + } catch (_e) { return null + } finally { + Error.stackTraceLimit = stackTraceLimit } } diff --git a/test/index.test.js b/test/index.test.js index 4c6ac8a..564f764 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -145,6 +145,14 @@ test('parse', t => { t.end() }) + t.test('should reset stackTraceLimit', t => { + const text = '{ "a": 5, "b": 6, "__proto__": { "x": 7 }, "c": { "d": 0, "e": "text", "__proto__": { "y": 8 }, "f": { "g": 2 } } }' + Error.stackTraceLimit = 42 + t.throws(() => j.parse(text)) + t.same(Error.stackTraceLimit, 42) + t.end() + }) + t.end() }) @@ -372,6 +380,14 @@ test('safeParse', t => { t.end() }) + t.test('should reset stackTraceLimit', t => { + const text = '{ "a": 5, "b": 6, "__proto__": { "x": 7 }, "c": { "d": 0, "e": "text", "__proto__": { "y": 8 }, "f": { "g": 2 } } }' + Error.stackTraceLimit = 42 + t.same(j.safeParse(text), null) + t.same(Error.stackTraceLimit, 42) + t.end() + }) + t.test('sanitizes nested object string', t => { const text = '{ "a": 5, "b": 6, "__proto__": { "x": 7 }, "c": { "d": 0, "e": "text", "__proto__": { "y": 8 }, "f": { "g": 2 } } }'