Fix unexpected IllegalReferenceCountException on decode multipart request. (#8575)

Motivation:

Http post request may be encoded as 'multipart/form-data' without any files and consist mixed attributes only.

Modifications:

- Do not double release attributes
- Add unit test

Result:

Code does not throw an IllegalReferenceCountException.
This commit is contained in:
Sergey S. Sergeev 2018-12-14 18:05:15 +03:00 committed by Norman Maurer
parent 250b279bd9
commit 6af0ecc795
2 changed files with 36 additions and 6 deletions

View File

@ -915,19 +915,15 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
*/
@Override
public void destroy() {
checkDestroyed();
// Release all data items, including those not yet pulled
cleanFiles();
destroyed = true;
if (undecodedChunk != null && undecodedChunk.refCnt() > 0) {
undecodedChunk.release();
undecodedChunk = null;
}
// release all data which was not yet pulled
for (int i = bodyListHttpDataRank; i < bodyListHttpData.size(); i++) {
bodyListHttpData.get(i).release();
}
}
/**

View File

@ -24,6 +24,7 @@ import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.DefaultHttpContent;
import io.netty.handler.codec.http.DefaultHttpRequest;
import io.netty.handler.codec.http.DefaultLastHttpContent;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
@ -689,4 +690,37 @@ public class HttpPostRequestDecoderTest {
assertEquals("tmp-0.txt", fileUpload.getFilename());
decoder.destroy();
}
// https://github.com/netty/netty/issues/8575
@Test
public void testMultipartRequest() throws Exception {
String BOUNDARY = "01f136d9282f";
ByteBuf byteBuf = Unpooled.wrappedBuffer(("--" + BOUNDARY + "\n" +
"Content-Disposition: form-data; name=\"msg_id\"\n" +
"\n" +
"15200\n" +
"--" + BOUNDARY + "\n" +
"Content-Disposition: form-data; name=\"msg\"\n" +
"\n" +
"test message\n" +
"--" + BOUNDARY + "--").getBytes());
FullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_0, HttpMethod.POST, "/up", byteBuf);
req.headers().add(HttpHeaderNames.CONTENT_TYPE, "multipart/form-data; boundary=" + BOUNDARY);
HttpPostRequestDecoder decoder =
new HttpPostRequestDecoder(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE),
req,
CharsetUtil.UTF_8);
assertTrue(decoder.isMultipart());
assertFalse(decoder.getBodyHttpDatas().isEmpty());
assertEquals(2, decoder.getBodyHttpDatas().size());
assertEquals("test message", ((Attribute) decoder.getBodyHttpData("msg")).getValue());
assertEquals("15200", ((Attribute) decoder.getBodyHttpData("msg_id")).getValue());
decoder.destroy();
assertEquals(1, req.refCnt());
}
}