-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
parsing so invalid request lines are rejected sooner. git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk@1767653 13f79535-47bb-0310-9956-ffa450edef68
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,62 +30,10 @@ | |
|
||
public abstract class AbstractInputBuffer<S> implements InputBuffer{ | ||
|
||
protected static final boolean[] HTTP_TOKEN_CHAR = new boolean[128]; | ||
|
||
/** | ||
* The string manager for this package. | ||
*/ | ||
protected static final StringManager sm = | ||
StringManager.getManager(Constants.Package); | ||
|
||
|
||
static { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
markt-asf
Author
Contributor
|
||
for (int i = 0; i < 128; i++) { | ||
if (i < 32) { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == 127) { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '(') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == ')') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '<') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '>') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '@') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == ',') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == ';') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == ':') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '\\') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '\"') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '/') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '[') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == ']') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '?') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '=') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '{') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == '}') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else if (i == ' ') { | ||
HTTP_TOKEN_CHAR[i] = false; | ||
} else { | ||
HTTP_TOKEN_CHAR[i] = true; | ||
} | ||
} | ||
} | ||
protected static final StringManager sm = StringManager.getManager(Constants.Package); | ||
|
||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,8 @@ public class HttpParser { | |
private static final boolean[] IS_SEPARATOR = new boolean[ARRAY_SIZE]; | ||
private static final boolean[] IS_TOKEN = new boolean[ARRAY_SIZE]; | ||
private static final boolean[] IS_HEX = new boolean[ARRAY_SIZE]; | ||
private static final boolean[] IS_NOT_REQUEST_TARGET = new boolean[ARRAY_SIZE]; | ||
private static final boolean[] IS_HTTP_PROTOCOL = new boolean[ARRAY_SIZE]; | ||
|
||
static { | ||
for (int i = 0; i < ARRAY_SIZE; i++) { | ||
|
@@ -65,6 +67,21 @@ public class HttpParser { | |
if ((i >= '0' && i <='9') || (i >= 'a' && i <= 'f') || (i >= 'A' && i <= 'F')) { | ||
IS_HEX[i] = true; | ||
} | ||
|
||
// Not valid for request target. | ||
// Combination of multiple rules from RFC7230 and RFC 3986. Must be | ||
// ASCII, no controls plus a few additional characters excluded | ||
if (IS_CONTROL[i] || i > 127 || | ||
i == ' ' || i == '\"' || i == '#' || i == '<' || i == '>' || i == '\\' || | ||
i == '^' || i == '`' || i == '{' || i == '|' || i == '}') { | ||
This comment has been minimized.
Sorry, something went wrong.
encounter
|
||
IS_NOT_REQUEST_TARGET[i] = true; | ||
} | ||
|
||
// Not valid for HTTP protocol | ||
// "HTTP/" DIGIT "." DIGIT | ||
if (i == 'H' || i == 'T' || i == 'P' || i == '/' || i == '.' || (i >= '0' && i <= '9')) { | ||
IS_HTTP_PROTOCOL[i] = true; | ||
} | ||
} | ||
} | ||
|
||
|
@@ -99,6 +116,7 @@ public static String unquote(String input) { | |
return result.toString(); | ||
} | ||
|
||
|
||
public static boolean isToken(int c) { | ||
// Fast for correct values, slower for incorrect ones | ||
try { | ||
|
@@ -108,15 +126,39 @@ public static boolean isToken(int c) { | |
} | ||
} | ||
|
||
|
||
public static boolean isHex(int c) { | ||
// Fast for correct values, slower for incorrect ones | ||
// Fast for correct values, slower for some incorrect ones | ||
try { | ||
return IS_HEX[c]; | ||
} catch (ArrayIndexOutOfBoundsException ex) { | ||
return false; | ||
} | ||
} | ||
|
||
|
||
public static boolean isNotRequestTarget(int c) { | ||
// Fast for valid request target characters, slower for some incorrect | ||
// ones | ||
try { | ||
return IS_NOT_REQUEST_TARGET[c]; | ||
} catch (ArrayIndexOutOfBoundsException ex) { | ||
return true; | ||
} | ||
} | ||
|
||
|
||
public static boolean isHttpProtocol(int c) { | ||
// Fast for valid HTTP protocol characters, slower for some incorrect | ||
// ones | ||
try { | ||
return IS_HTTP_PROTOCOL[c]; | ||
} catch (ArrayIndexOutOfBoundsException ex) { | ||
return false; | ||
} | ||
} | ||
|
||
|
||
// Skip any LWS and return the next char | ||
static int skipLws(StringReader input, boolean withReset) throws IOException { | ||
|
||
|
1 comment
on commit 779d5d3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies if you are already aware of this and don't care, but Internet Explorer 11 will happily place " and assorted other characters unencoded in the query string. Old versions of Chrome will too, if I recall correctly.
Correct me if I'm wrong, but don't you reject some chars which are only deemed unsafe in obsolete RFC1738 ('"', '{', '}', ''), but OTOH you accept some chars which are deemed unsafe in RFC3986 or even in both ('#', '!', '$', '&', "'", '*', '+')?