Skip to content

Commit

Permalink
fix(NSIS): prevent partial overwrites during Nsis7z::Extract (#6547)
Browse files Browse the repository at this point in the history
`Nsis7z::Extract` ignores the errors when copying the files and thus can
leave us with the app that has old asar and bindings, but new assets. In
addition to that, the app will firmly believe that it is still running
an old version and would attempt to repeatedly auto-update until fixed,
leading to excessive bandwidth use and very unhappy customers.

This change extracts the contents of 7z archive into a separate
directory before attempting to copy them with `CopyFiles` function that
(unlike `Nsis7z::Extract`) does detect and report failures. To make our
lives easier the `CopyFiles` will also erase all files on a failure so
after retrying a few times we will ultimately have to fallback to old 7z
extraction directly into output folder.
  • Loading branch information
indutny-signal authored Jan 12, 2022
1 parent 5648e05 commit bea51d6
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/nervous-cherries-speak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"app-builder-lib": patch
---

fix(nsis): Prevent partial updates from happening
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,45 @@
!macroend

!macro extractUsing7za FILE
Nsis7z::Extract "${FILE}"
Push $OUTDIR
CreateDirectory "$PLUGINSDIR\7z-out"
ClearErrors
SetOutPath "$PLUGINSDIR\7z-out"
Nsis7z::Extract "${FILE}"
Pop $R0
SetOutPath $R0

# Retry counter
StrCpy $R1 0

LoopExtract7za:
IntOp $R1 $R1 + 1

CopyFiles /SILENT "$PLUGINSDIR\7z-out\*" $OUTDIR
IfErrors 0 DoneExtract7za

${if} $R1 > 1
DetailPrint `Can't modify "${PRODUCT_NAME}"'s files.`
${if} $R1 < 5
# Try copying a few times before giving up
Goto LoopExtract7za
${else}
MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeClosed)" /SD IDCANCEL IDRETRY RetryExtract7za
${endIf}

# CopyFiles will remove all overwritten files when it encounters an
# issue and make app non-launchable. Extract over from the archive
# ignoring the failures so at least we will partially update and the
# app would start.
Nsis7z::Extract "${FILE}"
Quit
${else}
Goto LoopExtract7za
${endIf}

RetryExtract7za:
Sleep 1000
Goto LoopExtract7za

DoneExtract7za:
!macroend

0 comments on commit bea51d6

Please sign in to comment.