Windows: fix installer crash (electron-builder bump), memry-file paths, and cloud-lock write retries#736
Merged
Merged
Conversation
- Build memry-file URLs through a shared toMemryFileUrl helper: guaranteed leading slash, backslash-to-slash, per-segment percent-encoding, so Windows drive-letter paths no longer land in the URL host and resolve against the install directory (403 'server error' on every PDF/image). - Protocol handler allowlist now compares with the platform separator (isPathInsideDirs); the old dir + '/' prefix never matched Windows backslash paths, so even well-formed URLs were blocked. - Clicking a memry-file attachment link inside a note now opens the file via shell.openPath (vault/userData containment enforced) instead of being silently dropped by the openExternal allowlist. - Log app version and channel at startup for support triage.
Cloud-sync clients (Koofr/OneDrive/Dropbox) and antivirus scanners hold short-lived locks on vault files; atomic-write renames now retry EBUSY/EPERM/EACCES with bounded backoff instead of failing the save.
electron-builder 26.7.0's stock NSIS multiUser.nsh has a System.dll buffer over-read in the per-user fresh-install branch (crashes 0xc0000005 in .onInit — installer dies before any UI on affected machines; fixed upstream in 26.9.0, hardened later). 26.15.6 templates use a bounded lstrcpynW copy instead. Also publish MemryNote-<version>-win.zip alongside the setup exe so support can hand out an installer-free build; latest.yml still lists only the setup exe, so auto-update behavior is unchanged. Landing download API keeps resolving the -setup.exe (fixture test added).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
React Doctor found no new issues. 🎉 Reviewed by React Doctor for commit |
| // Write to the uniquely-named temp file exclusively (wx) with owner-only | ||
| // permissions, so a pre-existing symlink in a shared directory can't be | ||
| // followed and the temp contents can't be read by other users. | ||
| await writeFile(tempPath, content, { encoding: 'utf-8', mode: 0o600, flag: 'wx' }) |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
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.
Why
A Windows user (Reddit r/MemryNote) hit three independent failures, all confirmed from his
main.log+ Event Viewer data:MemryNote-*-setup.execrashes before showing any UI — faulting moduleSystem.dll(NSIS plugin),0xc0000005at offset0x1581, 3× deterministic. Root cause is a buffer over-read in electron-builder 26.7.0's stockmultiUser.nshper-user fresh-install branch (System::Call '*$2(&w${NSIS_MAX_STRLEN} .s)'reading a smallSHGetKnownFolderPathbuffer), fixed upstream in 26.9.0+. It only fires when no HKCUInstallLocationexists — which is why updates worked for years but a clean install after uninstall dies instantly, and why his in-app update "got stuck" (the app quit cleanly; the silent NSIS run crashed after exit).memry-file://local${absolutePath}, soC:was parsed as the URL host and the handler resolved a relative path against the install dir; and the handler allowlist compared withstartsWith(dir + '/'), which never matches Windows backslash paths, so even a well-formed URL was 403'd. His log shows the exact mangled path (...\Programs\@memrydesktop\Users\Leib.000\Koofr\...).memry-file:fell into theopenExternalscheme allowlist and was silently denied (8× in his log).His vault also lives inside a Koofr cloud-sync folder, which holds transient locks on vault files.
What
^26.0.12→^26.15.6— the fixed template uses a boundedlstrcpynWcopy. Verified by cross-building the actual Windows targets on macOS with the new version: realMemryNote-*-setup.exe(146 MB) +MemryNote-*-win.zip(191 MB) produced.MemryNote-<version>-win.zipalongside the setup exe (installer-free escape hatch for support).latest.ymlstill lists only the setup exe, so electron-updater behavior is unchanged; landing download API keeps resolving-setup.exe(fixture test with the zip listed first).toMemryFileUrlrenderer helper (leading slash, backslash→slash, per-segment percent-encoding) replacing both string-concat build sites; round-trip tests for Windows drive paths, spaces, Hebrew filenames, and URL-hostile chars.isPathInsideDirsplatform-separator containment used by the protocol handler and the window-open route; win32 behavior unit-tested (prefix-sibling dirs rejected).shell.openPathafter the same containment check, nevershell.openExternal; unknown schemes still blocked, https still allowed (tests extended).EBUSY/EPERM/EACCESwith bounded backoff (~3 attempts, <1s total) for cloud-sync/AV locks; tests cover transient-then-success, persistent failure, and immediate ENOENT propagation.architecture/local-storage.md, zip fallback inguide/install.md.Proof
docs:impact --strict+docs:buildgreen.memry-file-url.test.ts(8),external-url.test.ts(+10 incl. 5 win32 containment),index.phase2.test.ts(+2 wiring),file-ops.test.ts(retry matrix),apps/landing/api/download.test.ts(zip fixture).Notes
-win.zipwon't exist until the next release runspublish-release.yml; the workflow's staging filter and verify step now require it.