Skip to content

Bug: baseline-compiler fails on Windows native due to strict URI parsing in loader.go #505

@liketosweep

Description

@liketosweep

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

  1. Clone the repository on a Windows machine.
  2. Build the compiler:
    go build -o baseline-compiler.exe ./cmd
    
  3. 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:

  1. Convert backslashes to forward slashes using filepath.ToSlash().
  2. 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.yamlfile:///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.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions