From 4dd52bbb72aa258413a9eec8e75bf1f6a300cd76 Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 11 Dec 2023 19:59:29 -1000 Subject: [PATCH] fix: dont visit non-visitable values in WeakMaps --- src/index.js | 5 ++++- test/index.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 256d391..6399e0e 100644 --- a/src/index.js +++ b/src/index.js @@ -211,6 +211,9 @@ function* walkIterativelyPublic (target, config, maxDepth, visited = new Set(), // as we discover and walk them, new WeakMaps and references may be discovered // the weakMapTracker will continue to iterate them until they are exhausted for (const [childValue, childPath, childMaxDepth] of tracker.flushAll()) { + if (!shouldVisit(childValue, visited, config.shouldWalk)) { + continue; + } yield [childValue, childPath, childMaxDepth]; tracker.visitValue(childValue, childPath, childMaxDepth); const weakMapValueSubTree = walkIteratively(childValue, config, childMaxDepth, visited, childPath); @@ -230,10 +233,10 @@ const walkIteratively = function*(target, config, maxDepth, visited, path) { const props = getAllProps(target, config.shouldInvokeGetters, config.getAdditionalProps); const childMaxDepth = maxDepth - 1; for (const [key, childValue] of props) { - const childPath = [...path, config.generateKey(key, childValue)]; if (!shouldVisit(childValue, visited, config.shouldWalk)) { continue; } + const childPath = [...path, config.generateKey(key, childValue)]; yield [childValue, childPath, childMaxDepth]; const subTreeIterator = walkIteratively(childValue, config, childMaxDepth, visited, childPath); if (config.depthFirst) { diff --git a/test/index.js b/test/index.js index d74a124..1e4882b 100644 --- a/test/index.js +++ b/test/index.js @@ -1,6 +1,12 @@ import test from 'ava'; import LavaTube from '../src/index.js'; +test('non-visitable initial value', t => { + const start = 1; + const allValues = getAll({}, start); + t.deepEqual(allValues, []); +}) + test('exhaustiveWeakMapSearch', t => { const map = new WeakMap(); const obj = {}; @@ -23,6 +29,23 @@ test('exhaustiveWeakMapSearch', t => { ]); }) +test('exhaustiveWeakMapSearch - non-visitable', t => { + const map = new WeakMap(); + const obj = {}; + const nonVistitable = 'abc' + map.set(obj, nonVistitable); + const start = { + map, + obj, + }; + const opts = { + exhaustiveWeakMapSearch: true, + } + + const allValues = getAll(opts, start); + t.false(allValues.includes(nonVistitable)); +}) + test('exhaustiveWeakMapSearch - deep', t => { const firstWeakMap = new WeakMap() let lastWeakMap = firstWeakMap @@ -62,4 +85,12 @@ function find (opts, start, target) { } }); return result; +} + +function getAll (opts, start) { + const results = []; + new LavaTube(opts).walk(start, (value, path) => { + results.push(value); + }); + return results; } \ No newline at end of file