aboutsummaryrefslogtreecommitdiffstats
path: root/poi
diff options
context:
space:
mode:
Diffstat (limited to 'poi')
-rw-r--r--poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java10
-rw-r--r--poi/src/main/java/org/apache/poi/util/IOUtils.java36
-rw-r--r--poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestCell.java5
-rw-r--r--poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java2
-rw-r--r--poi/src/test/java/org/apache/poi/util/TestIOUtils.java21
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