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 152e061292 Prevent crashes when calculating cells on absolute anchors.
(#1089)
152e061292 is described below
commit 152e061292fd49219c310d2a950be6ea9a20ccb3
Author: Jacobo Aragunde Pérez <[email protected]>
AuthorDate: Tue May 26 19:12:15 2026 +0200
Prevent crashes when calculating cells on absolute anchors. (#1089)
Absolute anchors in OOXML aren't anchored to cells, they have absolute
positions in the document. The XSSFClientAnchor has code to calculate
the cell equivalent, using the absolute position and the cell width and
height. The same code is used to calculate the second anchor cell in
one-cell anchors.
For absolute anchors, it takes an empty cell (EMPTY_MARKER) and
calculates the first anchor cell by compounding it with the anchor
position, the problem is the empty cell has some null fields that the
code is not expecting, and it crashes.
We add those null cells and add a test that exercises this use case.
The same test would crash if run on trunk, with the following
exception:
java.lang.NullPointerException: Cannot invoke
"org.apache.xmlbeans.XmlAnySimpleType.getStringValue()" because "coordUnion" is
null
at
org.apache.poi.ooxml/org.apache.poi.ooxml.util.POIXMLUnits.parseLengthInner(POIXMLUnits.java:236)
at
org.apache.poi.ooxml/org.apache.poi.ooxml.util.POIXMLUnits.parseLength(POIXMLUnits.java:167)
at
org.apache.poi.ooxml/org.apache.poi.xssf.usermodel.XSSFClientAnchor.calcCell(XSSFClientAnchor.java:166)
at
org.apache.poi.ooxml/org.apache.poi.xssf.usermodel.XSSFClientAnchor.getCell1(XSSFClientAnchor.java:202)
at
org.apache.poi.ooxml/org.apache.poi.xssf.usermodel.XSSFClientAnchor.getCol1(XSSFClientAnchor.java:211)
at
org.apache.poi.ooxml/org.apache.poi.xssf.usermodel.TestXSSFDrawing.testAbsoluteAnchor(TestXSSFDrawing.java:938)
---
.../apache/poi/xssf/usermodel/XSSFClientAnchor.java | 4 ++--
.../org/apache/poi/xssf/usermodel/TestXSSFDrawing.java | 17 +++++++++++++++++
.../spreadsheet/absolute-anchor-over-empty-sheet.xlsx | Bin 0 -> 21153 bytes
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git
a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java
b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java
index 893e3ec3cd..14502d5e24 100644
---
a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java
+++
b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java
@@ -163,7 +163,7 @@ public class XSSFClientAnchor extends XSSFAnchor implements
ClientAnchor {
int cw = Units.columnWidthToEMU(sheet.getColumnWidth(c));
// start with width - offset, then keep adding column widths until the
next one puts us over w
- long wPos = cw - POIXMLUnits.parseLength(cell.xgetColOff());
+ long wPos = cell.xgetColOff() == null ? cw : cw -
POIXMLUnits.parseLength(cell.xgetColOff());
while (wPos < w) {
c++;
@@ -176,7 +176,7 @@ public class XSSFClientAnchor extends XSSFAnchor implements
ClientAnchor {
int rh = Units.toEMU(getRowHeight(sheet, r));
// start with height - offset, then keep adding row heights until the
next one puts us over h
- long hPos = rh - POIXMLUnits.parseLength(cell.xgetRowOff());
+ long hPos = cell.xgetRowOff() == null ? rh : rh -
POIXMLUnits.parseLength(cell.xgetRowOff());
while (hPos < h) {
r++;
diff --git
a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java
b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java
index 48c3b4478a..a02f21f436 100644
--- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java
+++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java
@@ -925,6 +925,23 @@ class TestXSSFDrawing {
}
}
+ @Test
+ void testAbsoluteAnchor() throws IOException {
+ try (XSSFWorkbook workbook =
XSSFTestDataSamples.openSampleWorkbook("absolute-anchor-over-empty-sheet.xlsx"))
{
+ XSSFSheet sheet = workbook.getSheetAt(0);
+ XSSFDrawing drawing = sheet.getDrawingPatriarch();
+ List<XSSFShape> shapes = drawing.getShapes();
+ assertEquals(1, shapes.size());
+
+ assertTrue(shapes.get(0).getAnchor() instanceof ClientAnchor);
+ ClientAnchor anchor = (ClientAnchor) shapes.get(0).getAnchor();
+ assertEquals(3, anchor.getCol1());
+ assertEquals(38, anchor.getRow1());
+ assertEquals(19, anchor.getCol2());
+ assertEquals(80, anchor.getRow2());
+ }
+ }
+
private static void checkRewrite(XSSFWorkbook wb) throws IOException {
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb);
assertNotNull(wb2);
diff --git a/test-data/spreadsheet/absolute-anchor-over-empty-sheet.xlsx
b/test-data/spreadsheet/absolute-anchor-over-empty-sheet.xlsx
new file mode 100644
index 0000000000..a8c3ce1c53
Binary files /dev/null and
b/test-data/spreadsheet/absolute-anchor-over-empty-sheet.xlsx differ
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]