BUG 38230 Fixed. Confirmed that the typecast from byte to char caused errors. Added testcase.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@369729 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jason Height 2006-01-17 09:08:23 +00:00
parent 4fb1a3e4fe
commit 1d00be095e
3 changed files with 46 additions and 5 deletions

View File

@ -249,7 +249,10 @@ public class RecordInputStream extends InputStream
for (int i=0;i<length;i++) { for (int i=0;i<length;i++) {
if ((remaining() == 0) && (isContinueNext())) if ((remaining() == 0) && (isContinueNext()))
nextRecord(); nextRecord();
char ch = (char)readByte(); byte b = readByte();
//Typecast direct to char from byte with high bit set causes all ones
//in the high byte of the char (which is of course incorrect)
char ch = (char)( (short)0xff & (short)b );
buf.append(ch); buf.append(ch);
} }
return buf.toString(); return buf.toString();

View File

@ -230,19 +230,21 @@ public class UnicodeString
in.setAutoContinue(false); in.setAutoContinue(false);
StringBuffer tmpString = new StringBuffer(field_1_charCount); StringBuffer tmpString = new StringBuffer(field_1_charCount);
int stringCharCount = field_1_charCount; int stringCharCount = field_1_charCount;
boolean isUncompressed = ((field_2_optionflags & 1) == 0); boolean isCompressed = ((field_2_optionflags & 1) == 0);
while (stringCharCount != 0) { while (stringCharCount != 0) {
if (in.remaining() == 0) { if (in.remaining() == 0) {
if (in.isContinueNext()) { if (in.isContinueNext()) {
in.nextRecord(); in.nextRecord();
//Check if we are now reading, compressed or uncompressed unicode. //Check if we are now reading, compressed or uncompressed unicode.
byte optionflags = in.readByte(); byte optionflags = in.readByte();
isUncompressed = ((optionflags & 1) == 0); isCompressed = ((optionflags & 1) == 0);
} else } else
throw new RecordFormatException("Expected continue record."); throw new RecordFormatException("Expected continue record.");
} }
if (isUncompressed) { if (isCompressed) {
char ch = (char)in.readByte(); //Typecast direct to char from byte with high bit set causes all ones
//in the high byte of the char (which is of course incorrect)
char ch = (char)( (short)0xff & (short)in.readByte() );
tmpString.append(ch); tmpString.append(ch);
} else { } else {
char ch = (char) in.readShort(); char ch = (char) in.readShort();

View File

@ -91,5 +91,41 @@ public class TestUnicodeWorkbook extends TestCase {
c3 = r.getCell((short)3); c3 = r.getCell((short)3);
assertEquals(c3.getCellFormula(), formulaString); assertEquals(c3.getCellFormula(), formulaString);
} }
/** Tests Bug38230
* That a Umlat is written and then read back.
* It should have been written as a compressed unicode.
*
*
*
*/
public void testUmlatReadWrite() throws Exception {
HSSFWorkbook wb = new HSSFWorkbook();
//Create a unicode sheet name (euro symbol)
HSSFSheet s = wb.createSheet("test");
HSSFRow r = s.createRow(0);
HSSFCell c = r.createCell((short)1);
c.setCellValue(new HSSFRichTextString("\u00e4"));
//Confirm that the sring will be compressed
assertEquals(c.getRichStringCellValue().getUnicodeString().getOptionFlags(), 0);
File tempFile = TempFile.createTempFile("umlat", "test.xls");
FileOutputStream stream = new FileOutputStream(tempFile);
wb.write(stream);
wb = null;
FileInputStream in = new FileInputStream(tempFile);
wb = new HSSFWorkbook(in);
//Test the sheetname
s = wb.getSheet("test");
assertNotNull(s);
c = r.getCell((short)1);
assertEquals(c.getRichStringCellValue().getString(), "\u00e4");
}
} }