http multipart decode with chinese chars should work (#10089)

Motivation:

I am receiving a mutlipart/form_data upload from postman. The filename contains Chinese, and so some invalid chars. We should ensure all of these are removed before trying to decode.

Modification:

Ensure all invalid characters are removed

Result:

Fixes #10087

Co-authored-by: liming.zhang <liming.zhang@luckincoffee.com>
This commit is contained in:
zlm0125 2020-03-06 17:33:58 +08:00 committed by Norman Maurer
parent 118e1c66dc
commit c88d320230
2 changed files with 36 additions and 1 deletions

View File

@ -799,7 +799,7 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
} else if (FILENAME_ENCODED.equals(name)) {
try {
name = HttpHeaderValues.FILENAME.toString();
String[] split = value.split("'", 3);
String[] split = cleanString(value).split("'", 3);
value = QueryStringDecoder.decodeComponent(split[2], Charset.forName(split[0]));
} catch (ArrayIndexOutOfBoundsException | UnsupportedCharsetException e) {
throw new ErrorDataDecoderException(e);

View File

@ -768,4 +768,39 @@ public class HttpPostRequestDecoderTest {
request.headers().set(HttpHeaderNames.CONTENT_TYPE, multipartDataValue);
assertTrue(HttpPostRequestDecoder.isMultipart(request));
}
// see https://github.com/netty/netty/issues/10087
@Test
public void testDecodeWithLanguageContentDispositionFieldParametersForFix() throws Exception {
final String boundary = "952178786863262625034234";
String encoding = "UTF-8";
String filename = "测试test.txt";
String filenameEncoded = URLEncoder.encode(filename, encoding);
final String body = "--" + boundary + "\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename*=\"" +
encoding + "''" + filenameEncoded + "\"\r\n" +
"\r\n" +
"foo\r\n" +
"\r\n" +
"--" + boundary + "--";
final DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.POST,
"http://localhost",
Unpooled.wrappedBuffer(body.getBytes()));
req.headers().add(HttpHeaderNames.CONTENT_TYPE, "multipart/form-data; boundary=" + boundary);
final DefaultHttpDataFactory inMemoryFactory = new DefaultHttpDataFactory(false);
final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(inMemoryFactory, req);
assertFalse(decoder.getBodyHttpDatas().isEmpty());
InterfaceHttpData part1 = decoder.getBodyHttpDatas().get(0);
assertTrue("the item should be a FileUpload", part1 instanceof FileUpload);
FileUpload fileUpload = (FileUpload) part1;
assertEquals("the filename should be decoded", filename, fileUpload.getFilename());
decoder.destroy();
req.release();
}
}