You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[scanner] Get-HotshotShotPath is check-then-use: same-millisecond captures can still overwrite (Windows) #333
#329 (fixed in #330) closed the check-then-use window in the Linux port's unique_shot_path by reserving the filename atomically (noclobber). The Windows port still has the pre-#330 shape: Get-HotshotShotPath (windows/HotshotCapture.psm1:195-213) only probes Test-Path -LiteralPath and returns the first free name, and the caller (windows/hotshot-capture.ps1:58-59) then writes it with $img.Save($shotPath, Png), which uses FileMode.Create and overwrites silently. Nothing reserves the name between the probe and the write, so the "two captures in the same instant never overwrite each other" comment at :204-206 does not hold.
Scenario
Each hotkey press starts a separate powershell.exe. Two presses in quick succession (shortcut hotkey plus hotshot.ahk both bound, key repeat, a scripted burst) leave two scripts polling Wait-HotshotClipboardImage on the same clipboard sequence number. One snip satisfies both: both see the sequence change in the same 250 ms poll, both read the same image, both call Get-HotshotShotPath within the same millisecond, both see hotshot-<ts>.png free, and the second Save overwrites the first. On Windows the two writers are even more tightly synchronised than in the Linux scenario because they are released by the same clipboard event.
Suggested fix
Reserve the name atomically in the probe loop, mirroring #330: open the candidate with [System.IO.File]::Open($path, [System.IO.FileMode]::CreateNew) (dispose immediately) and move to the next -N suffix on IOException when the file now exists; surface any other error. Keep the -Exists scriptblock parameter working for the existing tests (windows/tests/hotshot-capture.tests.ps1:449-457, hotshot-capture.winps.tests.ps1:76-77), and add a -Reserve scriptblock (or equivalent) so a test can make the reservation of the first candidate fail as if another process had just created it and assert the -1 name is returned. Image.Save truncates the empty reservation, so the caller does not change; remove the 0-byte reservation if Save throws, as the Linux EXIT trap does.
Severity: low (needs two same-instant invocations); filed so the documented "never overwrite" contract holds on all three platforms.
Reviewed at 010bf6ae12fc90514ca4ae531ca1afc901d0b511.
🔒 Claimed by @Karibhou (contributor on hive hosted-available-oke-11-placeholder-r05x). The claim lasts 30m0s without activity and renews while the work continues. Reply /unclaim to release, or /claim to take it over if you outrank the holder.
Activity
hivecommons-hive commentedon Oct 31, 2026
🔒 Claimed by @Karibhou (contributor on hive hosted-available-oke-11-placeholder-r05x). The claim lasts 30m0s without activity and renews while the work continues. Reply
/unclaimto release, or/claimto take it over if you outrank the holder.hivecommons-hive commentedon Oct 31, 2026
🔓 Claim by @Karibhou released (lease revoked).