Skip to content

Commit

Permalink
Merge pull request #112 from preactjs/unmark-guard
Browse files Browse the repository at this point in the history
Fix internal API able to unmark non-marked signals
  • Loading branch information
marvinhagemeister authored Sep 9, 2022
2 parents cd562d1 + 32abe07 commit a4d659e
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/neat-dingos-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@preact/signals-core": patch
---

Fix internal API functions being able to unmark non-invalidated signals
6 changes: 5 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,11 @@ function unmark(signal: Signal<any>) {
// wasn't flagged as needing an update by someone else. This is
// done to make the sweeping logic independent of the order
// in which a dependency tries to unmark a subtree.
if (!signal._requiresUpdate && --signal._pending === 0) {
if (
!signal._requiresUpdate &&
signal._pending > 0 &&
--signal._pending === 0
) {
signal._subs.forEach(unmark);
}
}
Expand Down
15 changes: 15 additions & 0 deletions packages/core/test/signal.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,21 @@ describe("computed()", () => {
a.value = "aa";
expect(spy).to.returned("aa c d");
});

it("should prevent invalid unmark state when called on a source signal", () => {
// Don't allow our internal logic to get in an invalid state, even through
// our own internal API. The bug this tests for is that a source signal
// will be unmarked, leading to all its subscribers `_pending` value to become
// negative. This is invalid and breaks further updates.
const a = signal("a");
const b = computed(() => a.value);
effect(() => b.value);

a._setCurrent()(true, true);

a.value = "aa";
expect(b.value).to.equal("aa");
});
});

describe("error handling", () => {
Expand Down

0 comments on commit a4d659e

Please sign in to comment.