lib.Uri: Fix local path edge cases #84
Loading…
Reference in a new issue
No description provided.
Delete branch "jan/fix/20260905-lib-uri-fix-path-join-for-empty-authority"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR fixes edge cases with local paths lib.Uri is not prepared for.
lib.Uri: Fix __assemble(): No '://' for relative paths
Assembling a scheme-bearing form always writes '://' after the scheme, even if the input has no authority part. For a schemeless relative path such as '../../local/path', .full then becomes 'file://../../local/path', which re-parses with '..' as the host and '/../local/path' as the path, both entirely broken.
Fix __assemble() to write a bare ':' instead of '://' when the input has no host and a relative path, so the assembled form re-parses back to the same relative path: full of '../../local/path' is now 'file:../../local/path'. Absolute paths and forms with an authority are unchanged.
The assembled 'file:../../local/path' form is a valid URI under the RFC 3986 generic grammar (scheme with a rootless path), while RFC 8089's file URI ABNF admits only an empty or an absolute path. Uri thus trades RFC 8089 conformance for RFC 3986 compatibility: a relative path survives the full-and-reparse cycle unchanged.
lib.Uri: Fix path join for empty authority
__new_with_path() joins base and path with exactly one '/', assuming a trailing '/' in base is a path separator. That assumption breaks for URIs with empty authority, where scheme_plus_authority ends in '://' (e.g. 'file:///tmp/x'): new_replace_path('/etc/hosts') drops the leading slash of the path and produces 'file://etc/hosts', which parses with hostname 'etc' and path '/hosts' instead of path '/etc/hosts'.
Treat a base ending in '://' separately and keep a leading slash in the path, adding one if it is missing.
__new_with_path() joins base and path with exactly one '/', assuming a trailing '/' in base is a path separator. That assumption breaks for URIs with empty authority, where scheme_plus_authority ends in '://' (e.g. 'file:///tmp/x'): new_replace_path('/etc/hosts') drops the leading slash of the path and produces 'file://etc/hosts', which parses with hostname 'etc' and path '/hosts' instead of path '/etc/hosts'. Treat a base ending in '://' separately and keep a leading slash in the path, adding one if it is missing. Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.84.2 Signed-off-by: Jan Lindemann <jan@janware.com>lib.Uri: Fix path join for empty authorityto lib.Uri: Fix local path edge cases