Background
As part of fixing #186 (Windows junctions not properly resolved), we replaced fs::canonicalize() with GetLongPathNameW in norm_case() to avoid resolving junctions/symlinks.
During this fix, we discovered that norm_case() was doing more than just case normalization - it was also:
- Converting relative paths to absolute paths
- Stripping trailing path separators (to match
canonicalize behavior)
- Normalizing case
Current State
The function is defined in crates/pet-fs/src/path.rs and is called from ~20+ locations across the codebase:
crates/pet-conda/src/environment_locations.rs
crates/pet-poetry/src/environment_locations.rs
crates/pet-windows-store/src/environments.rs
crates/pet-pipenv/src/lib.rs
crates/pet-global-virtualenvs/src/lib.rs
crates/pet-python-utils/src/fs_cache.rs
crates/pet-windows-registry/src/environments.rs
- And more...
Concern
The Windows Registry stores paths with trailing backslashes (e.g., C:\...\x64\). The old fs::canonicalize() silently stripped these. When we switched to GetLongPathNameW, we had to explicitly add trailing slash stripping to maintain backward compatibility.
This raises questions:
- Should path sources (like Windows Registry) sanitize their own output?
- Should
norm_case() be split into separate functions with clear responsibilities?
- Are there other implicit behaviors from
canonicalize() that callers depend on?
Suggested Audit Tasks
Related
Background
As part of fixing #186 (Windows junctions not properly resolved), we replaced
fs::canonicalize()withGetLongPathNameWinnorm_case()to avoid resolving junctions/symlinks.During this fix, we discovered that
norm_case()was doing more than just case normalization - it was also:canonicalizebehavior)Current State
The function is defined in
crates/pet-fs/src/path.rsand is called from ~20+ locations across the codebase:crates/pet-conda/src/environment_locations.rscrates/pet-poetry/src/environment_locations.rscrates/pet-windows-store/src/environments.rscrates/pet-pipenv/src/lib.rscrates/pet-global-virtualenvs/src/lib.rscrates/pet-python-utils/src/fs_cache.rscrates/pet-windows-registry/src/environments.rsConcern
The Windows Registry stores paths with trailing backslashes (e.g.,
C:\...\x64\). The oldfs::canonicalize()silently stripped these. When we switched toGetLongPathNameW, we had to explicitly add trailing slash stripping to maintain backward compatibility.This raises questions:
norm_case()be split into separate functions with clear responsibilities?canonicalize()that callers depend on?Suggested Audit Tasks
norm_case()call sites to understand what each caller actually needsnormalize_case()- Just case normalizationnormalize_path()- Full path normalization (relative→absolute, trailing slashes, case)Related