Keep the Windows updater inside its folders and its listed sizes

The direct-install updater trusted every path in hashes.json, so a path
like ..\..\x was downloaded to a file outside the install folder. It
also read each download to the end before checking its length, and the
restart script's log helper could throw before anything was copied,
leaving the user with an app that closed and never came back.

- Refuse any listed path with .., a drive, a rooted or network prefix,
  an empty name, or a name Windows would trim (trailing dot or space).
  The controller and the restart service now share one splitRelativePath.
- Stop reading a download as soon as it passes its listed length and
  fail it like a length mismatch.
- Write-Log swallows its own errors, so an unwritable log no longer
  stops the copy and relaunch. Real failures still end the script.
6d53fdbf22Dara Adedeji committed on 10/21/2026, 6:02:17 PMparentc2ddf79
4 files changedLine totals unavailable