Bug fix for HttpPostMultipartRequestDecoder part decoding with an invalid charset not reported as an ErrorDataDecoderException
Motivation: The current HttpPostMultipartRequestDecoder can decode multipart/form-data parts with a Content-Type that specifies a charset. When this charset is invalid the Charset.forName() throws an unchecked UnsupportedCharsetException. This exception is not catched by the decoder. It should actually be rethrown as an ErrorDataDecoderException, because the developer using the API would expect this validation failure to be reported as such. Modifications: Add a catch block for UnsupportedCharsetException and rethrow it as an ErrorDataDecoderException. Result: UnsupportedCharsetException are now rethrown as ErrorDataDecoderException.
This commit is contained in:
parent
5317c7b648
commit
1257c626d4
@ -32,6 +32,7 @@ import io.netty.util.internal.StringUtil;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.UnsupportedCharsetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -496,6 +497,8 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
|
|||||||
localCharset = Charset.forName(charsetAttribute.getValue());
|
localCharset = Charset.forName(charsetAttribute.getValue());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ErrorDataDecoderException(e);
|
throw new ErrorDataDecoderException(e);
|
||||||
|
} catch (UnsupportedCharsetException e) {
|
||||||
|
throw new ErrorDataDecoderException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Attribute nameAttribute = currentFieldAttributes.get(HttpPostBodyUtil.NAME);
|
Attribute nameAttribute = currentFieldAttributes.get(HttpPostBodyUtil.NAME);
|
||||||
@ -828,6 +831,8 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
|
|||||||
localCharset = Charset.forName(charsetAttribute.getValue());
|
localCharset = Charset.forName(charsetAttribute.getValue());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ErrorDataDecoderException(e);
|
throw new ErrorDataDecoderException(e);
|
||||||
|
} catch (UnsupportedCharsetException e) {
|
||||||
|
throw new ErrorDataDecoderException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentFileUpload == null) {
|
if (currentFileUpload == null) {
|
||||||
|
@ -31,6 +31,7 @@ import io.netty.handler.codec.http.LastHttpContent;
|
|||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.charset.UnsupportedCharsetException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static io.netty.util.ReferenceCountUtil.*;
|
import static io.netty.util.ReferenceCountUtil.*;
|
||||||
@ -406,4 +407,67 @@ public class HttpPostRequestDecoderTest {
|
|||||||
assertFalse(decoder.getBodyHttpDatas().isEmpty());
|
assertFalse(decoder.getBodyHttpDatas().isEmpty());
|
||||||
decoder.destroy();
|
decoder.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultipartRequestWithFileInvalidCharset() throws Exception {
|
||||||
|
final String boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";
|
||||||
|
final DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST,
|
||||||
|
"http://localhost");
|
||||||
|
req.headers().add(HttpHeaders.Names.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; charset=ABCD\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
data + "\r\n" +
|
||||||
|
"--" + boundary + "--\r\n";
|
||||||
|
|
||||||
|
req.content().writeBytes(body.getBytes(CharsetUtil.UTF_8));
|
||||||
|
// Create decoder instance to test.
|
||||||
|
try {
|
||||||
|
new HttpPostRequestDecoder(inMemoryFactory, req);
|
||||||
|
fail("Was expecting an ErrorDataDecoderException");
|
||||||
|
} catch (HttpPostRequestDecoder.ErrorDataDecoderException e) {
|
||||||
|
assertTrue(e.getCause() instanceof UnsupportedCharsetException);
|
||||||
|
} finally {
|
||||||
|
req.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultipartRequestWithFieldInvalidCharset() throws Exception {
|
||||||
|
final String boundary = "dLV9Wyq26L_-JQxk6ferf-RT153LhOO";
|
||||||
|
final DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST,
|
||||||
|
"http://localhost");
|
||||||
|
req.headers().add(HttpHeaders.Names.CONTENT_TYPE, "multipart/form-data; boundary=" + boundary);
|
||||||
|
// Force to use memory-based data.
|
||||||
|
final DefaultHttpDataFactory inMemoryFactory = new DefaultHttpDataFactory(false);
|
||||||
|
final String aData = "some data would be here. the data should be long enough that it " +
|
||||||
|
"will be longer than the original buffer length of 256 bytes in " +
|
||||||
|
"the HttpPostRequestDecoder in order to trigger the issue. Some more " +
|
||||||
|
"data just to be on the safe side.";
|
||||||
|
final String body =
|
||||||
|
"--" + boundary + "\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"root\"\r\n" +
|
||||||
|
"Content-Type: text/plain; charset=ABCD\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
aData +
|
||||||
|
"\r\n" +
|
||||||
|
"--" + boundary + "--\r\n";
|
||||||
|
|
||||||
|
req.content().writeBytes(body.getBytes(CharsetUtil.UTF_8));
|
||||||
|
// Create decoder instance to test.
|
||||||
|
try {
|
||||||
|
new HttpPostRequestDecoder(inMemoryFactory, req);
|
||||||
|
fail("Was expecting an ErrorDataDecoderException");
|
||||||
|
} catch (HttpPostRequestDecoder.ErrorDataDecoderException e) {
|
||||||
|
assertTrue(e.getCause() instanceof UnsupportedCharsetException);
|
||||||
|
} finally {
|
||||||
|
req.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user