Fix the B2C converter.
authorfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 21 Aug 2007 22:15:40 +0000 (22:15 +0000)
committerfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 21 Aug 2007 22:15:40 +0000 (22:15 +0000)
Sometimes data comes in incomplete chunks, and we have to check to see if we have available data, otherwise, when we return -1, the underlying InputStreamReader actually returns 1, and we get garbage in the output data.
I will discuss this on the dev list, since it affects all tomcat versions, at that time I will also provide a test case showing what can happen. Please comment on this fix, if there is something alarming

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@568307 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/tomcat/util/buf/B2CConverter.java

index 1699738..8b2c4dc 100644 (file)
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
+import java.nio.CharBuffer;
 
 /** Efficient conversion of bytes  to character .
  *  
@@ -82,7 +83,7 @@ public class B2CConverter {
     {
        try {
            // read from the reader
-           while( true ) { // conv.ready() ) {
+           while( iis.available()>0 ) { // conv.ready() ) {
                int cnt=conv.read( result, 0, BUFFER_SIZE );
                if( cnt <= 0 ) {
                    // End of stream ! - we may be in a bad state
@@ -211,6 +212,18 @@ final class  ReadConvertor extends InputStreamReader {
        return super.read( cbuf, off, len );
     }
     
+    public final int read() throws IOException {
+        return super.read();
+    }
+    
+    public final int read(CharBuffer cb) throws IOException {
+        return super.read(cb);
+    }
+    
+    public final int read(char[] cbuf) throws IOException {
+        return super.read(cbuf);
+    }
+    
     /** Reset the buffer
      */
     public  final void recycle() {
@@ -254,7 +267,7 @@ final class IntermediateInputStream extends InputStream {
     public  final int read() throws IOException {
        return (pos < end ) ? (buf[pos++] & 0xff) : -1;
     }
-
+    
     // -------------------- Internal methods --------------------
 
     void setBuffer( byte b[], int p, int l ) {
@@ -271,4 +284,32 @@ final class IntermediateInputStream extends InputStream {
        end=pos+len;
     }
 
+    public int available() throws IOException {
+        return end-pos;
+    }
+
+    public boolean markSupported() {
+        return false;
+    }
+
+    public int read(byte[] b) throws IOException {
+        return read(b,0,b.length);
+    }
+
+    /**
+     * Repositions this stream to the position at the time the <code>mark</code> method was last called on this input
+     * stream.
+     *
+     * @throws IOException if this stream has not been marked or if the mark has been invalidated.
+     * @todo Implement this java.io.InputStream method
+     */
+    public synchronized void reset() throws IOException {
+        //not implemented
+    }
+
+    public long skip(long n) throws IOException {
+        //not implemented
+        return 0L;
+    }
+
 }