From ae8715116c8a3e0c3d0f50c86b3772437f46590c Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Mon, 27 Jul 2015 12:15:23 +0200 Subject: [PATCH] [#4010] Correctly handle whitespaces in HttpPostMultipartRequestDecoder Motivation: Due not using a cast we insert 32 and not a whitespace into the String. Modifications: Correclty cast to char. Result: Correct handling of whitespaces. --- .../handler/codec/http/HttpConstants.java | 5 ++++ .../HttpPostMultipartRequestDecoder.java | 11 +++---- .../multipart/HttpPostRequestDecoderTest.java | 29 +++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpConstants.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpConstants.java index 643af73b2c..7fde88974c 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpConstants.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpConstants.java @@ -71,6 +71,11 @@ public final class HttpConstants { */ public static final Charset DEFAULT_CHARSET = CharsetUtil.UTF_8; + /** + * Horizontal space + */ + public static final char SP_CHAR = (char) SP; + private HttpConstants() { // Unused } diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java index a06784687c..ff8dbc38f1 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java @@ -48,6 +48,7 @@ import static io.netty.buffer.Unpooled.*; * */ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequestDecoder { + /** * Factory used to create InterfaceHttpData */ @@ -1732,15 +1733,15 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest for (int i = 0; i < field.length(); i++) { char nextChar = field.charAt(i); if (nextChar == HttpConstants.COLON) { - sb.append(HttpConstants.SP); + sb.append(HttpConstants.SP_CHAR); } else if (nextChar == HttpConstants.COMMA) { - sb.append(HttpConstants.SP); + sb.append(HttpConstants.SP_CHAR); } else if (nextChar == HttpConstants.EQUALS) { - sb.append(HttpConstants.SP); + sb.append(HttpConstants.SP_CHAR); } else if (nextChar == HttpConstants.SEMICOLON) { - sb.append(HttpConstants.SP); + sb.append(HttpConstants.SP_CHAR); } else if (nextChar == HttpConstants.HT) { - sb.append(HttpConstants.SP); + sb.append(HttpConstants.SP_CHAR); } else if (nextChar == HttpConstants.DOUBLE_QUOTE) { // nothing added, just removes it } else { diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoderTest.java index 14b3b02762..aacd8c090e 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/multipart/HttpPostRequestDecoderTest.java @@ -347,4 +347,33 @@ public class HttpPostRequestDecoderTest { assertFalse(decoder.getBodyHttpDatas().isEmpty()); decoder.destroy(); } + + @Test + public void testFilenameContainingSemicolon2() throws Exception { + final String boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO"; + final DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, + "http://localhost"); + req.headers().add(HttpHeaderNames.CONTENT_TYPE, "multipart/form-data; boundary=" + boundary); + // Force to use memory-based data. + final DefaultHttpDataFactory inMemoryFactory = new DefaultHttpDataFactory(false); + final String data = "asdf"; + final String filename = "tmp;0.txt"; + final String body = + "--" + boundary + "\r\n" + + "Content-Disposition: form-data; name=\"file\"; filename=\"" + filename + "\"\r\n" + + "Content-Type: image/gif\r\n" + + "\r\n" + + data + "\r\n" + + "--" + boundary + "--\r\n"; + + req.content().writeBytes(body.getBytes(CharsetUtil.UTF_8.name())); + // Create decoder instance to test. + final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(inMemoryFactory, req); + assertFalse(decoder.getBodyHttpDatas().isEmpty()); + InterfaceHttpData part1 = decoder.getBodyHttpDatas().get(0); + assertTrue(part1 instanceof FileUpload); + FileUpload fileUpload = (FileUpload) part1; + assertEquals("tmp 0.txt", fileUpload.getFilename()); + decoder.destroy(); + } }