Fix HttpPostMultipartRequestDecoder.splitMultipartHeader() String index out of range: -1 with empty header
Motivation: A Malformed empty header value (e.g. Content-Type: \r\n) will trigger a String index out of range while trying to parse the multi-part request, using the HttpPostMultipartRequestDecoder. Modification: Ensure that the substring() method is called passing the endValue >= valueStart. In case of an empty header value, the empty header value associated with the header key will be returned. Result: Fixes #7620
This commit is contained in:
parent
c0e84070b0
commit
b640797de1
@ -1467,7 +1467,7 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
|
|||||||
valueStart = HttpPostBodyUtil.findNonWhitespace(sb, colonEnd);
|
valueStart = HttpPostBodyUtil.findNonWhitespace(sb, colonEnd);
|
||||||
valueEnd = HttpPostBodyUtil.findEndOfString(sb);
|
valueEnd = HttpPostBodyUtil.findEndOfString(sb);
|
||||||
headers.add(sb.substring(nameStart, nameEnd));
|
headers.add(sb.substring(nameStart, nameEnd));
|
||||||
String svalue = sb.substring(valueStart, valueEnd);
|
String svalue = (valueStart >= valueEnd) ? StringUtil.EMPTY_STRING : sb.substring(valueStart, valueEnd);
|
||||||
String[] values;
|
String[] values;
|
||||||
if (svalue.indexOf(';') >= 0) {
|
if (svalue.indexOf(';') >= 0) {
|
||||||
values = splitMultipartHeaderValues(svalue);
|
values = splitMultipartHeaderValues(svalue);
|
||||||
|
@ -626,4 +626,34 @@ public class HttpPostRequestDecoderTest {
|
|||||||
req.release();
|
req.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/netty/netty/issues/7620
|
||||||
|
@Test
|
||||||
|
public void testDecodeMalformedEmptyContentTypeFieldParameters() 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: \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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user