Skip to content

Case-collision pass misses paths git quotes: the -z and non--z listings never match #4140

Description

@kyle-sexton

What

scripts/check-docs-naming.sh:96 drives the case-collision pass from git ls-files without -z, folds each line with tr, and then compares those folded lines against paths read from a -z listing:

done < <(git ls-files -- docs/)            # non-z, quoted
...
done < <(git ls-files -z -- docs/)         # -z, raw

Without -z, git quotes any path carrying a character outside the printable ASCII range: an embedded newline, a tab, a non-ASCII byte. Such a path arrives as "docs/a\nb.md", quotes and escape included, while the -z listing yields the raw bytes. The two can never match, so a case collision involving such a path is silently missed.

Found during a fresh-context review of PR #4133, which generalizes this script into plugins/docs-hygiene/skills/generate-file-name-gate/templates/check-file-names.sh.tmpl. The template carries the same code, so every emitted consumer gate inherits it. Pre-existing in the original; the generalization neither introduced it nor made it worse.

Impact

Narrow but real, and exactly where it matters least forgivingly: the collision pass exists because two paths differing only by case cannot coexist on a case-insensitive checkout, so a missed collision is a tree that corrupts on Windows or macOS checkout rather than a style nit. A repository whose docs/ carries a non-ASCII filename gets no protection for it.

Fix shape

Drive both loops from the same -z listing. The outer loop needs the folded duplicates, which sort/uniq -d can still produce from a NUL-delimited stream:

git ls-files -z -- docs/ | tr '\0' '\n' ...

is not the fix (it re-introduces the newline ambiguity). Reading the -z stream into an array once, folding in the shell, and finding duplicates there keeps one source of truth for the path bytes.

Fix both copies together, or land #4139 first so the drift test holds them together afterwards.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions