Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backport c83fe47 #14

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion java/org/apache/coyote/http11/InternalAprInputBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ private boolean parseHeader() throws IOException {
headers.removeHeader(headers.size() - 1);
skipLine(start);
return true;
} else if (chr != Constants.HT && HttpParser.isControl(chr)) {
} else if (HttpParser.isControl(chr) && chr != Constants.HT) {
// Invalid value
// Delete the header (it will be the most recent one)
headers.removeHeader(headers.size() - 1);
Expand Down
2 changes: 1 addition & 1 deletion java/org/apache/coyote/http11/InternalInputBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ private boolean parseHeader() throws IOException {
// Delete the header (it will be the most recent one)
skipLine(start,true);
return true;
} else if (chr != Constants.HT && HttpParser.isControl(chr)) {
} else if (HttpParser.isControl(chr) && chr != Constants.HT) {
// Invalid value
// Delete the header (it will be the most recent one)
skipLine(start,true);
Expand Down
8 changes: 7 additions & 1 deletion java/org/apache/coyote/http11/InternalNioInputBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@ public boolean parseHeaders()
private HeaderParseStatus parseHeader()
throws IOException {

/*
* Implementation note: Any changes to this method probably need to be echoed in
* ChunkedInputFilter.parseHeader(). Why not use a common implementation? In short, this code uses non-blocking
* reads whereas ChunkedInputFilter using blocking reads. The code is just different enough that a common
* implementation wasn't viewed as practical.
*/
while (headerParsePos == HeaderParsePosition.HEADER_START) {

// Read new bytes if needed
Expand Down Expand Up @@ -651,7 +657,7 @@ private HeaderParseStatus parseHeader()
} else if (prevChr == Constants.CR) {
// Invalid value - also need to delete header
return skipLine(true);
} else if (chr != Constants.HT && HttpParser.isControl(chr)) {
} else if (HttpParser.isControl(chr) && chr != Constants.HT) {
// Invalid value - also need to delete header
return skipLine(true);
} else if (chr == Constants.SP || chr == Constants.HT) {
Expand Down
16 changes: 14 additions & 2 deletions java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.res.StringManager;
import org.apache.tomcat.util.http.parser.HttpParser;

/**
* Chunked input filter. Parses chunked data according to
Expand Down Expand Up @@ -453,7 +454,13 @@ protected void parseEndChunk() throws IOException {
}
}


/*
* Implementation note: Any changes to this method probably need to be echoed in
* Http11InputBuffer.parseHeader(). Why not use a common implementation? In short, this code uses blocking
* reads whereas Http11InputBuffer using non-blocking reads. The code is just different enough that a common
* implementation wasn't viewed as practical.
*/

private boolean parseHeader() throws IOException {

MimeHeaders headers = request.getMimeHeaders();
Expand Down Expand Up @@ -500,6 +507,9 @@ private boolean parseHeader() throws IOException {

if (chr == Constants.COLON) {
colon = true;
} else if (!HttpParser.isToken(chr)) {
// Non-token characters are illegal in header names
throw new IOException(sm.getString("chunkedInputFilter.invalidTrailerHeaderName"));
} else {
trailingHeaders.append(chr);
}
Expand Down Expand Up @@ -561,7 +571,9 @@ private boolean parseHeader() throws IOException {
if (chr == Constants.CR || chr == Constants.LF) {
parseCRLF(true);
eol = true;
} else if (chr == Constants.SP) {
} else if (HttpParser.isControl(chr) && chr != Constants.HT) {
throw new IOException(sm.getString("chunkedInputFilter.invalidTrailerHeaderValue"));
} else if (chr == Constants.SP || chr == Constants.HT) {
trailingHeaders.append(chr);
} else {
trailingHeaders.append(chr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ chunkedInputFilter.invalidHeader=Invalid chunk header
chunkedInputFilter.maxExtension=maxExtensionSize exceeded
chunkedInputFilter.maxTrailer=maxTrailerSize exceeded

inputFilter.maxSwallow=maxSwallowSize exceeded
inputFilter.maxSwallow=maxSwallowSize exceeded

chunkedInputFilter.invalidTrailerHeaderName=Invalid trailer header name (non-token character in name)
chunkedInputFilter.invalidTrailerHeaderValue=Invalid trailer header value (control character in value)
3 changes: 3 additions & 0 deletions webapps/docs/changelog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@
<fix>
Make timing attacks against the Realm implementations harder. (schultz)
</fix>
<fix>
Align validation of HTTP trailer fields with standard fields. (markt)
</fix>
</changelog>
</subsection>
<subsection name="Jasper">
Expand Down
Loading