Fix fragment parsing for relative URI in RfcUriParser

When parsing a relative URI such as `path2#foo`, RfcUriParser's
SCHEME_OR_PATH state advanced to FRAGMENT without moving the component
index past the `#` character, so the captured fragment included the
entire input (`path2#foo`) instead of just `foo`. As a result,
`toUriString()` produced `path2#path2#foo`.

Update the SCHEME_OR_PATH `#` transition to advance the component
index to `i + 1`, matching the sibling `?` -> QUERY transition in the
same state and every other `-> FRAGMENT` transition in the parser.
URIs with a `/` in the path are unaffected because they leave
SCHEME_OR_PATH for PATH on the first slash; the WhatWG parser already
handled this case correctly.

Closes gh-36762

Signed-off-by: daguimu <daguimu.geek@gmail.com>
This commit is contained in:
daguimu
2026-06-01 10:52:37 +01:00
committed by rstoyanchev
parent 175c1f9437
commit c2191e3ce2
2 changed files with 22 additions and 1 deletions
@@ -270,6 +270,27 @@ class UriComponentsBuilderTests {
UriComponentsBuilder.fromUriString("http://[1abc:2abc:3abc::5ABC:6abc:8080/resource", parserType));
}
@ParameterizedTest // gh-36759
@EnumSource
void fromUriStringRelativeUriWithFragment(ParserType parserType) {
UriComponents result = UriComponentsBuilder.fromUriString("path2#foo", parserType).build();
assertThat(result.getScheme()).isNull();
assertThat(result.getHost()).isNull();
assertThat(result.getPath()).isEqualTo("path2");
assertThat(result.getFragment()).isEqualTo("foo");
assertThat(result.toUriString()).isEqualTo("path2#foo");
}
@ParameterizedTest // gh-36759
@EnumSource
void fromUriStringRelativeUriWithEmptyFragment(ParserType parserType) {
UriComponents result = UriComponentsBuilder.fromUriString("path2#", parserType).build();
assertThat(result.getScheme()).isNull();
assertThat(result.getHost()).isNull();
assertThat(result.getPath()).isEqualTo("path2");
assertThat(result.getFragment()).isNull();
}
@ParameterizedTest // see SPR-11970
@EnumSource
void fromUriStringNoPathWithReservedCharInQuery(ParserType parserType) {