Skip to content

Commit

Permalink
Align processing of trailer headers with standard processing
Browse files Browse the repository at this point in the history
  • Loading branch information
markt-asf committed Oct 9, 2023
1 parent 28c22d7 commit c83fe47
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
8 changes: 7 additions & 1 deletion java/org/apache/coyote/http11/Http11InputBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,12 @@ private boolean fill(boolean block) throws IOException {
*/
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 @@ -972,7 +978,7 @@ private HeaderParseStatus parseHeader() throws IOException {
} 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
15 changes: 14 additions & 1 deletion 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.HexUtils;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.http.parser.HttpParser;
import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.res.StringManager;

Expand Down Expand Up @@ -503,6 +504,13 @@ protected void parseEndChunk() throws IOException {

private boolean parseHeader() 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.
*/

MimeHeaders headers = request.getMimeHeaders();

byte chr = 0;
Expand Down Expand Up @@ -549,6 +557,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 @@ -610,7 +621,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
2 changes: 2 additions & 0 deletions java/org/apache/coyote/http11/filters/LocalStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ chunkedInputFilter.invalidCrlfCRCR=Invalid end of line sequence (CRCR)
chunkedInputFilter.invalidCrlfNoCR=Invalid end of line sequence (No CR before LF)
chunkedInputFilter.invalidCrlfNoData=Invalid end of line sequence (no data available to read)
chunkedInputFilter.invalidHeader=Invalid chunk header
chunkedInputFilter.invalidTrailerHeaderName=Invalid trailer header name (non-token character in name)
chunkedInputFilter.invalidTrailerHeaderValue=Invalid trailer header value (control character in value)
chunkedInputFilter.maxExtension=maxExtensionSize exceeded
chunkedInputFilter.maxTrailer=maxTrailerSize exceeded

Expand Down
3 changes: 3 additions & 0 deletions webapps/docs/changelog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@
<fix>
Avoid rare thread safety issue accessing message digest map. (remm)
</fix>
<fix>
Align validation of HTTP trailer fields with standard fields. (markt)
</fix>
</changelog>
</subsection>
<subsection name="Jasper">
Expand Down

0 comments on commit c83fe47

Please sign in to comment.