You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2026/09/18 15:27:26 UTC
(poi) branch trunk updated: ImageUtils.getResolution: unusable pixel-size metadata falls back to 96 dpi instead of throwing (#1297)
This is an automated email from the ASF dual-hosted git repository.
pjfanning pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git
The following commit(s) were added to refs/heads/trunk by this push:
new a6d6a99479 ImageUtils.getResolution: unusable pixel-size metadata falls back to 96 dpi instead of throwing (#1297)
a6d6a99479 is described below
commit a6d6a99479d38c186153ef006467e3775b594389
Author: PJ Fanning <pj...@users.noreply.github.com>
AuthorDate: Fri Sep 18 16:27:20 2026 +0100
ImageUtils.getResolution: unusable pixel-size metadata falls back to 96 dpi instead of throwing (#1297)
The HorizontalPixelSize/VerticalPixelSize an image's metadata reports is untrusted
input. A value of 0 made 25.4/0 infinite and MathUtil.safeDoubleToInt threw
IllegalArgumentException out of Picture.getImageDimension() and resize(); a
non-numeric value threw NumberFormatException. Both now give the default 96 dpi,
as a missing value already did.
Co-authored-by: Claude Opus 5 (1M context) <no...@anthropic.com>
---
.../java/org/apache/poi/ss/util/ImageUtils.java | 30 +++++++++++++++++++---
.../org/apache/poi/ss/util/TestImageUtils.java | 20 +++++++++++++++
2 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/poi/src/main/java/org/apache/poi/ss/util/ImageUtils.java b/poi/src/main/java/org/apache/poi/ss/util/ImageUtils.java
index bd86cb49ca..0db836badc 100644
--- a/poi/src/main/java/org/apache/poi/ss/util/ImageUtils.java
+++ b/poi/src/main/java/org/apache/poi/ss/util/ImageUtils.java
@@ -46,6 +46,9 @@ import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public final class ImageUtils {
+
+ /** the dpi assumed when an image carries no usable resolution metadata */
+ private static final int DEFAULT_DPI = 96;
private static final Logger LOG = PoiLogManager.getLogger(ImageUtils.class);
private static final int WIDTH_UNITS = 1024;
@@ -119,24 +122,43 @@ public final class ImageUtils {
* {96, 96} is the default.
*/
public static int[] getResolution(ImageReader r) throws IOException {
- int hdpi=96, vdpi=96;
- double mm2inch = 25.4;
+ int hdpi=DEFAULT_DPI, vdpi=DEFAULT_DPI;
NodeList lst;
Element node = (Element)r.getImageMetadata(0).getAsTree("javax_imageio_1.0");
lst = node.getElementsByTagName("HorizontalPixelSize");
if(lst != null && lst.getLength() == 1) {
- hdpi = MathUtil.safeDoubleToInt(mm2inch/Double.parseDouble(((Element)lst.item(0)).getAttribute("value")));
+ hdpi = dpiFromPixelSize(((Element)lst.item(0)).getAttribute("value"));
}
lst = node.getElementsByTagName("VerticalPixelSize");
if(lst != null && lst.getLength() == 1) {
- vdpi = MathUtil.safeDoubleToInt(mm2inch/Double.parseDouble(((Element)lst.item(0)).getAttribute("value")));
+ vdpi = dpiFromPixelSize(((Element)lst.item(0)).getAttribute("value"));
}
return new int[]{hdpi, vdpi};
}
+ /**
+ * @param pixelSizeMm the size of a pixel in millimeters, as found in the image metadata
+ * @return the dpi that pixel size means, or {@link #DEFAULT_DPI} if the metadata is unusable
+ * (not a number, zero, negative, or so small that the dpi does not fit an int)
+ */
+ static int dpiFromPixelSize(String pixelSizeMm) {
+ final double mm2inch = 25.4;
+ double pixelSize;
+ try {
+ pixelSize = Double.parseDouble(pixelSizeMm);
+ } catch (NumberFormatException | NullPointerException e) {
+ return DEFAULT_DPI;
+ }
+ double dpi = mm2inch / pixelSize;
+ if (!(dpi > 0 && dpi <= Integer.MAX_VALUE)) {
+ return DEFAULT_DPI;
+ }
+ return (int) dpi;
+ }
+
/**
* Calculate and set the preferred size (anchor) for this picture.
*
diff --git a/poi/src/test/java/org/apache/poi/ss/util/TestImageUtils.java b/poi/src/test/java/org/apache/poi/ss/util/TestImageUtils.java
index 1487574a49..7a2f17591a 100644
--- a/poi/src/test/java/org/apache/poi/ss/util/TestImageUtils.java
+++ b/poi/src/test/java/org/apache/poi/ss/util/TestImageUtils.java
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test;
import java.io.IOException;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
@@ -87,4 +88,23 @@ final class TestImageUtils {
);
}
}
+
+ /**
+ * The pixel size in an image's metadata is untrusted input: a zero, negative or garbage
+ * value must not throw (it used to give IllegalArgumentException from the int conversion)
+ */
+ @Test
+ void testDpiFromPixelSize() {
+ assertEquals(96, ImageUtils.dpiFromPixelSize("0.26458333"));
+ assertEquals(100, ImageUtils.dpiFromPixelSize("0.254"));
+ assertEquals(1, ImageUtils.dpiFromPixelSize("25.4"));
+ assertEquals(96, ImageUtils.dpiFromPixelSize("0"));
+ assertEquals(96, ImageUtils.dpiFromPixelSize("-0.1"));
+ assertEquals(96, ImageUtils.dpiFromPixelSize("1E-300"));
+ assertEquals(96, ImageUtils.dpiFromPixelSize("NaN"));
+ assertEquals(96, ImageUtils.dpiFromPixelSize("Infinity"));
+ assertEquals(96, ImageUtils.dpiFromPixelSize("abc"));
+ assertEquals(96, ImageUtils.dpiFromPixelSize(""));
+ assertEquals(96, ImageUtils.dpiFromPixelSize(null));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org