Skip to content

Windows: zstd -r follows directory junctions and symlinks, so -r --rm deletes files outside the given folder #4853

Open

Description

@ijbranch

Describe the bug
On Windows, recursive mode ignores reparse points. UTIL_isLink() (programs/util.c) returns 0 on every
non-POSIX platform, and the Windows UTIL_prepareFileList() never checks FILE_ATTRIBUTE_REPARSE_POINT, so a
directory junction or directory symlink inside the tree is entered like an ordinary folder. Unlike the POSIX
build, --no-follow-style behaviour (followLinks = 0, the default for -r) has no effect.

Consequences:

  • zstd -r --rm folder compresses and deletes files that are not under folder at all.
  • A junction pointing at an ancestor recurses until the path length or the stack gives out.

To Reproduce (Windows 11, cmd; mklink /J needs no administrator rights)

> mkdir outside tree
> echo outside the tree> outside\secret.txt
> echo inside> tree\a.txt
> mklink /J tree\link outside
Junction created for tree\link <<===>> outside
> zstd -r --rm -q tree
> dir /s /b outside tree
...\outside\secret.txt.zst
...\tree\a.txt.zst

outside\secret.txt has been compressed and deleted, although only tree was named.

Expected behavior
As on POSIX with the default followLinks = 0: junctions and directory symlinks met during recursion are skipped
(with a message at a suitable display level).

Suggested fix
In the Windows UTIL_prepareFileList(), skip entries whose cFile.dwFileAttributes include
FILE_ATTRIBUTE_REPARSE_POINT when followLinks is 0, and make UTIL_isLink() test that attribute
(GetFileAttributesA) on Windows. (-f sets followLinks = 1, as on POSIX; the reproduction above does not use
-f.)

Desktop

  • OS: Windows 11 Pro (26200), x64
  • Version: v1.5.7; UTIL_isLink() unchanged on dev (2026-10-05). UTIL_prepareFileList() on dev differs only
    by a free(path) leak fix
  • Compiler: MSVC 14.51 (Visual Studio 2026 Build Tools), Release
  • Build system: build/cmake, Visual Studio generator

Environment caveats

  • Found by code review, then reproduced as shown on Windows 11 only (x64), with zstd.exe built from the v1.5.7 source by MSVC 14.51 (Visual Studio 2026 Build Tools) through build/cmake, Win64 Release only. Not tested with MinGW, clang-cl or the official release binaries, nor on Win32.
  • tests/playTests.sh was not run (no POSIX shell environment here).
  • The functions cited were compared with dev (2026-10-05) by source and are unchanged, but dev itself was not built.
  • The analysis was AI-assisted (Claude); every behaviour reported above was reproduced as shown.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions