Name: rmT116609 Date: 09/13/2004
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)
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
While decoding UTF-16 streams when CoderResult coderResult = decoder.decode(in, out, false) is called and if the out buffer is indeed smaller than than needed, the coderResult.isOverflow() returns false while it should return true. OTOH, out.hasRemaining() returns false thus implying that buffer has overflowed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the given program herewith. It returns the correct result for UTF-8 while yields incorrect value for UTF-16
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Encoding UTF-8
out.hasRemaining() false
result.isOverFlow() true
Encoding UTF-16
out.hasRemaining() false
result.isOverFlow() true
ACTUAL -
Encoding UTF-8
out.hasRemaining() false
result.isOverFlow() true
Encoding UTF-16
out.hasRemaining() false
result.isOverFlow() false
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/**
* @author Chandra Patni
* @version 1.0
*/
public class JDKBug {
public static void main(String[] args) throws Exception {
//create a long enough string.. text contains 177
String text = "Java technology is a " +
"portfolio of products that are based on the power of " +
"networks and the idea that the same software should run " +
"on many different kinds of systems and devices.";
decode(text, "UTF-8"); // ok
decode(text, "UTF-16"); // buggy
}
public static void decode(String text, String encoding) throws Exception {
System.out.println("Encoding "+encoding);
byte buffer[] = text.getBytes(encoding);
ByteBuffer in = ByteBuffer.wrap(buffer);
CharBuffer out = CharBuffer.allocate(128); //allocate a buffer < 177
Charset utf16 = Charset.forName(encoding);
CharsetDecoder decoder = utf16.newDecoder();
CoderResult result = decoder.decode(in, out, true);
System.out.println("out.hasRemaining() "+out.hasRemaining());
System.out.println("result.isOverFlow() " + result.isOverflow());
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use out.hasRemaining() instead of CoderResult.isOverflow()
boolean overFlow = coderResult.isOverflow();
if("UTF-16".equalsIgnoreCase(charset.name())) {
//if there is nothing more to add to "out" buffer
//it means it has overflowed.
overFlow = !out.hasRemaining();
}
The fix for this should go into sun.nio.cs.UnicodeDecoder class
94 if (!dst.hasRemaining())
95 return CoderResult.UNDERFLOW;
Should return CoderResult.OVERFLOW
(Incident Review ID: 305705)
======================================================================