Skip to content

Commit

Permalink
Use UTF-8 for part headers
Browse files Browse the repository at this point in the history
Signed-off-by: Greg Wilkins <gregw@webtide.com>
  • Loading branch information
gregw committed Mar 27, 2018
1 parent 6ac5970 commit a756ac5
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 91 deletions.
111 changes: 22 additions & 89 deletions jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartParser.java
Expand Up @@ -26,87 +26,15 @@
import org.eclipse.jetty.http.HttpParser.RequestHandler;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.SearchPattern;
import org.eclipse.jetty.util.Utf8StringBuilder;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

/* ------------------------------------------------------------ */
/*
* RFC2046 and RFC7578
/** A parser for MultiPart content type.
*
* example:
------WebKitFormBoundaryzWHSH95mOxQwmKln
Content-Disposition: form-data; name="TextField"
Text value:;"' x ----
------WebKitFormBoundaryzWHSH95mOxQwmKln
Content-Disposition: form-data; name="file1"; filename="file with :%22; in name.txt"
Content-Type: text/plain
------WebKitFormBoundaryzWHSH95mOxQwmKln
Content-Disposition: form-data; name="file2"; filename="ManagedSelector.java"
Content-Type: text/x-java
------WebKitFormBoundaryzWHSH95mOxQwmKln
Content-Disposition: form-data; name="Action"
Submit
------WebKitFormBoundaryzWHSH95mOxQwmKln--
*
* BNF:
*
boundary := 0*69<bchars> bcharsnospace
bchars := bcharsnospace / " "
bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
"+" / "_" / "," / "-" / "." /
"/" / ":" / "=" / "?"
dash-boundary := "--" boundary
; boundary taken from the value of
; boundary parameter of the
; Content-Type field.
multipart-body := [preamble CRLF]
dash-boundary transport-padding CRLF
body-part *encapsulation
close-delimiter transport-padding
[CRLF epilogue]
transport-padding := *LWSP-char
; Composers MUST NOT generate
; non-zero length transport
; padding, but receivers MUST
; be able to handle padding
; added by message transports.
encapsulation := delimiter transport-padding
CRLF body-part
delimiter := CRLF dash-boundary
close-delimiter := delimiter "--"
preamble := discard-text
epilogue := discard-text
discard-text := *(*text CRLF) *text
; May be ignored or discarded.
body-part := MIME-part-headers [CRLF *OCTET]
; Lines in a body-part must not start
; with the specified dash-boundary and
; the delimiter must not appear anywhere
; in the body part. Note that the
; semantics of a body-part differ from
; the semantics of a message, as
; described in the text.
OCTET := <any 0-255 octet value>
* @see https://tools.ietf.org/html/rfc2046#section-5.1
* @see https://tools.ietf.org/html/rfc2045
*
*/
public class MultiPartParser
Expand Down Expand Up @@ -161,7 +89,7 @@ public enum State
private boolean _cr;
private ByteBuffer _patternBuffer;

private final StringBuilder _string = new StringBuilder();
private final Utf8StringBuilder _string = new Utf8StringBuilder();
private int _length;

private int _totalHeaderLineLength = -1;
Expand Down Expand Up @@ -303,17 +231,22 @@ private byte getNextByte(ByteBuffer buffer)
/* ------------------------------------------------------------------------------- */
private void setString(String s)
{
_string.setLength(0);
_string.reset();
_string.append(s);
_length = s.length();
}

/* ------------------------------------------------------------------------------- */
/*
* Mime Field strings are treated as UTF-8 as per https://tools.ietf.org/html/rfc7578#section-5.1
*/
private String takeString()
{
_string.setLength(_length);
String s = _string.toString();
_string.setLength(0);
// trim trailing whitespace.
if (s.length()>_length)
s = s.substring(0,_length);
_string.reset();
_length = -1;
return s;
}
Expand Down Expand Up @@ -497,7 +430,7 @@ protected boolean parseMimePartHeaders(ByteBuffer buffer)

if (_fieldValue == null)
{
_string.setLength(0);
_string.reset();
_length = 0;
}
else
Expand Down Expand Up @@ -528,8 +461,8 @@ protected boolean parseMimePartHeaders(ByteBuffer buffer)

// New header
setState(FieldState.IN_NAME);
_string.setLength(0);
_string.append((char)b);
_string.reset();
_string.append(b);
_length = 1;
}
}
Expand All @@ -550,7 +483,7 @@ protected boolean parseMimePartHeaders(ByteBuffer buffer)
break;

default:
_string.append((char)b);
_string.append(b);
_length = _string.length();
break;
}
Expand All @@ -567,7 +500,7 @@ protected boolean parseMimePartHeaders(ByteBuffer buffer)

case LINE_FEED:
_fieldName = takeString();
_string.setLength(0);
_string.reset();
_fieldValue = "";
_length = -1;
break;
Expand All @@ -584,7 +517,7 @@ protected boolean parseMimePartHeaders(ByteBuffer buffer)
switch (b)
{
case LINE_FEED:
_string.setLength(0);
_string.reset();
_fieldValue = "";
_length = -1;

Expand All @@ -596,7 +529,7 @@ protected boolean parseMimePartHeaders(ByteBuffer buffer)
break;

default:
_string.append((char)(0xff & b));
_string.append(b);
_length = _string.length();
setState(FieldState.IN_VALUE);
break;
Expand All @@ -607,7 +540,7 @@ protected boolean parseMimePartHeaders(ByteBuffer buffer)
switch (b)
{
case SPACE:
_string.append((char)(0xff & b));
_string.append(b);
break;

case LINE_FEED:
Expand All @@ -621,7 +554,7 @@ protected boolean parseMimePartHeaders(ByteBuffer buffer)
break;

default:
_string.append((char)(0xff & b));
_string.append(b);
if (b > SPACE || b < 0)
_length = _string.length();
break;
Expand Down
Expand Up @@ -231,10 +231,8 @@ private void checkParts(Collection<Part> parts, Function<String, Part> getPart)
// Evaluate expected contents checksums
for (NameValue expected : multipartExpectations.partSha1sums)
{
System.err.println(expected.name);
Part part = getPart.apply(expected.name);
assertThat("Part[" + expected.name + "]", part, is(notNullValue()));
System.err.println(BufferUtil.toDetailString(BufferUtil.toBuffer(IO.readBytes(part.getInputStream()))));
MessageDigest digest = MessageDigest.getInstance("SHA1");
try (InputStream partInputStream = part.getInputStream();
NoOpOutputStream noop = new NoOpOutputStream();
Expand Down

0 comments on commit a756ac5

Please sign in to comment.