Author: markt
Date: Mon May 14 10:50:22 2018
New Revision: 1831556
URL: http://svn.apache.org/viewvc?rev=1831556&view=rev
Log:
Relax Host validation by removing the requirement that the final component of a
FQDN must be alphabetic.
Modified:
tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/LocalStrings.properties
tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParserHost.java
tomcat/trunk/webapps/docs/changelog.xml
Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java?rev=1831556&r1=1831555&r2=1831556&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java Mon
May 14 10:50:22 2018
@@ -667,17 +667,13 @@ public class HttpParser {
pos++;
} while (true);
- if (octetCount != 4) {
+ if (octetCount != 4 || octet < 0 || octet > 255) {
// Might not be an IPv4 address. Could be a host name or a FQDN
with
// fully numeric components. Go back to the start and parse as a
// host / FQDN.
reader.reset();
return readHostDomainName(reader);
}
- if (octet < 0 || octet > 255) {
- throw new IllegalArgumentException(
- sm.getString("http.invalidOctet",
Integer.toString(octet)));
- }
return pos;
}
@@ -788,13 +784,9 @@ public class HttpParser {
static int readHostDomainName(Reader reader) throws IOException {
DomainParseState state = DomainParseState.NEW;
int pos = 0;
- int segmentIndex = 0;
while (state.mayContinue()) {
- state = state.next(reader.read(), segmentIndex);
- if (DomainParseState.PERIOD == state) {
- segmentIndex++;
- }
+ state = state.next(reader.read());
pos++;
}
@@ -836,31 +828,23 @@ public class HttpParser {
}
- private enum AllowsEnd {
- NEVER,
- FIRST,
- ALWAYS
- }
-
-
private enum DomainParseState {
- NEW( true, false, false, AllowsEnd.NEVER, " at the start of"),
- ALL_ALPHA( true, true, true, AllowsEnd.ALWAYS, " after a letter in"),
- ALPHA( true, true, true, AllowsEnd.FIRST, " after a letter in"),
- NUMERIC( true, true, true, AllowsEnd.FIRST, " after a number in"),
- PERIOD( true, false, false, AllowsEnd.NEVER, " after a period in"),
- HYPHEN( true, true, false, AllowsEnd.NEVER, " after a hypen in"),
- COLON( false, false, false, AllowsEnd.NEVER, " after a colon in"),
- END( false, false, false, AllowsEnd.NEVER, " at the end of");
+ NEW( true, false, false, false, " at the start of"),
+ ALPHA( true, true, true, true, " after a letter in"),
+ NUMERIC( true, true, true, true, " after a number in"),
+ PERIOD( true, false, false, false, " after a period in"),
+ HYPHEN( true, true, false, false, " after a hypen in"),
+ COLON( false, false, false, false, " after a colon in"),
+ END( false, false, false, false, " at the end of");
private final boolean mayContinue;
private final boolean allowsHyphen;
private final boolean allowsPeriod;
- private final AllowsEnd allowsEnd;
+ private final boolean allowsEnd;
private final String errorLocation;
private DomainParseState(boolean mayContinue, boolean allowsHyphen,
boolean allowsPeriod,
- AllowsEnd allowsEnd, String errorLocation) {
+ boolean allowsEnd, String errorLocation) {
this.mayContinue = mayContinue;
this.allowsHyphen = allowsHyphen;
this.allowsPeriod = allowsPeriod;
@@ -872,13 +856,9 @@ public class HttpParser {
return mayContinue;
}
- public DomainParseState next(int c, int segmentIndex) {
+ public DomainParseState next(int c) {
if (HttpParser.isAlpha(c)) {
- if (ALL_ALPHA == this || NEW == this || PERIOD == this) {
- return ALL_ALPHA;
- } else {
- return ALPHA;
- }
+ return ALPHA;
} else if (HttpParser.isNumeric(c)) {
return NUMERIC;
} else if (c == '.') {
@@ -889,26 +869,18 @@ public class HttpParser {
Character.toString((char) c), errorLocation));
}
} else if (c == ':') {
- if (allowsEnd == AllowsEnd.ALWAYS ||
- allowsEnd == AllowsEnd.FIRST && segmentIndex == 0) {
+ if (allowsEnd) {
return COLON;
} else {
throw new
IllegalArgumentException(sm.getString("http.invalidCharacterDomain",
Character.toString((char) c), errorLocation));
}
} else if (c == -1) {
- if (allowsEnd == AllowsEnd.ALWAYS ||
- allowsEnd == AllowsEnd.FIRST && segmentIndex == 0) {
+ if (allowsEnd) {
return END;
} else {
- String msg;
- if (allowsEnd == AllowsEnd.NEVER) {
- msg = sm.getString("http.invalidSegmentEndState",
this.name());
- } else {
- // allowsEnd == AllowsEnd.FIRST && segmentIndex > 0
- msg = sm.getString("http.invalidEndState",
this.name());
- }
- throw new IllegalArgumentException(msg);
+ throw new IllegalArgumentException(
+ sm.getString("http.invalidSegmentEndState",
this.name()));
}
} else if (c == '-') {
if (allowsHyphen) {
Modified:
tomcat/trunk/java/org/apache/tomcat/util/http/parser/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/LocalStrings.properties?rev=1831556&r1=1831555&r2=1831556&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/tomcat/util/http/parser/LocalStrings.properties
(original)
+++
tomcat/trunk/java/org/apache/tomcat/util/http/parser/LocalStrings.properties
Mon May 14 10:50:22 2018
@@ -26,7 +26,6 @@ http.illegalCharacterDomain=The characte
http.illegalCharacterIpv4=The character [{0}] is never valid in an IPv4
address.
http.illegalCharacterIpv6=The character [{0}] is never valid in an IPv6
address.
http.invalidCharacterDomain=The character [{0}] is not valid{1} a domain name.
-http.invalidEndState=The state [{0}] is not valid for the end of a domain name.
http.invalidHextet=Invalid hextet. A hextet must consist of 4 or less hex
characters.
http.invalidIpv4Location=The IPv6 address contains an embedded IPv4 address at
an invalid location.
http.invalidOctet=Invalid octet [{0}]. The valid range for IPv4 octets is 0 to
255.
Modified:
tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParserHost.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParserHost.java?rev=1831556&r1=1831555&r2=1831556&view=diff
==============================================================================
---
tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParserHost.java
(original)
+++
tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestHttpParserHost.java
Mon May 14 10:50:22 2018
@@ -56,18 +56,25 @@ public class TestHttpParserHost {
result.add(new Object[] { TestType.IPv4, "0.0.0.0:8080",
Integer.valueOf(7), null} );
result.add(new Object[] { TestType.IPv4, "0", Integer.valueOf(-1),
null} );
// IPv4 - invalid
- result.add(new Object[] { TestType.IPv4, "0.0", Integer.valueOf(-1),
IAE} );
- result.add(new Object[] { TestType.IPv4, "0.0.0", Integer.valueOf(-1),
IAE} );
result.add(new Object[] { TestType.IPv4, ".0.0.0",
Integer.valueOf(-1), IAE} );
result.add(new Object[] { TestType.IPv4, "0.0.0.",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "256.0.0.0",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "0.256.0.0",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "0.0.256.0",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "0.0.0.256",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "0.a.0.0",
Integer.valueOf(-1), IAE} );
result.add(new Object[] { TestType.IPv4, "0..0.0",
Integer.valueOf(-1), IAE} );
result.add(new Object[] { TestType.IPv4, "0]", Integer.valueOf(-1),
IAE} );
// Domain Name - valid
+ result.add(new Object[] { TestType.IPv4, "0.0", Integer.valueOf(-1),
null} );
+ result.add(new Object[] { TestType.IPv4, "0.0:8080",
Integer.valueOf(3), null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.0", Integer.valueOf(-1),
null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.0:8080",
Integer.valueOf(5), null} );
+ result.add(new Object[] { TestType.IPv4, "256.0.0.0",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "256.0.0.0:8080",
Integer.valueOf(9), null} );
+ result.add(new Object[] { TestType.IPv4, "0.256.0.0",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "0.256.0.0:8080",
Integer.valueOf(9), null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.256.0",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.256.0:8080",
Integer.valueOf(9), null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.0.256",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.0.256:8080",
Integer.valueOf(9), null} );
+ result.add(new Object[] { TestType.IPv4, "0.a.0.0",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "0.a.0.0:8080",
Integer.valueOf(7), null} );
result.add(new Object[] { TestType.IPv4, "localhost",
Integer.valueOf(-1), null} );
result.add(new Object[] { TestType.IPv4, "localhost:8080",
Integer.valueOf(9), null} );
result.add(new Object[] { TestType.IPv4, "tomcat.apache.org",
Integer.valueOf(-1), null} );
@@ -80,18 +87,42 @@ public class TestHttpParserHost {
result.add(new Object[] { TestType.IPv4, "foo.0.0.com:8080",
Integer.valueOf(11), null} );
result.add(new Object[] { TestType.IPv4, "1foo.0.0.com",
Integer.valueOf(-1), null} );
result.add(new Object[] { TestType.IPv4, "1foo.0.0.com:8080",
Integer.valueOf(12), null} );
+ result.add(new Object[] { TestType.IPv4, "foo1.0.0.com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "foo1.0.0.com:8080",
Integer.valueOf(12), null} );
+ result.add(new Object[] { TestType.IPv4, "1foo1.0.0.com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "1foo1.0.0.com:8080",
Integer.valueOf(13), null} );
result.add(new Object[] { TestType.IPv4, "1-foo.0.0.com",
Integer.valueOf(-1), null} );
result.add(new Object[] { TestType.IPv4, "1-foo.0.0.com:8080",
Integer.valueOf(13), null} );
result.add(new Object[] { TestType.IPv4, "1--foo.0.0.com",
Integer.valueOf(-1), null} );
result.add(new Object[] { TestType.IPv4, "1--foo.0.0.com:8080",
Integer.valueOf(14), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.1com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.1com:8080",
Integer.valueOf(12), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.com1",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.com1:8080",
Integer.valueOf(12), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.1com1",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.1com1:8080",
Integer.valueOf(13), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.1-com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.1-com:8080",
Integer.valueOf(13), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.1--com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.0.0.1--com:8080",
Integer.valueOf(14), null} );
result.add(new Object[] { TestType.IPv4, "com", Integer.valueOf(-1),
null} );
result.add(new Object[] { TestType.IPv4, "com:8080",
Integer.valueOf(3), null} );
result.add(new Object[] { TestType.IPv4, "0com", Integer.valueOf(-1),
null} );
result.add(new Object[] { TestType.IPv4, "0com:8080",
Integer.valueOf(4), null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.0com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.0com:8080",
Integer.valueOf(8), null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.0.0com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "0.0.0.0com:8080",
Integer.valueOf(10), null} );
result.add(new Object[] { TestType.IPv4, "123", Integer.valueOf(-1),
null} );
result.add(new Object[] { TestType.IPv4, "123:8080",
Integer.valueOf(3), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.bar.0com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "foo.bar.0com:8080",
Integer.valueOf(12), null} );
result.add(new Object[] { TestType.IPv4, "myapp-t.mydomain.com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "myapp-t.mydomain.com:8080",
Integer.valueOf(20), null} );
result.add(new Object[] { TestType.IPv4, "myapp-t.my-domain.com",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4, "myapp-t.my-domain.com:8080",
Integer.valueOf(21), null} );
+ result.add(new Object[] { TestType.IPv4, "myapp-t.my-domain.c-om",
Integer.valueOf(-1), null} );
+ result.add(new Object[] { TestType.IPv4,
"myapp-t.my-domain.c-om:8080", Integer.valueOf(22), null} );
// Domain Name - invalid
result.add(new Object[] { TestType.IPv4, ".", Integer.valueOf(-1),
IAE} );
result.add(new Object[] { TestType.IPv4, ".:8080",
Integer.valueOf(-1), IAE} );
@@ -108,11 +139,6 @@ public class TestHttpParserHost {
result.add(new Object[] { TestType.IPv4, "foo.-bar",
Integer.valueOf(-1), IAE} );
result.add(new Object[] { TestType.IPv4, "foo.^bar",
Integer.valueOf(-1), IAE} );
result.add(new Object[] { TestType.IPv4, "foo.b*ar",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "0.0.0com",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "0.0.0.0com",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "foo.bar.0com",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "foo.bar.0com:8080",
Integer.valueOf(-1), IAE} );
- result.add(new Object[] { TestType.IPv4, "myapp-t.my-domain.c-om",
Integer.valueOf(-1), IAE} );
// IPv6 - valid
result.add(new Object[] { TestType.IPv6, "[::1]", Integer.valueOf(-1),
null} );
result.add(new Object[] { TestType.IPv6, "[::1]:8080",
Integer.valueOf(5), null} );
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1831556&r1=1831555&r2=1831556&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Mon May 14 10:50:22 2018
@@ -105,6 +105,10 @@
is sending AJP messages that are too large for the configured
<code>packetSize</code>. (markt)
</fix>
+ <fix>
+ Relax Host validation by removing the requirement that the final
+ component of a FQDN must be alphabetic. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]