From adc74777b3790486adc2cd03fd0a154095e95cf4 Mon Sep 17 00:00:00 2001 From: Dhamoder Nalla Date: Tue, 1 Aug 2023 14:40:37 +0000 Subject: [PATCH] 8305763: Parsing a URI with an underscore goes through a silent exception, negatively impacting performance Backport-of: 749d4801937ac145f945765f0ba0980bbccf384f --- src/java.base/share/classes/java/net/URI.java | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/classes/java/net/URI.java b/src/java.base/share/classes/java/net/URI.java index 863bb771350..7d1bf935363 100644 --- a/src/java.base/share/classes/java/net/URI.java +++ b/src/java.base/share/classes/java/net/URI.java @@ -3193,6 +3193,7 @@ private int parseAuthority(int start, int n) boolean serverChars; boolean regChars; + boolean skipParseException; if (scan(p, n, "]") > p) { // contains a literal IPv6 address, therefore % is allowed @@ -3208,15 +3209,28 @@ private int parseAuthority(int start, int n) return n; } + // When parsing a URI, skip creating exception objects if the server-based + // authority is not required and the registry parse is successful. + // + skipParseException = (!requireServerAuthority && regChars); if (serverChars) { // Might be (probably is) a server-based authority, so attempt // to parse it as such. If the attempt fails, try to treat it // as a registry-based authority. try { - q = parseServer(p, n); - if (q < n) - failExpecting("end of authority", q); - authority = input.substring(p, n); + q = parseServer(p, n, skipParseException); + if (q < n) { + if (skipParseException) { + userInfo = null; + host = null; + port = -1; + q = p; + } else { + failExpecting("end of authority", q); + } + } else { + authority = input.substring(p, n); + } } catch (URISyntaxException x) { // Undo results of failed parse userInfo = null; @@ -3254,7 +3268,7 @@ private int parseAuthority(int start, int n) // [@][:] // - private int parseServer(int start, int n) + private int parseServer(int start, int n, boolean skipParseException) throws URISyntaxException { int p = start; @@ -3294,7 +3308,7 @@ private int parseServer(int start, int n) } else { q = parseIPv4Address(p, n); if (q <= p) - q = parseHostname(p, n); + q = parseHostname(p, n, skipParseException); p = q; } @@ -3311,7 +3325,10 @@ private int parseServer(int start, int n) } p = q; } + } else if (p < n && skipParseException) { + return p; } + if (p < n) failExpecting("port number", p); @@ -3416,7 +3433,7 @@ private int parseIPv4Address(int start, int n) { // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum // toplabel = alpha | alpha *( alphanum | "-" ) alphanum // - private int parseHostname(int start, int n) + private int parseHostname(int start, int n, boolean skipParseException) throws URISyntaxException { int p = start; @@ -3444,9 +3461,12 @@ private int parseHostname(int start, int n) p = q; } while (p < n); - if ((p < n) && !at(p, n, ':')) + if ((p < n) && !at(p, n, ':')) { + if (skipParseException) { + return p; + } fail("Illegal character in hostname", p); - + } if (l < 0) failExpecting("hostname", start);