Some checks failed
check / check (push) Failing after 1m19s
streamDecrypt discarded the secretstream tag, so a download cut short by a dropped connection decrypted cleanly up to the last whole chunk and was returned as a success. downloadFile and downloadThumbnail then wrote straight to the destination, and runBackup skips any existing non-empty file, so a truncated original was treated as complete on every subsequent run and never repaired. streamDecrypt now tracks the tag of each chunk it pulls and throws if the stream ended on anything other than TAG_FINAL, or if the body carried no chunks at all — Ente always emits at least one chunk, as encryptBlob shows by producing a TAG_FINAL chunk even for zero-length plaintext, so an empty body is a failed transfer rather than an empty file. Both error messages say the stream was truncated. Plaintext is now staged in a temporary sibling file (same directory, so the rename cannot cross a filesystem boundary; random UUID suffix, so concurrent downloads cannot collide) and renamed into place only after the whole stream has decrypted and verified. On any error the temporary file is removed and the original error is rethrown unchanged, so a cleanup failure never masks the real diagnosis. A failed download therefore leaves the destination exactly as it was. Public signatures and the DownloadResult shape are unchanged. The download layer keeps its no-direct-sodium-import shape: TAG_FINAL is re-exported from src/crypto as STREAM_TAG_FINAL, which decryptBlob now uses too. Also moves the pullStreamChunk doc comment off decryptBlob, where it had been sitting. Retry and backoff remain out of scope; they stay the Next Step in TODO.md and are tracked separately.
22 KiB
22 KiB