diff options
Diffstat (limited to 'poi')
5 files changed, 63 insertions, 11 deletions
diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 1569553682..fd4f97365d 100644 --- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -1020,8 +1020,6 @@ public class HSSFCell extends CellBase { _sheet.getSheet().setActiveCellCol(col); } - private static final DataFormatter DATA_FORMATTER = new DataFormatter(); - /** * Returns a string representation of the cell * @@ -1045,8 +1043,14 @@ public class HSSFCell extends CellBase { case FORMULA: return getCellFormula(); case NUMERIC: + if (DateUtil.isCellDateFormatted(this)) { + DataFormatter df = new DataFormatter(); + df.setUseCachedValuesForFormulaCells(true); + return df.formatCellValue(this); + } + return Double.toString(getNumericCellValue()); case STRING: - return DATA_FORMATTER.formatCellValue(this); + return getRichStringCellValue().toString(); default: return "Unknown Cell Type: " + getCellType(); } diff --git a/poi/src/main/java/org/apache/poi/util/IOUtils.java b/poi/src/main/java/org/apache/poi/util/IOUtils.java index 430e895557..ff86043a54 100644 --- a/poi/src/main/java/org/apache/poi/util/IOUtils.java +++ b/poi/src/main/java/org/apache/poi/util/IOUtils.java @@ -108,6 +108,14 @@ public final class IOUtils { } /** + * @return The maximum number of bytes that should be possible to be allocated in one step. + * @since 5.4.1 + */ + public static int getByteArrayMaxOverride() { + return BYTE_ARRAY_MAX_OVERRIDE; + } + + /** * Peeks at the first 8 bytes of the stream. Returns those bytes, but * with the stream unaffected. Requires a stream that supports mark/reset, * or a PushbackInputStream. If the stream has >0 but <8 bytes, @@ -209,6 +217,27 @@ public final class IOUtils { } /** + * Reads up to {@code length} bytes from the input stream, and returns the bytes read. + * + * @param stream The byte stream of data to read. + * @param length The maximum length to read, use {@link Integer#MAX_VALUE} to read the stream + * until EOF + * @param maxLength if the input is equal to/longer than {@code maxLength} bytes, + * then throw an {@link IOException} complaining about the length. + * use {@link Integer#MAX_VALUE} to disable the check - if {@link #setByteArrayMaxOverride(int)} is + * set then that max of that value and this maxLength is used + * @return A byte array with the read bytes. + * @throws IOException If reading data fails or EOF is encountered too early for the given length. + * @throws RecordFormatException If the requested length is invalid. + * @since POI 5.4.1 + */ + public static byte[] toByteArray(InputStream stream, final long length, final int maxLength) throws IOException { + return toByteArray(stream, + length > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) length, + maxLength, true, length != Integer.MAX_VALUE); + } + + /** * Reads the input stream, and returns the bytes read. * * @param stream The byte stream of data to read. @@ -227,15 +256,12 @@ public final class IOUtils { private static byte[] toByteArray(InputStream stream, final int length, final int maxLength, final boolean checkEOFException, final boolean isLengthKnown) throws IOException { - if (length < 0 || maxLength < 0) { - throw new RecordFormatException("Can't allocate an array of length < 0"); - } final int derivedMaxLength = Math.max(maxLength, BYTE_ARRAY_MAX_OVERRIDE); if ((length != Integer.MAX_VALUE) || (derivedMaxLength != Integer.MAX_VALUE)) { checkLength(length, derivedMaxLength); } - final int derivedLen = isLengthKnown ? Math.min(length, derivedMaxLength) : derivedMaxLength; + final int derivedLen = isLengthKnown && length >= 0 ? Math.min(length, derivedMaxLength) : derivedMaxLength; final int byteArrayInitLen = calculateByteArrayInitLength(isLengthKnown, length, derivedMaxLength); final int internalBufferLen = DEFAULT_BUFFER_SIZE; try (UnsynchronizedByteArrayOutputStream baos = UnsynchronizedByteArrayOutputStream.builder().setBufferSize(byteArrayInitLen).get()) { @@ -254,7 +280,7 @@ public final class IOUtils { throwRecordTruncationException(derivedMaxLength); } - if (checkEOFException && derivedLen != Integer.MAX_VALUE && totalBytes < derivedLen) { + if (checkEOFException && length >= 0 && derivedLen != Integer.MAX_VALUE && totalBytes < derivedLen) { throw new EOFException("unexpected EOF - expected len: " + derivedLen + " - actual len: " + totalBytes); } diff --git a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestCell.java b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestCell.java index de2c4ad7c6..ceef38cd18 100644 --- a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestCell.java +++ b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestCell.java @@ -365,6 +365,9 @@ public abstract class BaseTestCell { dateStyle.setDataFormat(formatId); r.getCell(7).setCellStyle(dateStyle); + // null rich text + r.createCell(8).setCellValue(factory.createRichTextString(null)); // blank + assertEquals("FALSE", r.getCell(0).toString(), "Boolean"); assertEquals("TRUE", r.getCell(1).toString(), "Boolean"); assertEquals("1.5", r.getCell(2).toString(), "Numeric"); @@ -375,6 +378,7 @@ public abstract class BaseTestCell { // toString on a date-formatted cell displays dates as dd-MMM-yyyy, which has locale problems with the month String dateCell1 = r.getCell(7).toString(); assertEquals("2/2/10 0:00", dateCell1); + assertEquals("", r.getCell(8).toString(), "Blank"); //Write out the file, read it in, and then check cell values try (Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1)) { @@ -388,6 +392,7 @@ public abstract class BaseTestCell { assertEquals("", r.getCell(6).toString(), "Blank"); String dateCell2 = r.getCell(7).toString(); assertEquals(dateCell1, dateCell2, "Date"); + assertEquals("", r.getCell(8).toString(), "Blank"); } } } diff --git a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java index 29f62da235..64f585608a 100644 --- a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java +++ b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java @@ -531,7 +531,7 @@ public abstract class BaseTestConditionalFormatting { // Sanity check data assertEquals("Values", s.getRow(0).getCell(0).toString()); - assertEquals("10", s.getRow(2).getCell(0).toString()); + assertEquals(10.0, s.getRow(2).getCell(0).getNumericCellValue()); // Check we found all the conditional formatting rules we should have SheetConditionalFormatting sheetCF = s.getSheetConditionalFormatting(); diff --git a/poi/src/test/java/org/apache/poi/util/TestIOUtils.java b/poi/src/test/java/org/apache/poi/util/TestIOUtils.java index bb12f9932e..7f026adc74 100644 --- a/poi/src/test/java/org/apache/poi/util/TestIOUtils.java +++ b/poi/src/test/java/org/apache/poi/util/TestIOUtils.java @@ -110,8 +110,25 @@ final class TestIOUtils { } @Test - void testToByteArrayNegativeLength() { - assertThrows(RecordFormatException.class, () -> IOUtils.toByteArray(data123(), -1)); + void testToByteArrayNegativeLength() throws IOException { + final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7}; + IOUtils.setByteArrayMaxOverride(30 * 1024 * 1024); + try (ByteArrayInputStream is = new ByteArrayInputStream(array)) { + assertArrayEquals(array, IOUtils.toByteArray(is, -1, 100)); + } finally { + IOUtils.setByteArrayMaxOverride(-1); + } + } + + @Test + void testToByteArrayNegativeLength2() throws IOException { + final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7}; + IOUtils.setByteArrayMaxOverride(30 * 1024 * 1024); + try (ByteArrayInputStream is = new ByteArrayInputStream(array)) { + assertArrayEquals(array, IOUtils.toByteArray(is, -1)); + } finally { + IOUtils.setByteArrayMaxOverride(-1); + } } @Test |