Test Case and 5.5.x patch can be found here.
http://people.apache.org/~fhanik/tomcat/b2c/

This is what is happening

int cnt=conv.read( result, 0, BUFFER_SIZE );
is called with a "while (true)" statement,

When the IntermediateInputStream.read returns -1, the above statement returns 
cnt==1.
So to avoid calling conv.read, we must check to see if we have more bytes to 
read by implementing the available() method, to avoid the inputstream ever 
returning -1.

To test the WAR, just install it in webapps, (you must use IE), then paste the 
characters from the RTF document inside the submit box,
the result, will show two characters that got mangled in the bottom. Need to 
put on your reading glasses for that.

I've also attached the patch for Tomcat 5.5.x, which I intend to apply this 
week, unless someones objects of course.
Filip



[EMAIL PROTECTED] wrote:
Author: fhanik
Date: Tue Aug 21 15:15:40 2007
New Revision: 568307

URL: http://svn.apache.org/viewvc?rev=568307&view=rev
Log:
Fix the B2C converter.
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

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java?rev=568307&r1=568306&r2=568307&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/buf/B2CConverter.java Tue Aug 21 
15:15:40 2007
@@ -22,6 +22,7 @@
 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 @@
     {
        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 @@
        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 @@
     public  final int read() throws IOException {
        return (pos < end ) ? (buf[pos++] & 0xff) : -1;
     }
-
+ // -------------------- Internal methods -------------------- void setBuffer( byte b[], int p, int l ) {
@@ -269,6 +282,34 @@
        pos=mb.getStart();
        len=mb.getLength();
        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;
     }
}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to