镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Reject "." and ".." as a file name and as a file path's last segment [patch] - #555

Open
matt-edmondson wants to merge 1 commit into
mainfrom
fix/dot-file-names-554
Open

matt-edmondson wants to merge 1 commit into
mainfrom
fix/dot-file-names-554

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #554

What was wrong

IsFileNameAttribute rejected only Path.GetInvalidFileNameChars(). That meant FileName.Create("..") and FileName.Create(".") were accepted. As a result:

  • dir / FileName.Create("..") built a "file" path that names dir's parent, which is outside dir.
  • RemoveExtension() then read the second dot as an extension separator and moved the path to another directory.

The file path types also accepted a final . or .. segment, such as /home/user/.., a/.. or ..

Change

  • IsFileNameAttribute now rejects . and ...
  • A new internal HasFileNameSegmentAttribute is applied to SemanticFilePath<TDerived>. It rejects a final . or .. segment, splitting on / or \ as SemanticFilePath already does. AbsoluteFilePath, RelativeFilePath and FilePath inherit it, so a valid file path always has a valid FileName. The attribute is internal, so the public API is unchanged.
  • DirectoryName and the directory path types are unchanged, because a directory can legitimately be named .. (Paths: dir.Parent / dir.Name names a different directory when the path ends in .. or ., breaking the documented round trip #503).
  • docs/validation-reference.md describes the new rule.

Open question from the issue: home / FileName.Create("") still returns the directory itself, typed as a file. Under the framework's convention, empty input passes attribute validation, so whether this should throw is a design choice. I left it unchanged rather than settle it here.

Tests

Semantics.Test/Paths/DotFileNameTests.cs covers:

  • FileName.Create throws ArgumentException for . and .., and TryCreate returns false.
  • The three file path types reject ./.. as the final segment: absolute, relative, a bare segment, and with / and \ separators.
  • Names that only contain dots still pass: ..., .bashrc, ..hidden, file.. Leading and inner .. segments in file paths are still accepted.
  • DirectoryName, RelativeDirectoryPath and AbsoluteDirectoryPath still accept ./...

I checked the tests against the code without the fix: with the two library changes reverted, all 7 rejection tests fail.

Full suite on Linux / .NET 10: 2069 passed, 0 failed, 14 skipped. One run error is from this environment only: the Semantics.Cpp.Test net9.0 leg needs a .NET 9 runtime, which isn't installed here. Its net10.0 leg passed.


Generated by Claude Code

…[patch]

"." and ".." name a directory on every platform, but IsFileName checked only
for invalid characters, so FileName.Create("..") passed. dir / FileName then
built a "file" path naming dir's parent, outside dir, and RemoveExtension()
read the second dot as an extension separator and moved it to another
directory. The file path types accepted the same final segments.

IsFileName now rejects both. A new internal HasFileNameSegment attribute on
SemanticFilePath rejects them as the last segment of AbsoluteFilePath,
RelativeFilePath and FilePath, so a valid file path always has a valid
FileName. DirectoryName and the directory path types are unchanged (#503).

Fixes #554

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW3W1DsZmnUsfmWXu2k
@sonarqubecloud

Copy link
Copy Markdown

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

Labels

None yet

Projects

None yet

1 participant