diff --git a/poi-examples/src/main/java/org/apache/poi/examples/hpsf/ReadCustomPropertySets.java b/poi-examples/src/main/java/org/apache/poi/examples/hpsf/ReadCustomPropertySets.java index ca8cba1ce9..187f434b94 100644 --- a/poi-examples/src/main/java/org/apache/poi/examples/hpsf/ReadCustomPropertySets.java +++ b/poi-examples/src/main/java/org/apache/poi/examples/hpsf/ReadCustomPropertySets.java @@ -29,6 +29,7 @@ import org.apache.poi.hpsf.PropertySetFactory; import org.apache.poi.hpsf.Section; import org.apache.poi.poifs.eventfilesystem.POIFSReader; import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent; +import org.apache.poi.util.ExceptionUtil; /** *
Sample application showing how to read a document's custom property set.
@@ -66,6 +67,9 @@ public final class ReadCustomPropertySets {
out("No property set stream: \"" + streamName + "\"");
return;
} catch (Exception ex) {
+ if (ExceptionUtil.isFatal(ex)) {
+ ExceptionUtil.rethrow(ex);
+ }
throw new HPSFRuntimeException("Property set stream \"" + streamName + "\": " + ex);
}
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java
index 13c1e7848c..42e27b4c97 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java
@@ -50,6 +50,7 @@ import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.util.Beta;
+import org.apache.poi.util.ExceptionUtil;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.xssf.model.CalculationChain;
@@ -1164,6 +1165,9 @@ public final class XSSFCell extends CellBase {
RichTextString rt = _sharedStringSource.getItemAt(sstIndex);
return rt.getString();
} catch (Throwable t) {
+ if (ExceptionUtil.isFatal(t)) {
+ ExceptionUtil.rethrow(t);
+ }
return "";
}
case NUMERIC:
diff --git a/poi-ooxml/src/test/java/org/apache/poi/sl/tests/SLCommonUtils.java b/poi-ooxml/src/test/java/org/apache/poi/sl/tests/SLCommonUtils.java
index 3c3d243db8..44a95d8a0a 100644
--- a/poi-ooxml/src/test/java/org/apache/poi/sl/tests/SLCommonUtils.java
+++ b/poi-ooxml/src/test/java/org/apache/poi/sl/tests/SLCommonUtils.java
@@ -25,6 +25,7 @@ import java.io.InputStream;
import org.apache.poi.POIDataSamples;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
+import org.apache.poi.util.ExceptionUtil;
public class SLCommonUtils {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
@@ -34,7 +35,8 @@ public class SLCommonUtils {
try (InputStream is = _slTests.openResourceAsStream(sampleName)) {
return SlideShowFactory.create(is);
} catch (Exception e) {
- throw new RuntimeException(e);
+ ExceptionUtil.rethrow(e);
+ return null; //keeps compiler happy, the ExceptionUtil.rethrow(e) will throw an exception
}
}
@@ -48,7 +50,10 @@ public class SLCommonUtils {
try {
Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
return false;
- } catch (Exception e) {
+ } catch (Throwable e) {
+ if (ExceptionUtil.isFatal(e)) {
+ ExceptionUtil.rethrow(e);
+ }
return true;
}
}
diff --git a/poi/src/main/java/org/apache/poi/poifs/nio/CleanerUtil.java b/poi/src/main/java/org/apache/poi/poifs/nio/CleanerUtil.java
index 11fe068abb..11b2c621d9 100644
--- a/poi/src/main/java/org/apache/poi/poifs/nio/CleanerUtil.java
+++ b/poi/src/main/java/org/apache/poi/poifs/nio/CleanerUtil.java
@@ -17,6 +17,7 @@
package org.apache.poi.poifs.nio;
+import org.apache.poi.util.ExceptionUtil;
import org.apache.poi.util.SuppressForbidden;
import java.io.IOException;
@@ -181,7 +182,9 @@ public final class CleanerUtil {
unmapper.invokeExact(buffer);
return null;
} catch (Throwable t) {
- return t;
+ if (ExceptionUtil.isFatal(t)) {
+ ExceptionUtil.rethrow(t);
+ }
}
});
if (error != null) {
diff --git a/poi/src/main/java/org/apache/poi/util/ExceptionUtil.java b/poi/src/main/java/org/apache/poi/util/ExceptionUtil.java
new file mode 100644
index 0000000000..01ec1aced2
--- /dev/null
+++ b/poi/src/main/java/org/apache/poi/util/ExceptionUtil.java
@@ -0,0 +1,60 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+package org.apache.poi.util;
+
+/**
+ * Utilitity methods for dealing with exceptions/throwables
+ *
+ * @since POI 5.2.4
+ */
+public class ExceptionUtil {
+ private ExceptionUtil() {}
+
+ /**
+ * It is important never to catch all Throwables. Some like
+ * {@link InterruptedException} should be rethrown. Based on
+ * scala.util.control.NonFatal.
+ *
+ * @param throwable to check
+ * @return whether the Throwable is a fatal error
+ */
+ public static boolean isFatal(Throwable throwable) {
+ //similar to https://www.scala-lang.org/api/2.13.8/scala/util/control/NonFatal$.html
+ return (throwable instanceof VirtualMachineError
+ || throwable instanceof ThreadDeath
+ || throwable instanceof InterruptedException
+ || throwable instanceof LinkageError);
+ }
+
+ /**
+ * Designed to be used in conjunction with {@link #isFatal(Throwable)}.
+ * This method should be used with care.
+ *
+ * @param throwable to check
+ * @throws Throwable the input throwable if it is an Error or RuntimeException.
+ * Otherwise wraps the throwable in a RuntimeException.
+ */
+ public static void rethrow(Throwable throwable) {
+ if (throwable instanceof Error) {
+ throw (Error) throwable;
+ }
+ if (throwable instanceof RuntimeException) {
+ throw (RuntimeException) throwable;
+ }
+ throw new RuntimeException(throwable);
+ }
+}
diff --git a/poi/src/main/java/org/apache/poi/util/XMLHelper.java b/poi/src/main/java/org/apache/poi/util/XMLHelper.java
index 7ad8e3f0b0..02eecb331b 100644
--- a/poi/src/main/java/org/apache/poi/util/XMLHelper.java
+++ b/poi/src/main/java/org/apache/poi/util/XMLHelper.java
@@ -163,9 +163,15 @@ public final class XMLHelper {
// this also catches NoClassDefFoundError, which may be due to a local class path issue
// This may occur if the code is run inside a web container or a restricted JVM
// See bug 61170: https://bz.apache.org/bugzilla/show_bug.cgi?id=61170
+ if (ExceptionUtil.isFatal(re)) {
+ ExceptionUtil.rethrow(re);
+ }
logThrowable(re, "Failed to create SAXParserFactory", "-");
throw re;
} catch (Exception e) {
+ if (ExceptionUtil.isFatal(e)) {
+ ExceptionUtil.rethrow(e);
+ }
logThrowable(e, "Failed to create SAXParserFactory", "-");
throw new IllegalStateException("Failed to create SAXParserFactory", e);
}
@@ -260,6 +266,9 @@ public final class XMLHelper {
} catch (ClassNotFoundException ignored) {
// continue without log, this is expected in some setups
} catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here
+ if (ExceptionUtil.isFatal(e)) {
+ ExceptionUtil.rethrow(e);
+ }
logThrowable(e, "SAX Feature unsupported", securityManagerClassName);
}
}
@@ -273,9 +282,15 @@ public final class XMLHelper {
feature.accept(name, value);
return true;
} catch (Exception e) {
+ if (ExceptionUtil.isFatal(e)) {
+ ExceptionUtil.rethrow(e);
+ }
logThrowable(e, "SAX Feature unsupported", name);
- } catch (Error ame) {
- logThrowable(ame, "Cannot set SAX feature because outdated XML parser in classpath", name);
+ } catch (Error e) {
+ if (ExceptionUtil.isFatal(e)) {
+ ExceptionUtil.rethrow(e);
+ }
+ logThrowable(e, "Cannot set SAX feature because outdated XML parser in classpath", name);
}
return false;
}
@@ -285,10 +300,16 @@ public final class XMLHelper {
property.accept(name, value);
return true;
} catch (Exception e) {
+ if (ExceptionUtil.isFatal(e)) {
+ ExceptionUtil.rethrow(e);
+ }
logThrowable(e, "SAX Feature unsupported", name);
- } catch (Error ame) {
+ } catch (Error e) {
+ if (ExceptionUtil.isFatal(e)) {
+ ExceptionUtil.rethrow(e);
+ }
// ignore all top error object - GraalVM in native mode is not coping with java.xml error message resources
- logThrowable(ame, "Cannot set SAX feature because outdated XML parser in classpath", name);
+ logThrowable(e, "Cannot set SAX feature because outdated XML parser in classpath", name);
}
return false;
}
@@ -298,7 +319,9 @@ public final class XMLHelper {
property.accept(name, value);
return true;
} catch (Exception|Error e) {
- // ok to ignore
+ if (ExceptionUtil.isFatal(e)) {
+ ExceptionUtil.rethrow(e);
+ }
}
return false;
}