diff --git a/.changeset/long-goats-kiss.md b/.changeset/long-goats-kiss.md new file mode 100644 index 00000000000..174aed37ddc --- /dev/null +++ b/.changeset/long-goats-kiss.md @@ -0,0 +1,5 @@ +--- +"fast-check": patch +--- + +🐛 Make `subarray` a bit more resilient to poisoning diff --git a/packages/fast-check/src/arbitrary/_internals/helpers/IsSubarrayOf.ts b/packages/fast-check/src/arbitrary/_internals/helpers/IsSubarrayOf.ts index 852681f0ff1..4e2c916290c 100644 --- a/packages/fast-check/src/arbitrary/_internals/helpers/IsSubarrayOf.ts +++ b/packages/fast-check/src/arbitrary/_internals/helpers/IsSubarrayOf.ts @@ -1,12 +1,16 @@ +import { Map, safeMapGet, safeMapSet } from '../../../utils/globals'; + +const safeObjectIs = Object.is; + export function isSubarrayOf(source: unknown[], small: unknown[]): boolean { const countMap = new Map(); let countMinusZero = 0; for (const sourceEntry of source) { - if (Object.is(sourceEntry, -0)) { + if (safeObjectIs(sourceEntry, -0)) { ++countMinusZero; } else { - const oldCount = countMap.get(sourceEntry) || 0; - countMap.set(sourceEntry, oldCount + 1); + const oldCount = safeMapGet(countMap, sourceEntry) || 0; + safeMapSet(countMap, sourceEntry, oldCount + 1); } } for (let index = 0; index !== small.length; ++index) { @@ -14,13 +18,13 @@ export function isSubarrayOf(source: unknown[], small: unknown[]): boolean { return false; } const smallEntry = small[index]; - if (Object.is(smallEntry, -0)) { + if (safeObjectIs(smallEntry, -0)) { if (countMinusZero === 0) return false; --countMinusZero; } else { - const oldCount = countMap.get(smallEntry) || 0; + const oldCount = safeMapGet(countMap, smallEntry) || 0; if (oldCount === 0) return false; - countMap.set(smallEntry, oldCount - 1); + safeMapSet(countMap, smallEntry, oldCount - 1); } } return true; diff --git a/packages/fast-check/src/utils/globals.ts b/packages/fast-check/src/utils/globals.ts index 5ec2efaf0f1..52930808cba 100644 --- a/packages/fast-check/src/utils/globals.ts +++ b/packages/fast-check/src/utils/globals.ts @@ -64,6 +64,10 @@ const SencodeURIComponent: typeof encodeURIComponent = // eslint-disable-next-line @typescript-eslint/no-non-null-assertion typeof encodeURIComponent !== 'undefined' ? encodeURIComponent : undefined!; export { SencodeURIComponent as encodeURIComponent }; +const SMap = Map; +export { SMap as Map }; +const SSymbol = Symbol; +export { SSymbol as Symbol }; // Various remarks concerning this part of the file: // - Functions accepting a variadic number of arguments ALWAYS use (...args) instead of (a, b)