Skip to content

fix(core): preserve leading slash when partitioning triple-slash URIs - #1865

Merged
ggrossetie merged 1 commit into
asciidoctor:mainfrom
ggrossetie:fix/path-resolver-triple-slash-uri
Jul 30, 2026
Merged

fix(core): preserve leading slash when partitioning triple-slash URIs#1865
ggrossetie merged 1 commit into
asciidoctor:mainfrom
ggrossetie:fix/path-resolver-triple-slash-uri

Conversation

@ggrossetie

Copy link
Copy Markdown
Member

PathResolver#partitionPath() unconditionally filtered out every empty segment produced by splitting a path on /, including the leading empty segment left over when a URI root under-consumes its slashes. UriSniffRx matches at most 2 slashes after the scheme, so for file:///Users/guillaume/foo.png, the root captured is file:// and the 3rd slash survives as a leading "" in the remainder passed to partitionPath().

Dropping that empty segment made joinPath() reassemble file://Users/guillaume/foo.png instead of file:///Users/guillaume/foo.png — a malformed URL whose non-empty "host" (Users) browsers reject outright with Not allowed to load local resource. This surfaced in the asciidoctor-chart browser extension when resolving file:// asset targets, but affects any consumer that resolves a file:///-style absolute path through PathResolver.

The fix mirrors Ruby's String#split('/') semantics, which the original Ruby-to-JS port didn't replicate: Ruby's split drops only trailing empty strings from the result, keeping leading/interior ones. The JS port instead dropped all of them unconditionally. partitionPath() now only trims trailing empty segments, so the leading placeholder segment survives and joinPath() correctly reconstructs the missing slash.

Added regression tests covering partitionPath() and expandPath() on triple-slash file:// URIs (including with a .. segment to resolve), and confirmed http://-style URIs with a real authority are unaffected.

PathResolver#partitionPath() unconditionally filtered out every empty
segment produced by String#split('/'), including the leading empty
segment left over when a URI root under-consumes its slashes (e.g.
UriSniffRx matches at most 2 slashes after the scheme, so "file://"
is the root for "file:///Users/foo" and the 3rd slash survives as a
leading "" in the remainder). Dropping that segment made joinPath()
reassemble "file://Users/foo" instead of "file:///Users/foo" — a
malformed URL whose non-empty "host" (Users) browsers reject outright.

Mirror Ruby's String#split('/') semantics instead: only trailing
empty segments are dropped, leading/interior ones are kept.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ggrossetie
ggrossetie force-pushed the fix/path-resolver-triple-slash-uri branch from cff7878 to ee383ba Compare July 30, 2026 13:12
@ggrossetie
ggrossetie merged commit fae3271 into asciidoctor:main Jul 30, 2026
12 checks passed
@ggrossetie
ggrossetie deleted the fix/path-resolver-triple-slash-uri branch July 30, 2026 13:16
ggrossetie added a commit to asciidoctor/asciidoctor-browser-extension that referenced this pull request Jul 31, 2026
Route the warning through doc.getLogger() instead of console.warn, and
drop the outdated XMLHttpRequest/Manifest V3 explanation since fetch is
now used. Note the real cause (readAsset losing the leading / on
file:// URLs, see asciidoctor/asciidoctor.js#1865) as a FIXME.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant