[Bug-61048] SXSSF module writes wrong escape sequence for carriage returns

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1804596 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2017-08-09 18:37:14 +00:00
parent 161e6fe60a
commit 58e98bace6
3 changed files with 41 additions and 32 deletions

View File

@ -361,53 +361,43 @@ public class SheetDataWriter implements Closeable {
char c = chars[counter];
switch (c) {
case '<':
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
last = counter + 1;
_out.write("&lt;");
break;
case '>':
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
last = counter + 1;
_out.write("&gt;");
break;
case '&':
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
last = counter + 1;
_out.write("&amp;");
break;
case '"':
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
last = counter + 1;
_out.write("&quot;");
break;
// Special characters
case '\n':
case '\r':
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
_out.write("&#xa;");
last = counter + 1;
break;
case '\r':
writeLastChars(_out, chars, last, counter);
_out.write("&#xd;");
last = counter + 1;
break;
case '\t':
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
_out.write("&#x9;");
last = counter + 1;
break;
case 0xa0:
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
_out.write("&#xa0;");
last = counter + 1;
break;
@ -415,23 +405,17 @@ public class SheetDataWriter implements Closeable {
// YK: XmlBeans silently replaces all ISO control characters ( < 32) with question marks.
// the same rule applies to "not a character" symbols.
if (replaceWithQuestionMark(c)) {
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
_out.write('?');
last = counter + 1;
}
else if (Character.isHighSurrogate(c) || Character.isLowSurrogate(c)) {
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
_out.write(c);
last = counter + 1;
}
else if (c > 127) {
if (counter > last) {
_out.write(chars, last, counter - last);
}
writeLastChars(_out, chars, last, counter);
last = counter + 1;
// If the character is outside of ascii, write the
// numeric value.
@ -447,6 +431,12 @@ public class SheetDataWriter implements Closeable {
}
}
private static void writeLastChars(Writer out, char[] chars, int last, int counter) throws IOException {
if (counter > last) {
out.write(chars, last, counter - last);
}
}
static boolean replaceWithQuestionMark(char c) {
return c < ' ' || ('\uFFFE' <= c && c <= '\uFFFF');
}

View File

@ -78,7 +78,7 @@ public class TestFonts {
311, 312, 313, 318,
348, //Windows 10, 15.6" 3840x2160
362, // Windows 10, 13.3" 1080p high-dpi
398, 399,
377, 398, 399, //Mac
406 // Ubuntu Trusty, 15", 1680x1050
};

View File

@ -72,4 +72,23 @@ public final class TestSheetDataWriter {
IOUtils.closeQuietly(writer);
}
}
@Test
public void testWriteNewLines() throws IOException {
SheetDataWriter writer = new SheetDataWriter();
try {
writer.outputQuotedString("\r\n");
writer.close();
File file = writer.getTempFile();
FileInputStream is = new FileInputStream(file);
String text;
try {
text = new String(IOUtils.toByteArray(is), "UTF-8");
} finally {
is.close();
}
assertEquals("&#xd;&#xa;", text);
} finally {
IOUtils.closeQuietly(writer);
}
}
}