Socket
Socket
Sign inDemoInstall

fast-safe-stringify

Package Overview
Dependencies
0
Maintainers
3
Versions
36
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.6 to 2.0.7

98

benchmark.js

@@ -11,2 +11,5 @@ const Benchmark = require('benchmark')

circ.o = { obj: circ, array }
const circGetters = JSON.parse(JSON.stringify(obj))
Object.assign(circGetters, { get o () { return { obj: circGetters, array } } })
const deep = require('./package.json')

@@ -24,40 +27,103 @@ deep.deep = JSON.parse(JSON.stringify(deep))

suite.add('util.inspect: simple object', function () {
inspect(obj)
const deepCircGetters = JSON.parse(JSON.stringify(deep))
for (let i = 0; i < 10; i++) {
deepCircGetters[i.toString()] = {
deep: {
deep: {
get circ () { return deep.deep },
deep: { get circ () { return deep.deep.deep } }
},
get circ () { return deep }
},
get array () { return array }
}
}
const deepCircNonCongifurableGetters = JSON.parse(JSON.stringify(deep))
Object.defineProperty(deepCircNonCongifurableGetters.deep.deep.deep, 'circ', {
get: () => deepCircNonCongifurableGetters,
enumerable: true,
configurable: false
})
suite.add('util.inspect: circular ', function () {
inspect(circ)
Object.defineProperty(deepCircNonCongifurableGetters.deep.deep, 'circ', {
get: () => deepCircNonCongifurableGetters,
enumerable: true,
configurable: false
})
suite.add('util.inspect: deep ', function () {
inspect(deep)
Object.defineProperty(deepCircNonCongifurableGetters.deep, 'circ', {
get: () => deepCircNonCongifurableGetters,
enumerable: true,
configurable: false
})
suite.add('util.inspect: deep circular', function () {
inspect(deepCirc)
Object.defineProperty(deepCircNonCongifurableGetters, 'array', {
get: () => array,
enumerable: true,
configurable: false
})
suite.add('\njson-stringify-safe: simple object', function () {
suite.add('util.inspect: simple object ', function () {
inspect(obj, { showHidden: false, depth: null })
})
suite.add('util.inspect: circular ', function () {
inspect(circ, { showHidden: false, depth: null })
})
suite.add('util.inspect: circular getters ', function () {
inspect(circGetters, { showHidden: false, depth: null })
})
suite.add('util.inspect: deep ', function () {
inspect(deep, { showHidden: false, depth: null })
})
suite.add('util.inspect: deep circular ', function () {
inspect(deepCirc, { showHidden: false, depth: null })
})
suite.add('util.inspect: large deep circular getters ', function () {
inspect(deepCircGetters, { showHidden: false, depth: null })
})
suite.add('util.inspect: deep non-conf circular getters', function () {
inspect(deepCircNonCongifurableGetters, { showHidden: false, depth: null })
})
suite.add('\njson-stringify-safe: simple object ', function () {
jsonStringifySafe(obj)
})
suite.add('json-stringify-safe: circular ', function () {
suite.add('json-stringify-safe: circular ', function () {
jsonStringifySafe(circ)
})
suite.add('json-stringify-safe: deep ', function () {
suite.add('json-stringify-safe: circular getters ', function () {
jsonStringifySafe(circGetters)
})
suite.add('json-stringify-safe: deep ', function () {
jsonStringifySafe(deep)
})
suite.add('json-stringify-safe: deep circular', function () {
suite.add('json-stringify-safe: deep circular ', function () {
jsonStringifySafe(deepCirc)
})
suite.add('json-stringify-safe: large deep circular getters ', function () {
jsonStringifySafe(deepCircGetters)
})
suite.add('json-stringify-safe: deep non-conf circular getters', function () {
jsonStringifySafe(deepCircNonCongifurableGetters)
})
suite.add('\nfast-safe-stringify: simple object', function () {
suite.add('\nfast-safe-stringify: simple object ', function () {
fastSafeStringify(obj)
})
suite.add('fast-safe-stringify: circular ', function () {
suite.add('fast-safe-stringify: circular ', function () {
fastSafeStringify(circ)
})
suite.add('fast-safe-stringify: deep ', function () {
suite.add('fast-safe-stringify: circular getters ', function () {
fastSafeStringify(circGetters)
})
suite.add('fast-safe-stringify: deep ', function () {
fastSafeStringify(deep)
})
suite.add('fast-safe-stringify: deep circular', function () {
suite.add('fast-safe-stringify: deep circular ', function () {
fastSafeStringify(deepCirc)
})
suite.add('fast-safe-stringify: large deep circular getters ', function () {
fastSafeStringify(deepCircGetters)
})
suite.add('fast-safe-stringify: deep non-conf circular getters', function () {
fastSafeStringify(deepCircNonCongifurableGetters)
})

@@ -64,0 +130,0 @@ // add listeners

@@ -7,2 +7,3 @@ module.exports = stringify

var arr = []
var replacerStack = []

@@ -12,6 +13,15 @@ // Regular stringify

decirc(obj, '', [], undefined)
var res = JSON.stringify(obj, replacer, spacer)
var res
if (replacerStack.length === 0) {
res = JSON.stringify(obj, replacer, spacer)
} else {
res = JSON.stringify(obj, replaceGetterValues(replacer), spacer)
}
while (arr.length !== 0) {
var part = arr.pop()
part[0][part[1]] = part[2]
if (part.length === 4) {
Object.defineProperty(part[0], part[1], part[3])
} else {
part[0][part[1]] = part[2]
}
}

@@ -25,4 +35,14 @@ return res

if (stack[i] === val) {
parent[k] = '[Circular]'
arr.push([parent, k, val])
var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k)
if (propertyDescriptor.get !== undefined) {
if (propertyDescriptor.configurable) {
Object.defineProperty(parent, k, { value: '[Circular]' })
arr.push([parent, k, val, propertyDescriptor])
} else {
replacerStack.push([val, k])
}
} else {
parent[k] = '[Circular]'
arr.push([parent, k, val])
}
return

@@ -61,6 +81,15 @@ }

var tmp = deterministicDecirc(obj, '', [], undefined) || obj
var res = JSON.stringify(tmp, replacer, spacer)
var res
if (replacerStack.length === 0) {
res = JSON.stringify(tmp, replacer, spacer)
} else {
res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer)
}
while (arr.length !== 0) {
var part = arr.pop()
part[0][part[1]] = part[2]
if (part.length === 4) {
Object.defineProperty(part[0], part[1], part[3])
} else {
part[0][part[1]] = part[2]
}
}

@@ -75,4 +104,14 @@ return res

if (stack[i] === val) {
parent[k] = '[Circular]'
arr.push([parent, k, val])
var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k)
if (propertyDescriptor.get !== undefined) {
if (propertyDescriptor.configurable) {
Object.defineProperty(parent, k, { value: '[Circular]' })
arr.push([parent, k, val, propertyDescriptor])
} else {
replacerStack.push([val, k])
}
} else {
parent[k] = '[Circular]'
arr.push([parent, k, val])
}
return

@@ -109,1 +148,20 @@ }

}
// wraps replacer function to handle values we couldn't replace
// and mark them as [Circular]
function replaceGetterValues (replacer) {
replacer = replacer !== undefined ? replacer : function (k, v) { return v }
return function (key, val) {
if (replacerStack.length > 0) {
for (var i = 0; i < replacerStack.length; i++) {
var part = replacerStack[i]
if (part[1] === key && part[0] === val) {
val = '[Circular]'
replacerStack.splice(i, 1)
break
}
}
}
return replacer.call(this, key, val)
}
}

4

package.json
{
"name": "fast-safe-stringify",
"version": "2.0.6",
"version": "2.0.7",
"description": "Safely and quickly serialize JavaScript objects",

@@ -15,3 +15,3 @@ "keywords": [

"scripts": {
"test": "standard && tap test.js test-stable.js",
"test": "standard && tap --no-esm test.js test-stable.js",
"benchmark": "node benchmark.js"

@@ -18,0 +18,0 @@ },

@@ -17,2 +17,18 @@ const test = require('tap').test

test('circular getter reference to root', function (assert) {
const fixture = {
name: 'Tywin Lannister',
get circle () {
return fixture
}
}
const expected = s(
{ circle: '[Circular]', name: 'Tywin Lannister' }
)
const actual = fss(fixture)
assert.is(actual, expected)
assert.end()
})
test('nested circular reference to root', function (assert) {

@@ -248,1 +264,50 @@ const fixture = { name: 'Tywin Lannister' }

})
test('circular getters are restored when stringified', function (assert) {
const fixture = {
name: 'Tywin Lannister',
get circle () {
return fixture
}
}
fss(fixture)
assert.is(fixture.circle, fixture)
assert.end()
})
test('non-configurable circular getters use a replacer instead of markers', function (assert) {
const fixture = { name: 'Tywin Lannister' }
Object.defineProperty(fixture, 'circle', {
configurable: false,
get: function () { return fixture },
enumerable: true
})
fss(fixture)
assert.is(fixture.circle, fixture)
assert.end()
})
test('getter child circular reference', function (assert) {
const fixture = {
name: 'Tywin Lannister',
child: {
name: 'Tyrion Lannister',
get dinklage () { return fixture.child }
},
get self () { return fixture }
}
const expected = s({
child: {
dinklage: '[Circular]', name: 'Tyrion Lannister'
},
name: 'Tywin Lannister',
self: '[Circular]'
})
const actual = fss(fixture)
assert.is(actual, expected)
assert.end()
})

@@ -17,2 +17,17 @@ const test = require('tap').test

test('circular getter reference to root', function (assert) {
const fixture = {
name: 'Tywin Lannister',
get circle () {
return fixture
}
}
const expected = s(
{ name: 'Tywin Lannister', circle: '[Circular]' }
)
const actual = fss(fixture)
assert.is(actual, expected)
assert.end()
})
test('nested circular reference to root', function (assert) {

@@ -242,1 +257,50 @@ const fixture = { name: 'Tywin Lannister' }

})
test('circular getters are restored when stringified', function (assert) {
const fixture = {
name: 'Tywin Lannister',
get circle () {
return fixture
}
}
fss(fixture)
assert.is(fixture.circle, fixture)
assert.end()
})
test('non-configurable circular getters use a replacer instead of markers', function (assert) {
const fixture = { name: 'Tywin Lannister' }
Object.defineProperty(fixture, 'circle', {
configurable: false,
get: function () { return fixture },
enumerable: true
})
fss(fixture)
assert.is(fixture.circle, fixture)
assert.end()
})
test('getter child circular reference are replaced instead of marked', function (assert) {
const fixture = {
name: 'Tywin Lannister',
child: {
name: 'Tyrion Lannister',
get dinklage () { return fixture.child }
},
get self () { return fixture }
}
const expected = s({
name: 'Tywin Lannister',
child: {
name: 'Tyrion Lannister', dinklage: '[Circular]'
},
self: '[Circular]'
})
const actual = fss(fixture)
assert.is(actual, expected)
assert.end()
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc