mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-20 04:09:04 +00:00
Fix out-of-bounds read for truncated percent-escape in opaque host
The opaque-host percent-escape validation guard reads input.codePointAt(i + 2) after only checking 'input.length() - i < 2', so an input such as 'foo://%4' throws StringIndexOutOfBoundsException instead of reporting a validation error. Fix the bounds guard to require two code points after '%' and check ASCII hex digits rather than ASCII digits, matching the URL spec, where invalid percent-escapes in opaque hosts are validation errors, not failures. Signed-off-by: Sagar Chanchal <Sagarr2112@gmail.com>
This commit is contained in:
committed by
Brian Clozel
parent
2aa36fea64
commit
cb9ce4d9e2
@@ -2241,8 +2241,8 @@ final class WhatWgUrlParser {
|
||||
// If input contains a U+0025 (%) and the two code points following it
|
||||
// are not ASCII hex digits, invalid-URL-unit validation error.
|
||||
if (p.validate() && ch == '%' &&
|
||||
(input.length() - i < 2 || !isAsciiDigit(input.codePointAt(i + 1)) ||
|
||||
!isAsciiDigit(input.codePointAt(i + 2)))) {
|
||||
(input.length() - i < 3 || !isAsciiHexDigit(input.codePointAt(i + 1)) ||
|
||||
!isAsciiHexDigit(input.codePointAt(i + 2)))) {
|
||||
p.validationError("Code point \"" + ch + "\" is not a URL unit.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.web.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -63,6 +66,21 @@ class WhatWgUrlParserTests {
|
||||
testParse("file://xn--/p", "file", "xn--", null, "/p", null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseOpaqueHostTruncatedPercentEscape() {
|
||||
// A truncated or non-hex percent-escape in an opaque host is a validation error,
|
||||
// not a failure, and must not read past the end of the input
|
||||
// (see https://url.spec.whatwg.org/#concept-opaque-host-parser).
|
||||
List<String> errors = new ArrayList<>();
|
||||
WhatWgUrlParser.UrlRecord record = WhatWgUrlParser.parse("foo://%4", EMPTY_URL_RECORD, null, errors::add);
|
||||
assertThat(record.host().toString()).isEqualTo("%4");
|
||||
|
||||
record = WhatWgUrlParser.parse("foo://%4x", EMPTY_URL_RECORD, null, errors::add);
|
||||
assertThat(record.host().toString()).isEqualTo("%4x");
|
||||
|
||||
assertThat(errors).isNotEmpty();
|
||||
}
|
||||
|
||||
private void testParse(String input, String scheme, @Nullable String host, @Nullable String port, String path, @Nullable String query, @Nullable String fragment) {
|
||||
WhatWgUrlParser.UrlRecord result = WhatWgUrlParser.parse(input, EMPTY_URL_RECORD, null, null);
|
||||
assertThat(result.scheme()).as("Invalid scheme").isEqualTo(scheme);
|
||||
|
||||
Reference in New Issue
Block a user