Skip to content

Commit 901e86d

Browse files
authored
Merge pull request #12591 from jetty/fix/12.0.x/npe-httpuri-decodedpath
Issue #12577 - Fixing NPE from HttpURI.getDecodedPath() if path doesn't exist
2 parents a8aec30 + 89adf5b commit 901e86d

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -497,18 +497,21 @@ public static Stream<Arguments> decodePathTests()
497497
{"http://localhost:9000/x\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32", "/x\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32", "/x\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32", EnumSet.noneOf(Violation.class)},
498498
{"http://localhost:9000/\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32", "/\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32", "/\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32\uD83C\uDF32", EnumSet.noneOf(Violation.class)},
499499
// @checkstyle-enable-check : AvoidEscapedUnicodeCharactersCheck
500+
501+
// An empty (null) authority
502+
{"http://", null, null, null}
500503
}).map(Arguments::of);
501504
}
502505

503506
@ParameterizedTest
504507
@MethodSource("decodePathTests")
505-
public void testDecodedPath(String input, String canonicalPath, String decodedPath, EnumSet<Violation> expected)
508+
public void testDecodedPath(String input, String expectedCanonicalPath, String expectedDecodedPath, EnumSet<Violation> expected)
506509
{
507510
try
508511
{
509512
HttpURI uri = HttpURI.from(input);
510-
assertThat("Canonical Path", uri.getCanonicalPath(), is(canonicalPath));
511-
assertThat("Decoded Path", uri.getDecodedPath(), is(decodedPath));
513+
assertThat("Canonical Path", uri.getCanonicalPath(), is(expectedCanonicalPath));
514+
assertThat("Decoded Path", uri.getDecodedPath(), is(expectedDecodedPath));
512515

513516
EnumSet<Violation> ambiguous = EnumSet.copyOf(expected);
514517
ambiguous.retainAll(EnumSet.complementOf(EnumSet.of(Violation.UTF16_ENCODINGS, Violation.BAD_UTF8_ENCODING)));
@@ -523,9 +526,9 @@ public void testDecodedPath(String input, String canonicalPath, String decodedPa
523526
}
524527
catch (Exception e)
525528
{
526-
if (decodedPath != null)
529+
if (expectedDecodedPath != null)
527530
e.printStackTrace();
528-
assertThat(decodedPath, nullValue());
531+
assertThat(expectedDecodedPath, nullValue());
529532
}
530533
}
531534

jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,11 +471,14 @@ public static StringBuilder encodeString(StringBuilder buf,
471471
/**
472472
* Decodes a percent-encoded URI path (assuming UTF-8 characters) and strips path parameters.
473473
* @param path The URI path to decode
474+
* @return the decoded path (or null if input path is null)
474475
* @see #canonicalPath(String)
475476
* @see #normalizePath(String)
476477
*/
477478
public static String decodePath(String path)
478479
{
480+
if (path == null)
481+
return null;
479482
return decodePath(path, 0, path.length());
480483
}
481484

@@ -484,11 +487,14 @@ public static String decodePath(String path)
484487
* @param path A String holding the URI path to decode
485488
* @param offset The start of the URI within the path string
486489
* @param length The length of the URI within the path string
490+
* @return the decoded path (or null if input path is null)
487491
* @see #canonicalPath(String)
488492
* @see #normalizePath(String)
489493
*/
490494
public static String decodePath(String path, int offset, int length)
491495
{
496+
if (path == null)
497+
return null;
492498
try
493499
{
494500
Utf8StringBuilder builder = null;

jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/URIUtilTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ public static Stream<Arguments> decodePathSource()
135135

136136
// Test for null character (real world ugly test case)
137137
Arguments.of("/%00/", "/%00/", "/\u0000/"),
138+
Arguments.of(null, null, null),
138139

139140
// Deprecated Microsoft Percent-U encoding
140141
Arguments.of("abc%u3040", "abc\u3040", "abc\u3040"),
@@ -179,10 +180,10 @@ public void testCanonicalEncodedPath(String encodedPath, String canonicalPath, S
179180

180181
@ParameterizedTest(name = "[{index}] {0}")
181182
@MethodSource("decodePathSource")
182-
public void testDecodePath(String encodedPath, String canonicalPath, String decodedPath)
183+
public void testDecodePath(String encodedPath, String expectedCanonicalPath, String expectedDecodedPath)
183184
{
184185
String path = URIUtil.decodePath(encodedPath);
185-
assertEquals(decodedPath, path);
186+
assertEquals(expectedDecodedPath, path);
186187
}
187188

188189
public static Stream<Arguments> decodeBadPathSource()

0 commit comments

Comments
 (0)