RFC 3986 conformance: fixed incorrect parsing of URI authority expressions with ":" character in the userinfo component
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/URIAuthority.java b/httpcore5/src/main/java/org/apache/hc/core5/net/URIAuthority.java
index 920c426..2907f9d 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/URIAuthority.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/URIAuthority.java
@@ -61,7 +61,6 @@
TERMINATORS.set('?');
HOST_SEPARATORS.or(TERMINATORS);
HOST_SEPARATORS.set('@');
- HOST_SEPARATORS.set(':');
PORT_SEPARATORS.or(TERMINATORS);
PORT_SEPARATORS.set(':');
}
@@ -77,31 +76,22 @@
static URIAuthority parse(final CharSequence s, final Tokenizer.Cursor cursor) throws URISyntaxException {
final Tokenizer tokenizer = Tokenizer.INSTANCE;
String userInfo = null;
- String hostName = null;
- String portText = null;
+ final int initPos = cursor.getPos();
final String token = tokenizer.parseContent(s, cursor, HOST_SEPARATORS);
- if (!cursor.atEnd()) {
- final char separator1 = s.charAt(cursor.getPos());
- if (separator1 == '@') {
- userInfo = !TextUtils.isEmpty(token) ? token : null;
- cursor.updatePos(cursor.getPos() + 1);
- hostName = tokenizer.parseContent(s, cursor, PORT_SEPARATORS);
- if (!cursor.atEnd()) {
- final char separator2 = s.charAt(cursor.getPos());
- if (separator2 == ':') {
- cursor.updatePos(cursor.getPos() + 1);
- portText = tokenizer.parseContent(s, cursor, TERMINATORS);
- }
- }
- } else {
- hostName = token;
- if (separator1 == ':') {
- cursor.updatePos(cursor.getPos() + 1);
- portText = tokenizer.parseContent(s, cursor, TERMINATORS);
- }
+ if (!cursor.atEnd() && s.charAt(cursor.getPos()) == '@') {
+ cursor.updatePos(cursor.getPos() + 1);
+ if (!TextUtils.isBlank(token)) {
+ userInfo = token;
}
} else {
- hostName = token;
+ //Rewind
+ cursor.updatePos(initPos);
+ }
+ final String hostName = tokenizer.parseContent(s, cursor, PORT_SEPARATORS);
+ String portText = null;
+ if (!cursor.atEnd() && s.charAt(cursor.getPos()) == ':') {
+ cursor.updatePos(cursor.getPos() + 1);
+ portText = tokenizer.parseContent(s, cursor, TERMINATORS);
}
final int port;
if (!TextUtils.isBlank(portText)) {
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIAuthority.java b/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIAuthority.java
index 3aa1986..1b2a807 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIAuthority.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIAuthority.java
@@ -182,6 +182,8 @@
CoreMatchers.equalTo(new URIAuthority("someuser", "somehost", 8080)));
MatcherAssert.assertThat(URIAuthority.parse("@somehost:8080"),
CoreMatchers.equalTo(new URIAuthority("somehost", 8080)));
+ MatcherAssert.assertThat(URIAuthority.parse("test:test@localhost:38339"),
+ CoreMatchers.equalTo(new URIAuthority("test:test", "localhost", 38339)));
}
@Test