Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@naoNao89
Copy link
Contributor

fixes #8910

The problem is that dirname("/home/dos/.") was giving "/home" when it should return "/home/dos". This broke homeshick for the reporter because their symlinks ended up pointing to the wrong places.

Turns out Rust's Path::parent() normalizes the path automatically, so it treats "/home/dos/." the same as "/home/dos/" - both just return "/home". Not what we want for POSIX compliance.

The fix is pretty straightforward: check if the path ends with "/." before calling parent(), and if it does, just strip those two characters off and return what's left. Special case for "/." which becomes "/".

I followed the same pattern basename used when they hit this exact #8373. Used byte-level checking so non-UTF-8 paths still work fine.

Added a bunch of tests covering the basic case, edge cases like double slashes, emoji paths, and made sure nothing broke for existing behavior.

@naoNao89 naoNao89 force-pushed the fix-dirname-trailing-dot branch from b9a43db to c78014a Compare October 15, 2025 03:25
Fixes uutils#8910

Match POSIX/GNU behavior where dirname("/home/dos/.") returns
"/home/dos" instead of "/home". This aligns with the basename fix
from uutils#8373 (c5268a8).

The issue occurs because Rust's Path::parent() normalizes paths,
treating "/home/dos/." the same as "/home/dos/", both returning
"/home" as the parent. This breaks tools like homeshick that rely
on correct dirname behavior for symlink generation.

Solution:
- Detect paths ending in "/." using byte-level checking
- Strip the "/." suffix manually before path operations
- Handle edge case: "/." -> "/"
- Preserve non-UTF-8 path handling with platform-specific code
- Add comprehensive tests covering edge cases

Tests added:
- Basic "/." handling (5 test cases)
- Flag interaction with -z/--zero
- Multiple paths with mixed "/." suffixes
- Edge cases: double slashes, dots in middle
- Unicode/emoji paths
- Non-UTF-8 paths (Unix only)
- Backward compatibility verification (7 test cases)
@naoNao89 naoNao89 force-pushed the fix-dirname-trailing-dot branch from c78014a to df6ef34 Compare October 15, 2025 03:30
Previously, when encountering invalid UTF-8 on non-Unix platforms for paths ending in /., the code would incorrectly print the original path unchanged instead of falling through to normal dirname logic.

This fix restructures the code to track whether the /. suffix was successfully handled, and falls through to Path::parent() logic when it cannot be handled (either because the path doesnt end with /. or because UTF-8 conversion failed on non-Unix).
@github-actions
Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/tail/overlay-headers (fails in this run but passes in the 'main' branch)

- Remove duplicate test case for /usr/local/bin/. in test_trailing_dot
- Consolidate test_existing_behavior_preserved by removing redundant tests
- Extract trailing dot handling into dedicated handle_trailing_dot function
- Eliminates handled_trailing_dot boolean for cleaner code flow

Addresses feedback from cakebaker on PR uutils#8911
@github-actions
Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/tail/overlay-headers (fails in this run but passes in the 'main' branch)

Wrap POSIX and GNU documentation URLs in angle brackets to comply
with rustdoc requirements (-D rustdoc::bare-urls)
@github-actions
Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/tail/overlay-headers (fails in this run but passes in the 'main' branch)

@sylvestre sylvestre merged commit 88bc1c5 into uutils:main Oct 16, 2025
121 checks passed
naoNao89 added a commit to naoNao89/coreutils that referenced this pull request Oct 25, 2025
Fix dirname handling of paths ending in `/.`
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: GNU and uutils dirname handles paths ending in "/." differently

3 participants