Conversation
coneilen
force-pushed
the
coneilen-microsoft-fix-repository-dialog-reentrancy
branch
2 times, most recently
from
September 23, 2026 04:34
c5e02f4 to
62b53c0
Compare
Acquire the operation modal before shared state is written and release it with defer on every exit path. Add a mutation-sensitive acquisition test covering nested and sequential opens. Signed-off-by: Colin Neilens <coneilen@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
coneilen
force-pushed
the
coneilen-microsoft-fix-repository-dialog-reentrancy
branch
from
September 23, 2026 05:16
62b53c0 to
9f5d8e2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #427.
operation_dialog_activeinWindowsRepositoryDialogs.zigwas written but never read as an entry gate. It was set at:1073with no preceding check, cleared manually at two separate sites (:1092,:1115), and its only read was a wndproc message filter at:1146. Nothing prevented reentry.That mattered because
operation_dialog_stateis a single module-level variable overwritten before the modal is entered (:1053,:1065,:1074,:1075). A second call therefore did not just open a second window: it repointed the already-running modal at a different allocator, parent HWND, and operation, and resetclosed/cancelledunderneath the first modal'swhile (!operation_dialog_state.closed)loop, which later frees throughoperation_dialog_state.allocator. The mismatchedEnableWindow(parent, 0)/EnableWindow(parent, 1)pairing could also leave a window permanently disabled.Approach
Follows the precedent established by PR #420 for
NativeForms.zig:Call sites use
try acquireOperationDialog(); defer releaseOperationDialog();. The two manual clears are removed.deferis the substantive part of the fix, not stylistic: clearing the flag at two hand-placed sites meant any added early return or error path would leak the flag and wedge the dialog permanently.Failure semantic
Fail fast, rejecting the second call before any shared-state write or remote worker start. The clone caller cancels the newly started operation on presentation error, so the rejected request is explicitly terminated and reported rather than silently dropped.
Deferral was considered and rejected: it would require transferring live operation and allocator ownership beyond the lifetime of this synchronous API. This differs deliberately from #420, which retained a deferred update offer because that offer was durable, replayable data rather than a live resource handle.
The guards at
WindowsCodespaceDialog.zig:252andWindowsRepositoryDialogs.zig:619are intentionally untouched; they are synchronous user-initiated opens with a disabled owner window and no durable event, so dropping a duplicate is already correct there.RED: new reentrancy test on unfixed code -> failed with
expected error.OperationDialogAlreadyOpen, found void, confirming a second entry proceeded straight throughGREEN: after adding the acquire/release guard -> all 14 tests pass under pinned Zig 0.15.2, including the 13 pre-existing ones
REGRESSION: the new test asserts the flag is set while held, that a second acquire returns
error.OperationDialogAlreadyOpen, and that it is cleared on release -> a future removal of the guard or of thedeferre-fails itVerification
Run under pinned Zig 0.15.2.
WindowsRepositoryDialogs.zigis one of the orphaned files from #424 whose 13 tests had never been executed by any harness; all 13 pass, so no pre-existing defects were uncovered here. This file is deliberately not wired intoWindowsShell.Tests.ps1in this PR to avoid colliding with #426, which is actively rewriting that file; wiring it should follow #426.