You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ce...@apache.org on 2026/10/27 15:35:15 UTC
(poi) 02/03: Avoid more NPEs and ClassCastExceptions in CellFormat
This is an automated email from the ASF dual-hosted git repository.
centic9 pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git
commit d51c386d706c93f2038cb4cae83be6900cb5d069
Author: Dominik Stadler <do...@gmx.at>
AuthorDate: Tue Oct 27 10:57:11 2026 +0100
Avoid more NPEs and ClassCastExceptions in CellFormat
---
.../apache/poi/ss/format/CellDateFormatter.java | 2 +-
.../apache/poi/ss/format/CellElapsedFormatter.java | 4 +++
.../java/org/apache/poi/ss/format/CellFormat.java | 34 +++++++++++++++-------
.../org/apache/poi/ss/format/TestCellFormat.java | 30 +++++++++++++++++--
4 files changed, 57 insertions(+), 13 deletions(-)
diff --git a/poi/src/main/java/org/apache/poi/ss/format/CellDateFormatter.java b/poi/src/main/java/org/apache/poi/ss/format/CellDateFormatter.java
index 7775aa2784..f7309b0be9 100644
--- a/poi/src/main/java/org/apache/poi/ss/format/CellDateFormatter.java
+++ b/poi/src/main/java/org/apache/poi/ss/format/CellDateFormatter.java
@@ -220,7 +220,7 @@ public class CellDateFormatter extends CellFormatter {
if (msecs < 0) {
msecs += 1000;
}
- formatter.format(locale, sFmt, msecs / 1000.0);
+ formatter.format(locale, sFmt == null ? "%f" : sFmt, msecs / 1000.0);
}
toAppendTo.delete(pos, pos + 2);
doneMillis = true;
diff --git a/poi/src/main/java/org/apache/poi/ss/format/CellElapsedFormatter.java b/poi/src/main/java/org/apache/poi/ss/format/CellElapsedFormatter.java
index a350231fc1..d7cdd7e207 100644
--- a/poi/src/main/java/org/apache/poi/ss/format/CellElapsedFormatter.java
+++ b/poi/src/main/java/org/apache/poi/ss/format/CellElapsedFormatter.java
@@ -177,6 +177,10 @@ public class CellElapsedFormatter extends CellFormatter {
@Override
public void formatValue(StringBuffer toAppendTo, Object value) {
+ if (!(value instanceof Number)) {
+ throw new IllegalArgumentException("Expected object of type number for format " + format + ", but had: " + value);
+ }
+
double elapsed = ((Number) value).doubleValue();
if (elapsed < 0) {
diff --git a/poi/src/main/java/org/apache/poi/ss/format/CellFormat.java b/poi/src/main/java/org/apache/poi/ss/format/CellFormat.java
index 93becf26ee..77c9f257b1 100644
--- a/poi/src/main/java/org/apache/poi/ss/format/CellFormat.java
+++ b/poi/src/main/java/org/apache/poi/ss/format/CellFormat.java
@@ -468,23 +468,37 @@ public class CellFormat {
if ((!posNumFmt.hasCondition() && val >= 0)
|| (posNumFmt.hasCondition() && posNumFmt.applies(val))) {
return posNumFmt;
- } else if (!negNumFmt.hasCondition()
- || (negNumFmt.hasCondition() && negNumFmt.applies(val))) {
- return negNumFmt;
} else {
- // Return ###...### (255 #s) to match Excel 2007 behaviour
- return new CellFormatPart(QUOTE + INVALID_VALUE_FOR_FORMAT + QUOTE);
+ if (negNumFmt == null) {
+ throw new IllegalStateException(
+ "Cannot apply cell format, check for warning logs during creation of format: " + format);
+ }
+
+ if (!negNumFmt.hasCondition()
+ || (negNumFmt.hasCondition() && negNumFmt.applies(val))) {
+ return negNumFmt;
+ } else {
+ // Return ###...### (255 #s) to match Excel 2007 behaviour
+ return new CellFormatPart(QUOTE + INVALID_VALUE_FOR_FORMAT + QUOTE);
+ }
}
} else {
if ((!posNumFmt.hasCondition() && val > 0)
|| (posNumFmt.hasCondition() && posNumFmt.applies(val))) {
return posNumFmt;
- } else if ((!negNumFmt.hasCondition() && val < 0)
- || (negNumFmt.hasCondition() && negNumFmt.applies(val))) {
- return negNumFmt;
- // Only the first two format parts can have conditions
} else {
- return zeroNumFmt;
+ if (negNumFmt == null) {
+ throw new IllegalStateException(
+ "Cannot apply cell format, check for warning logs during creation of format: " + format);
+ }
+
+ if ((!negNumFmt.hasCondition() && val < 0)
+ || (negNumFmt.hasCondition() && negNumFmt.applies(val))) {
+ return negNumFmt;
+ // Only the first two format parts can have conditions
+ } else {
+ return zeroNumFmt;
+ }
}
}
} else {
diff --git a/poi/src/test/java/org/apache/poi/ss/format/TestCellFormat.java b/poi/src/test/java/org/apache/poi/ss/format/TestCellFormat.java
index e1ebd0ca3c..d7ab91dfad 100644
--- a/poi/src/test/java/org/apache/poi/ss/format/TestCellFormat.java
+++ b/poi/src/test/java/org/apache/poi/ss/format/TestCellFormat.java
@@ -30,6 +30,7 @@ import java.nio.file.Files;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.IllegalFormatConversionException;
import java.util.Locale;
import java.util.TimeZone;
import java.util.stream.Stream;
@@ -59,14 +60,14 @@ class TestCellFormat {
private static TimeZone userTimeZone;
@BeforeAll
- public static void setTimeZone() {
+ static void setTimeZone() {
userTimeZone = LocaleUtil.getUserTimeZone();
LocaleUtil.setUserTimeZone(TimeZone.getTimeZone("CET"));
LocaleUtil.setUserLocale(Locale.US);
}
@AfterAll
- public static void resetTimeZone() {
+ static void resetTimeZone() {
LocaleUtil.setUserTimeZone(userTimeZone);
LocaleUtil.setUserLocale(Locale.ROOT);
}
@@ -1336,4 +1337,29 @@ class TestCellFormat {
assertThrows(IllegalArgumentException.class,
() -> cellFormat.apply(Double.parseDouble("-2.0579980172405396E-35")));
}
+
+ @Test
+ void testApplyNPE3() {
+ CellFormat cellFormat = CellFormat.getInstance(Locale.ROOT, ";@\u007F??.???@;['@|';??");
+
+ assertThrows(IllegalStateException.class,
+ () -> cellFormat.apply(0.0d));
+ }
+
+ @Test
+ void testApplyNPE4() {
+ CellFormat cellFormat = CellFormat.getInstance(Locale.ROOT, "y*S_#1\u0000y*\u0000\by*\u0000\n\u0000");
+
+ CellFormatResult result = cellFormat.apply(-0.0d);
+ // exact outcome may depend on current year, do not depend on it here
+ assertNotNull(result);
+ }
+
+ @Test
+ void testApplyClassCaseException() {
+ CellFormat cellFormat = CellFormat.getInstance(Locale.ENGLISH, "|;x;\b̼;\bS\n1\\E]\\E]S[S]S[$-S]");
+
+ assertThrows(IllegalArgumentException.class,
+ () -> cellFormat.apply(""));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org