Skip to content

hts_rename_over() can lose its destination when the retried rename fails #790

Description

@xroche

hts_rename_over() falls back to unlink-then-rename because Windows' rename() refuses an existing target. Between the unlink and the retry there is no copy of the destination left, so any retry failure loses it.

The ordinary Windows shape that hits this: a third party holds src open without FILE_SHARE_DELETE (virus scanner, indexer, backup agent). _wrename fails with ERROR_SHARING_VIOLATION, which _dosmaperr maps to EACCES; src exists, so the gate added in #784 lets the fallback through, the unlink succeeds, and the retry fails the same way. The caller gets HTS_FALSE back with dst already gone.

Two smaller variants of the same window: src removed by an external actor between the existence check and the retry, and a caller whose src and dst sit in different directories where only dst's parent is writable. No current call site can produce the second one — all four build src as dst plus a suffix — but the header documents no such restriction, so a future caller inherits it.

The fix is to rename dst aside rather than unlink it, and drop the aside copy only once the move has succeeded. #784 narrowed the failure classes that reach the unlink at all and documented what survives; closing the window itself needs the aside.

Found reviewing #784. Three of the four destinations are user data: a mirrored file, a finished .wacz, and a rewritten page nothing will re-fetch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions