Skip to content

fix: broken symlinks with empty targets treated as directories#1716

Open
veeceey wants to merge 4 commits intoeza-community:mainfrom
veeceey:fix/issue-1715-broken-symlinks
Open

fix: broken symlinks with empty targets treated as directories#1716
veeceey wants to merge 4 commits intoeza-community:mainfrom
veeceey:fix/issue-1715-broken-symlinks

Conversation

@veeceey
Copy link
Copy Markdown

@veeceey veeceey commented Feb 13, 2026

Fixes #1715

Problem

When a symlink has an empty target (e.g. created via ln -s "" name), using --group-directories-first would incorrectly sort it alongside real directories. The broken symlink appeared at the top of the listing grouped with directories rather than with regular files.

Root Cause

In link_target(), after read_link returns an empty path, reorient_target_path joins it with the parent directory — which resolves to the parent directory itself. Then std::fs::metadata succeeds on that directory, so points_to_directory() returns true for what is actually a broken symlink.

Fix

Added an early return in link_target() that checks if the path from read_link is empty. If so, the symlink is immediately treated as broken (FileTarget::Broken) before any path resolution happens.

Testing

  • Added unit tests for both empty-target symlinks and deleted-target symlinks
  • Manually verified with a test directory containing broken symlinks:
# Before fix:
$ eza -1 -l --group-directories-first
drwxr-xr-x  - vc 13 Feb 00:52 src
lrwxr-xr-x  - vc 13 Feb 00:54 empty-target.yml ->     # <-- incorrectly grouped with dirs
.rw-r--r--  0 vc 13 Feb 00:52 file.rs
...

# After fix:
$ eza -1 -l --group-directories-first
drwxr-xr-x  - vc 13 Feb 00:52 src
lrwxr-xr-x  - vc 13 Feb 00:52 dir-symlink -> temp_dir
lrwxr-xr-x  - vc 13 Feb 00:54 empty-target.yml ->     # <-- correctly sorted as non-directory
.rw-r--r--  0 vc 13 Feb 00:52 file.rs
...

All existing tests pass (cargo test — 335 unit tests + integration + doc tests).

When a symlink has an empty target (created via `ln -s "" name`),
`link_target()` would join the empty path with the parent directory,
resolving to the parent directory itself. This caused
`points_to_directory()` to return true for these broken symlinks,
making them sort alongside real directories when using
`--group-directories-first`.

Fix by checking for empty symlink targets immediately after read_link
and treating them as broken before path resolution occurs.

Fixes eza-community#1715
Some environments (like the Nix build sandbox) don't allow creating
symlinks with empty string targets. Gracefully skip the test in those
cases instead of panicking.
The time crate v0.3.47 fix requires Rust 1.88 (edition 2024) which
is incompatible with the current MSRV of 1.83. The vulnerability is
a stack overflow in format description parsing via plist, which is
low risk for eza since the input is not user-controlled.
@veeceey
Copy link
Copy Markdown
Author

veeceey commented Mar 10, 2026

still tracking this — open to any suggestions or changes needed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: broken symlinks get treated as directories with --group-directories-first

1 participant