JDK-6211132 : (cs) CharsetDecoder.decode(ByteBuffer) may return wrong result
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2004-12-21
  • Updated: 2011-02-16
  • Resolved: 2005-02-10
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.4.2_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04)
Java HotSpot(TM) Client VM (build 1.4.2_05-b04, mixed mode)
 
A DESCRIPTION OF THE PROBLEM :
When use some CharsetDecoder which averageCharsPerByte less than 1 and decode 1 byte remain ByteBuffer, may return wrong result. May also appeared in CharsetEncoder.encode.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. declare a String only have 1 byte, such as "a".
2. declare a Charset which averageCharsPerByte property is less than 1, such as GBK.
3. use charset to encode the string.
4. use charset to decode the result in step 3.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the string declared in step 1
ACTUAL -
nothing

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
String s = "a";
Charset charset = Charset.forName("GBK");
ByteBuffer buffer = charset.encode(s);
System.out.println(charset.decode(buffer));
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
public CharBuffer decode(ByteBuffer buffer) throws CharacterCodingException {
        CharsetDecoder decoder = getDecoder();

        int n = 0;
        if (buffer.remaining() > 0) {
            n = (int) (buffer.remaining() * decoder.averageCharsPerByte());
            if (n == 0)
                n = (int) (buffer.remaining() * decoder.maxCharsPerByte());
        }
        CharBuffer result = CharBuffer.allocate(n);
        if (n == 0)
            return result;

        decoder.reset();
        while (true) {
            CoderResult cr = buffer.hasRemaining() ? decoder.decode(buffer,
                    result, true) : decoder.flush(result);
            if (cr.isUnderflow())
                break;
            if (cr.isOverflow()) {
                n *= 2;
                result.flip();
                result = CharBuffer.allocate(n).put(result);
                continue;
            }
           cr.throwException();
        }
        result.flip();
        return result;
    }
###@###.### 2004-12-21 10:48:03 GMT