You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by as...@apache.org on 2010/10/14 21:01:48 UTC
svn commit: r1022657 - in /httpcomponents/httpcore/trunk: RELEASE_NOTES.txt
httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java
httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java
Author: asankha
Date: Thu Oct 14 19:01:45 2010
New Revision: 1022657
URL: http://svn.apache.org/viewvc?rev=1022657&view=rev
Log:
fix HTTPCORE-239 - The ChunkEncoder could request for a negative buffer limit causing an IllegalArgumentException
Modified:
httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java
httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java
Modified: httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt?rev=1022657&r1=1022656&r2=1022657&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpcore/trunk/RELEASE_NOTES.txt Thu Oct 14 19:01:45 2010
@@ -1,5 +1,9 @@
Changes since 4.1-BETA2
+* [HTTPCORE-239]: The ChunkEncoder could request for a negative buffer limit causing an
+ IllegalArgumentException.
+ Contributed by Asankha Perera <asankha at apache.org>
+
* [HTTPCORE-236]: SSLIOSession#isAppInputReady() does not check the status of the session input
buffer.
Contributed by Dmitry Lukyanov <dlukyanov at ukr.net>
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java?rev=1022657&r1=1022656&r2=1022657&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkEncoder.java Thu Oct 14 19:01:45 2010
@@ -81,15 +81,14 @@ public class ChunkEncoder extends Abstra
} else {
avail = 4096;
}
- if (avail == 0) {
- return 0;
- }
// subtract the length of the longest chunk header
// 12345678\r\n
- avail -= 10;
-
- if (avail < chunk) {
+ // <chunk-data>\r\n
+ avail -= 12;
+ if (avail <= 0) {
+ return 0;
+ } else if (avail < chunk) {
// write no more than 'avail' bytes
chunk = avail;
this.lineBuffer.clear();
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java?rev=1022657&r1=1022656&r2=1022657&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkEncoder.java Thu Oct 14 19:01:45 2010
@@ -28,6 +28,8 @@
package org.apache.http.impl.nio.codecs;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
@@ -103,6 +105,42 @@ public class TestChunkEncoder extends Te
assertEquals("4\r\n1234\r\n0\r\n\r\n", s);
}
+ public void testHttpCore239() throws Exception {
+ FixedByteChannel channel = new FixedByteChannel(16);
+ HttpParams params = new BasicHttpParams();
+ SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16, params);
+ HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+ ChunkEncoder encoder = new ChunkEncoder(channel, outbuf, metrics);
+
+ // fill up the channel
+ channel.write(wrap("0123456789ABCDEF"));
+ // fill up the out buffer
+ outbuf.write(wrap("0123456789ABCDEF"));
+
+ ByteBuffer src = wrap("0123456789ABCDEF");
+ assertEquals(0, encoder.write(src));
+ assertEquals(0, encoder.write(src));
+ assertEquals(0, encoder.write(src));
+
+ // should not be able to copy any bytes, until we flush the channel and buffer
+ channel.reset();
+ outbuf.flush(channel);
+ channel.reset();
+
+ assertEquals(4, encoder.write(src));
+ channel.flush();
+ assertEquals(4, encoder.write(src));
+ channel.flush();
+ assertEquals(4, encoder.write(src));
+ channel.flush();
+ assertEquals(4, encoder.write(src));
+ channel.flush();
+ assertEquals(0, encoder.write(src));
+
+ outbuf.flush(channel);
+ String s = channel.toString("US-ASCII");
+ assertEquals("4\r\n0123\r\n4\r\n4567\r\n4\r\n89AB\r\n4\r\nCDEF\r\n", s);
+ }
public void testChunkExceed() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -114,20 +152,21 @@ public class TestChunkEncoder extends Te
ByteBuffer src = wrap("0123456789ABCDEF");
- assertEquals(6, encoder.write(src));
+ assertEquals(4, encoder.write(src));
assertTrue(src.hasRemaining());
- assertEquals(10, src.remaining());
+ assertEquals(12, src.remaining());
- assertEquals(6, encoder.write(src));
+ assertEquals(4, encoder.write(src));
assertTrue(src.hasRemaining());
- assertEquals(4, src.remaining());
+ assertEquals(8, src.remaining());
assertEquals(4, encoder.write(src));
+ assertEquals(4, encoder.write(src));
assertFalse(src.hasRemaining());
outbuf.flush(channel);
String s = baos.toString("US-ASCII");
- assertEquals("6\r\n012345\r\n6\r\n6789AB\r\n4\r\nCDEF\r\n", s);
+ assertEquals("4\r\n0123\r\n4\r\n4567\r\n4\r\n89AB\r\n4\r\nCDEF\r\n", s);
}
@@ -211,4 +250,50 @@ public class TestChunkEncoder extends Te
}
}
+ public class FixedByteChannel implements WritableByteChannel {
+
+ // collect bytes written for unit test result evaluation
+ private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ private final ByteBuffer buffer;
+
+ public FixedByteChannel(int size) {
+ this.buffer = ByteBuffer.allocate(size);
+ }
+
+ public int write(ByteBuffer src) throws IOException {
+ // copy bytes into baos for result evaluation
+ final int start = src.position();
+ int count = 0;
+ for (int i=start; i<src.limit() && buffer.remaining() > 0; i++) {
+ final byte b = src.get(i);
+ baos.write(b);
+ buffer.put(b);
+ count++;
+ }
+ // update processed position on src buffer
+ src.position(src.position() + count);
+ return count;
+ }
+
+ public boolean isOpen() {
+ return false;
+ }
+
+ public void close() throws IOException {
+ }
+
+ public void flush() {
+ buffer.clear();
+ }
+
+ public void reset() {
+ baos.reset();
+ buffer.clear();
+ }
+
+ public String toString(String encoding) throws UnsupportedEncodingException {
+ return baos.toString(encoding);
+ }
+ }
+
}