Skip to content

Commit

Permalink
🐛 Make subarray a bit more resilient to poisoning (#5469)
Browse files Browse the repository at this point in the history
**Description**

<!-- Please provide a short description and potentially linked issues
justifying the need for this PR -->

While we may still miss lots of poisoning cases, we try to be closer to
a fully poisoning free implementation for `subarray`. In theory it
should make tests easier to troubleshoot in case the test failed because
of a poisoning it introduced itself.

<!-- * Your PR is fixing a bug or regression? Check for existing issues
related to this bug and link them -->
<!-- * Your PR is adding a new feature? Make sure there is a related
issue or discussion attached to it -->

<!-- You can provide any additional context to help into understanding
what's this PR is attempting to solve: reproduction of a bug, code
snippets... -->

**Checklist** — _Don't delete this checklist and make sure you do the
following before opening the PR_

- [x] The name of my PR follows [gitmoji](https://gitmoji.dev/)
specification
- [x] My PR references one of several related issues (if any)
- [x] New features or breaking changes must come with an associated
Issue or Discussion
- [x] My PR does not add any new dependency without an associated Issue
or Discussion
- [x] My PR includes bumps details, please run `yarn bump` and flag the
impacts properly
- [x] My PR adds relevant tests and they would have failed without my PR
(when applicable)

<!-- More about contributing at
https://github.com/dubzzz/fast-check/blob/main/CONTRIBUTING.md -->

**Advanced**

<!-- How to fill the advanced section is detailed below! -->

- [x] Category: 🐛 Fix a bug
- [x] Impacts: None expected, should be more resilient to poisoning

<!-- [Category] Please use one of the categories below, it will help us
into better understanding the urgency of the PR -->
<!-- * ✨ Introduce new features -->
<!-- * 📝 Add or update documentation -->
<!-- * ✅ Add or update tests -->
<!-- * 🐛 Fix a bug -->
<!-- * 🏷️ Add or update types -->
<!-- * ⚡️ Improve performance -->
<!-- * _Other(s):_ ... -->

<!-- [Impacts] Please provide a comma separated list of the potential
impacts that might be introduced by this change -->
<!-- * Generated values: Can your change impact any of the existing
generators in terms of generated values, if so which ones? when? -->
<!-- * Shrink values: Can your change impact any of the existing
generators in terms of shrink values, if so which ones? when? -->
<!-- * Performance: Can it require some typings changes on user side?
Please give more details -->
<!-- * Typings: Is there a potential performance impact? In which cases?
-->
  • Loading branch information
dubzzz authored Dec 9, 2024
1 parent 1dcc0a8 commit 2f0bb24
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/long-goats-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fast-check": patch
---

🐛 Make `subarray` a bit more resilient to poisoning
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { Map, safeMapGet, safeMapSet } from '../../../utils/globals';

const safeObjectIs = Object.is;

export function isSubarrayOf(source: unknown[], small: unknown[]): boolean {
const countMap = new Map<unknown, number>();
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) {
if (!(index in small)) {
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;
Expand Down
4 changes: 4 additions & 0 deletions packages/fast-check/src/utils/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 2f0bb24

Please sign in to comment.