Description
When baseline-compiler is built and executed natively on Windows (tested under MinGW64/Git Bash and PowerShell), it panics immediately while attempting to load control families. The failure originates in cmd/pkg/baseline/loader.go, where fetcher.URI{} is used to resolve YAML source paths. This struct internally delegates to Go's url.Parse(), which strictly expects RFC-3986 URIs. Windows absolute paths of the form C:\Users\... are not valid URIs — the parser misidentifies the drive letter as a URI host and the remainder as an invalid port, causing a fatal crash.
Steps to Reproduce
- Clone the repository on a Windows machine.
- Build the compiler:
go build -o baseline-compiler.exe ./cmd
- Run any compile command against a local catalog, e.g.:
./baseline-compiler.exe compile --crosswalk-output reverse.md
Actual Behavior
The process panics with an invalid-port parse error. Go's url.Parse() interprets the Windows drive letter C: as a URI host:port component:
ERROR: error loading controls families: invalid source "file://C:\Users\...\OSPS-AC.yaml": parse
"file://C:\...": invalid port ":\Users\..." after host
If the drive letter is avoided by using a relative path, the error shifts to an unsupported scheme:
ERROR: error loading controls families: unsupported URI scheme
Expected Behavior
The compiler should transparently normalise Windows-style absolute paths into valid file:/// URIs before passing them to fetcher.URI{}, allowing YAML catalog files to be resolved and loaded correctly on all platforms without any manual workaround.
Root Cause Analysis
In cmd/pkg/baseline/loader.go, source paths are passed directly to fetcher.URI{} with no platform-aware normalisation. fetcher.URI{} expects a well-formed Unix-style file:/// URI. On Windows:
- Backslash separators (
\) are not valid URI delimiters.
- The
C: drive letter prefix is parsed as a host:port pair by url.Parse(), triggering the invalid port panic.
- There is no sanitisation or fallback step before the URI is constructed.
Suggested Fix
Introduce a cross-platform path-normalisation helper in loader.go that is applied before any path is passed to fetcher.URI{}. Two steps are required:
- Convert backslashes to forward slashes using
filepath.ToSlash().
- Prepend the
file:/// scheme when the path is an absolute local path with no existing URI scheme.
func toFileURI(path string) string {
cleaned := filepath.ToSlash(filepath.Clean(path))
if filepath.IsAbs(path) && !strings.Contains(cleaned, "://") {
return "file:///" + strings.TrimPrefix(cleaned, "/")
}
return cleaned
}
This normalises C:\Users\foo\OSPS-AC.yaml → file:///C:/Users/foo/OSPS-AC.yaml, which is the format Go's url.Parse() accepts correctly on all platforms.
Environment
| Field |
Value |
| OS |
Windows 11 (also reproduced on Windows 10) |
| Shell |
MinGW64 / Git Bash, PowerShell |
| Go version |
1.22+ |
| Affected file |
cmd/pkg/baseline/loader.go |
| Affected struct |
fetcher.URI{} |
Note: I have investigated this issue and have a working local patch ready. I am happy to open a PR with the fix as soon as a maintainer confirms this approach is acceptable.
Description
When
baseline-compileris built and executed natively on Windows (tested under MinGW64/Git Bash and PowerShell), it panics immediately while attempting to load control families. The failure originates incmd/pkg/baseline/loader.go, wherefetcher.URI{}is used to resolve YAML source paths. This struct internally delegates to Go'surl.Parse(), which strictly expects RFC-3986 URIs. Windows absolute paths of the formC:\Users\...are not valid URIs — the parser misidentifies the drive letter as a URI host and the remainder as an invalid port, causing a fatal crash.Steps to Reproduce
Actual Behavior
The process panics with an invalid-port parse error. Go's
url.Parse()interprets the Windows drive letterC:as a URI host:port component:If the drive letter is avoided by using a relative path, the error shifts to an unsupported scheme:
Expected Behavior
The compiler should transparently normalise Windows-style absolute paths into valid
file:///URIs before passing them tofetcher.URI{}, allowing YAML catalog files to be resolved and loaded correctly on all platforms without any manual workaround.Root Cause Analysis
In
cmd/pkg/baseline/loader.go, source paths are passed directly tofetcher.URI{}with no platform-aware normalisation.fetcher.URI{}expects a well-formed Unix-stylefile:///URI. On Windows:\) are not valid URI delimiters.C:drive letter prefix is parsed as a host:port pair byurl.Parse(), triggering theinvalid portpanic.Suggested Fix
Introduce a cross-platform path-normalisation helper in
loader.gothat is applied before any path is passed tofetcher.URI{}. Two steps are required:filepath.ToSlash().file:///scheme when the path is an absolute local path with no existing URI scheme.This normalises
C:\Users\foo\OSPS-AC.yaml→file:///C:/Users/foo/OSPS-AC.yaml, which is the format Go'surl.Parse()accepts correctly on all platforms.Environment