Socket
Socket
Sign inDemoInstall

fast-redact

Package Overview
Dependencies
Maintainers
2
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fast-redact - npm Package Compare versions

Comparing version 3.2.0 to 3.3.0

165

lib/modifiers.js

@@ -44,24 +44,13 @@ 'use strict'

function nestedRestore (arr) {
const length = arr.length
for (var i = 0; i < length; i++) {
const { key, target, value, level } = arr[i]
if (level === 0 || level === 1) {
if (has(target, key)) {
target[key] = value
}
/* istanbul ignore else */
if (typeof target === 'object') {
const targetKeys = Object.keys(target)
for (var j = 0; j < targetKeys.length; j++) {
const tKey = targetKeys[j]
const subTarget = target[tKey]
if (has(subTarget, key)) {
subTarget[key] = value
}
}
}
} else {
restoreNthLevel(key, target, value, level)
/**
* @param {RestoreInstruction[]} instructions a set of instructions for restoring values to objects
*/
function nestedRestore (instructions) {
for (let i = 0; i < instructions.length; i++) {
const { target, path, value } = instructions[i]
let current = target
for (let i = path.length - 1; i > 0; i--) {
current = current[path[i]]
}
current[path[0]] = value
}

@@ -77,8 +66,3 @@ }

const key = keys[i]
const { value, parent, exists, level } =
specialSet(target, key, path, ns, censor, isCensorFct, censorFctTakesPath)
if (exists === true && parent !== null) {
store.push({ key: ns[ns.length - 1], target: parent, value, level })
}
specialSet(store, target, key, path, ns, censor, isCensorFct, censorFctTakesPath)
}

@@ -94,3 +78,3 @@ return store

function specialSet (o, k, path, afterPath, censor, isCensorFct, censorFctTakesPath) {
function specialSet (store, o, k, path, afterPath, censor, isCensorFct, censorFctTakesPath) {
const afterPathLen = afterPath.length

@@ -104,3 +88,2 @@ const lastPathIndex = afterPathLen - 1

var oov = null
var exists = true
var wc = null

@@ -111,9 +94,12 @@ var kIsWc

var level = 0
// need to track depth of the `redactPath` tree
var depth = 0
var redactPathCurrent = tree()
ov = n = o[k]
if (typeof n !== 'object') return { value: null, parent: null, exists }
if (typeof n !== 'object') return
while (n != null && ++i < afterPathLen) {
depth += 1
k = afterPath[i]
oov = ov
if (k !== '*' && !wc && !(typeof n === 'object' && k in n)) {
exists = false
break

@@ -137,4 +123,5 @@ }

if (consecutive) {
redactPathCurrent = node(redactPathCurrent, wck, depth)
level = i
ov = iterateNthLevel(wcov, level - 1, k, path, afterPath, censor, isCensorFct, censorFctTakesPath, originalKey, n, nv, ov, kIsWc, wck, i, lastPathIndex, exists)
ov = iterateNthLevel(wcov, level - 1, k, path, afterPath, censor, isCensorFct, censorFctTakesPath, originalKey, n, nv, ov, kIsWc, wck, i, lastPathIndex, redactPathCurrent, store, o[originalKey], depth + 1)
} else {

@@ -153,8 +140,15 @@ if (kIsWc || (typeof wcov === 'object' && wcov !== null && k in wcov)) {

if (kIsWc) {
const rv = restoreInstr(node(redactPathCurrent, wck, depth), ov, o[originalKey])
store.push(rv)
n[wck] = nv
} else {
if (wcov[k] === nv) {
exists = false
// pass
} else if ((nv === undefined && censor !== undefined) || (has(wcov, k) && nv === ov)) {
redactPathCurrent = node(redactPathCurrent, wck, depth)
} else {
wcov[k] = (nv === undefined && censor !== undefined) || (has(wcov, k) && nv === ov) ? wcov[k] : nv
redactPathCurrent = node(redactPathCurrent, wck, depth)
const rv = restoreInstr(node(redactPathCurrent, k, depth + 1), ov, o[originalKey])
store.push(rv)
wcov[k] = nv
}

@@ -168,2 +162,3 @@ }

ov = n[k]
redactPathCurrent = node(redactPathCurrent, k, depth)
nv = (i !== lastPathIndex)

@@ -174,3 +169,9 @@ ? ov

: censor)
n[k] = (has(n, k) && nv === ov) || (nv === undefined && censor !== undefined) ? n[k] : nv
if ((has(n, k) && nv === ov) || (nv === undefined && censor !== undefined)) {
// pass
} else {
const rv = restoreInstr(redactPathCurrent, ov, o[originalKey])
store.push(rv)
n[k] = nv
}
n = n[k]

@@ -181,7 +182,5 @@ }

if (ov === oov || typeof ov === 'undefined') {
exists = false
// pass
}
}
return { value: ov, parent: oov, exists, level }
}

@@ -199,3 +198,3 @@

function iterateNthLevel (wcov, level, k, path, afterPath, censor, isCensorFct, censorFctTakesPath, originalKey, n, nv, ov, kIsWc, wck, i, lastPathIndex, exists) {
function iterateNthLevel (wcov, level, k, path, afterPath, censor, isCensorFct, censorFctTakesPath, originalKey, n, nv, ov, kIsWc, wck, i, lastPathIndex, redactPathCurrent, store, parent, depth) {
if (level === 0) {

@@ -214,17 +213,22 @@ if (kIsWc || (typeof wcov === 'object' && wcov !== null && k in wcov)) {

if (kIsWc) {
const rv = restoreInstr(redactPathCurrent, ov, parent)
store.push(rv)
n[wck] = nv
} else {
if (wcov[k] === nv) {
exists = false
// pass
} else if ((nv === undefined && censor !== undefined) || (has(wcov, k) && nv === ov)) {
// pass
} else {
wcov[k] = (nv === undefined && censor !== undefined) || (has(wcov, k) && nv === ov) ? wcov[k] : nv
const rv = restoreInstr(node(redactPathCurrent, k, depth + 1), ov, parent)
store.push(rv)
wcov[k] = nv
}
}
}
return ov
}
for (const key in wcov) {
if (typeof wcov[key] === 'object') {
var temp = iterateNthLevel(wcov[key], level - 1, k, path, afterPath, censor, isCensorFct, censorFctTakesPath, originalKey, n, nv, ov, kIsWc, wck, i, lastPathIndex, exists)
return temp
redactPathCurrent = node(redactPathCurrent, key, depth)
iterateNthLevel(wcov[key], level - 1, k, path, afterPath, censor, isCensorFct, censorFctTakesPath, originalKey, n, nv, ov, kIsWc, wck, i, lastPathIndex, redactPathCurrent, store, parent, depth + 1)
}

@@ -234,14 +238,67 @@ }

function restoreNthLevel (key, target, value, level) {
if (level === 0) {
if (has(target, key)) {
target[key] = value
}
return
/**
* @typedef {object} TreeNode
* @prop {TreeNode} [parent] reference to the parent of this node in the tree, or `null` if there is no parent
* @prop {string} key the key that this node represents (key here being part of the path being redacted
* @prop {TreeNode[]} children the child nodes of this node
* @prop {number} depth the depth of this node in the tree
*/
/**
* instantiate a new, empty tree
* @returns {TreeNode}
*/
function tree () {
return { parent: null, key: null, children: [], depth: 0 }
}
/**
* creates a new node in the tree, attaching it as a child of the provided parent node
* if the specified depth matches the parent depth, adds the new node as a _sibling_ of the parent instead
* @param {TreeNode} parent the parent node to add a new node to (if the parent depth matches the provided `depth` value, will instead add as a sibling of this
* @param {string} key the key that the new node represents (key here being part of the path being redacted)
* @param {number} depth the depth of the new node in the tree - used to determing whether to add the new node as a child or sibling of the provided `parent` node
* @returns {TreeNode} a reference to the newly created node in the tree
*/
function node (parent, key, depth) {
if (parent.depth === depth) {
return node(parent.parent, key, depth)
}
for (const objKey in target) {
if (typeof target[objKey] === 'object') {
restoreNthLevel(key, target[objKey], value, level - 1)
}
var child = {
parent,
key,
depth,
children: []
}
parent.children.push(child)
return child
}
/**
* @typedef {object} RestoreInstruction
* @prop {string[]} path a reverse-order path that can be used to find the correct insertion point to restore a `value` for the given `parent` object
* @prop {*} value the value to restore
* @prop {object} target the object to restore the `value` in
*/
/**
* create a restore instruction for the given redactPath node
* generates a path in reverse order by walking up the redactPath tree
* @param {TreeNode} node a tree node that should be at the bottom of the redact path (i.e. have no children) - this will be used to walk up the redact path tree to construct the path needed to restore
* @param {*} value the value to restore
* @param {object} target a reference to the parent object to apply the restore instruction to
* @returns {RestoreInstruction} an instruction used to restore a nested value for a specific object
*/
function restoreInstr (node, value, target) {
let current = node
const path = []
do {
path.push(current.key)
current = current.parent
} while (current.parent != null)
return { path, value, target }
}
{
"name": "fast-redact",
"version": "3.2.0",
"version": "3.3.0",
"description": "very fast object redaction",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -1358,1 +1358,85 @@ 'use strict'

})
test('restores nested wildcard values', ({ end, is }) => {
const o = { a: { b: [{ c: [
{ d: '123' },
{ d: '456' }
] }] } }
const censor = 'censor'
const paths = ['a.b[*].c[*].d']
const redact = fastRedact({ paths, censor, serialize: false })
redact(o)
is(o.a.b[0].c[0].d, censor)
is(o.a.b[0].c[1].d, censor)
redact.restore(o)
is(o.a.b[0].c[0].d, '123')
is(o.a.b[0].c[1].d, '456')
end()
})
test('restores multi nested wildcard values', ({ end, is }) => {
const o = {
a: {
b1: {
c1: {
d1: { e: '123' },
d2: { e: '456' }
},
c2: {
d1: { e: '789' },
d2: { e: '012' }
}
},
b2: {
c1: {
d1: { e: '345' },
d2: { e: '678' }
},
c2: {
d1: { e: '901' },
d2: { e: '234' }
}
}
}
}
const censor = 'censor'
const paths = ['a.*.*.*.e']
const redact = fastRedact({ paths, censor, serialize: false })
redact(o)
is(o.a.b1.c1.d1.e, censor)
is(o.a.b1.c1.d2.e, censor)
is(o.a.b1.c2.d1.e, censor)
is(o.a.b1.c2.d2.e, censor)
is(o.a.b2.c1.d1.e, censor)
is(o.a.b2.c1.d2.e, censor)
is(o.a.b2.c2.d1.e, censor)
is(o.a.b2.c2.d2.e, censor)
redact.restore(o)
is(o.a.b1.c1.d1.e, '123')
is(o.a.b1.c1.d2.e, '456')
is(o.a.b1.c2.d1.e, '789')
is(o.a.b1.c2.d2.e, '012')
is(o.a.b2.c1.d1.e, '345')
is(o.a.b2.c1.d2.e, '678')
is(o.a.b2.c2.d1.e, '901')
is(o.a.b2.c2.d2.e, '234')
end()
})
test('redact multi trailing wildcard', ({ end, is }) => {
const o = { a: { b: { c: 'value' } } }
const censor = 'censor'
const paths = ['a.*.*']
const redact = fastRedact({ paths, censor, serialize: false })
redact(o)
is(o.a.b.c, censor)
redact.restore(o)
is(o.a.b.c, 'value')
end()
})
SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc