From f4ad0dce981015dfd7776c8acf4e7d62e7c3ff09 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 5 Mar 2015 19:54:25 +1100 Subject: [PATCH] 461350 Update HttpParser IllegalCharacter handling to RFC7230 --- .../org/eclipse/jetty/http/HttpParser.java | 100 +++++++++++++----- .../jetty/server/ConnectionOpenCloseTest.java | 4 +- 2 files changed, 78 insertions(+), 26 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index d6437f7d3ce..0826030abd6 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -22,6 +22,7 @@ import static org.eclipse.jetty.http.HttpTokens.*; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.EnumSet; import org.eclipse.jetty.util.ArrayTernaryTrie; @@ -343,42 +344,93 @@ public class HttpParser return _state == state; } + /* ------------------------------------------------------------------------------- */ + enum CharState { ILLEGAL, CR, LF, LEGAL } + private final static CharState[] __charState; + static + { + // token = 1*tchar + // tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" + // / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" + // / DIGIT / ALPHA + // ; any VCHAR, except delimiters + // quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE + // qdtext = HTAB / SP /%x21 / %x23-5B / %x5D-7E / obs-text + // obs-text = %x80-FF + // comment = "(" *( ctext / quoted-pair / comment ) ")" + // ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text + // quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + + __charState=new CharState[256]; + Arrays.fill(__charState,CharState.ILLEGAL); + __charState[LINE_FEED]=CharState.LF; + __charState[CARRIAGE_RETURN]=CharState.CR; + __charState[TAB]=CharState.LEGAL; + __charState[SPACE]=CharState.LEGAL; + + __charState['!']=CharState.LEGAL; + __charState['#']=CharState.LEGAL; + __charState['$']=CharState.LEGAL; + __charState['%']=CharState.LEGAL; + __charState['&']=CharState.LEGAL; + __charState['\'']=CharState.LEGAL; + __charState['*']=CharState.LEGAL; + __charState['+']=CharState.LEGAL; + __charState['-']=CharState.LEGAL; + __charState['.']=CharState.LEGAL; + __charState['^']=CharState.LEGAL; + __charState['_']=CharState.LEGAL; + __charState['`']=CharState.LEGAL; + __charState['|']=CharState.LEGAL; + __charState['~']=CharState.LEGAL; + + __charState['"']=CharState.LEGAL; + + __charState['\\']=CharState.LEGAL; + __charState['(']=CharState.LEGAL; + __charState[')']=CharState.LEGAL; + Arrays.fill(__charState,0x21,0x27+1,CharState.LEGAL); + Arrays.fill(__charState,0x2A,0x5B+1,CharState.LEGAL); + Arrays.fill(__charState,0x5D,0x7E+1,CharState.LEGAL); + Arrays.fill(__charState,0x80,0xFF+1,CharState.LEGAL); + + } + /* ------------------------------------------------------------------------------- */ private byte next(ByteBuffer buffer) { byte ch = buffer.get(); - if (_cr) + CharState s = __charState[0xff & ch]; + switch(s) { - if (ch!=LINE_FEED) - throw new BadMessageException("Bad EOL"); - _cr=false; - return ch; - } + case ILLEGAL: + throw new IllegalCharacterException(_state,ch,buffer); + + case LF: + _cr=false; + break; + + case CR: + if (_cr) + throw new BadMessageException("Bad EOL"); - if (ch>=0 && ch0 && _state.ordinal()