From 5f5d8f496efc725e4055303d5b8580d426f761ed Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Thu, 31 Jul 2014 14:55:04 +0000 Subject: [PATCH] Fix bug #56527 - Avoid NPE from XSSFHyperLink when setting the cell it references on a new link git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1614914 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/usermodel/XSSFHyperlink.java | 28 ++++----- .../poi/xssf/usermodel/TestXSSFBugs.java | 59 ++++++++++++++++++- 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java index 9b0885cc6..86538fd68 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java @@ -25,7 +25,6 @@ import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.util.CellReference; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink; - /** * XSSF Implementation of a Hyperlink. * Note - unlike with HSSF, many kinds of hyperlink @@ -223,9 +222,16 @@ public class XSSFHyperlink implements Hyperlink { protected void setCellReference(String ref) { _ctHyperlink.setRef(ref); } + protected void setCellReference(CellReference ref) { + setCellReference(ref.formatAsString()); + } private CellReference buildCellReference() { - return new CellReference(_ctHyperlink.getRef()); + String ref = _ctHyperlink.getRef(); + if (ref == null) { + ref = "A1"; + } + return new CellReference(ref); } @@ -273,15 +279,12 @@ public class XSSFHyperlink implements Hyperlink { * @param col the 0-based column of the first cell that contains the hyperlink */ public void setFirstColumn(int col) { - _ctHyperlink.setRef( - new CellReference( - getFirstRow(), col - ).formatAsString() - ); + setCellReference(new CellReference( getFirstRow(), col )); } /** - * Set the column of the last cell that contains the hyperlink + * Set the column of the last cell that contains the hyperlink. + * For XSSF, a Hyperlink may only reference one cell * * @param col the 0-based column of the last cell that contains the hyperlink */ @@ -295,15 +298,12 @@ public class XSSFHyperlink implements Hyperlink { * @param row the 0-based row of the first cell that contains the hyperlink */ public void setFirstRow(int row) { - _ctHyperlink.setRef( - new CellReference( - row, getFirstColumn() - ).formatAsString() - ); + setCellReference(new CellReference( row, getFirstColumn() )); } /** - * Set the row of the last cell that contains the hyperlink + * Set the row of the last cell that contains the hyperlink. + * For XSSF, a Hyperlink may only reference one cell * * @param row the 0-based row of the last cell that contains the hyperlink */ diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 891a1bd78..162ee4aad 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -18,7 +18,13 @@ package org.apache.poi.xssf.usermodel; import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -44,7 +50,26 @@ import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.ValueEval; import org.apache.poi.ss.formula.functions.Function; -import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellValue; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.Comment; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.DataFormatter; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Drawing; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.FormulaError; +import org.apache.poi.ss.usermodel.FormulaEvaluator; +import org.apache.poi.ss.usermodel.Hyperlink; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Name; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellReference; @@ -1761,6 +1786,36 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { NumberEval eval = new NumberEval(Math.floor(excelDate)); checkValue(excel, eval.getStringValue() + ".0"); } + + @Test + public void testBug56527() { + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = wb.createSheet(); + XSSFCreationHelper creationHelper = wb.getCreationHelper(); + XSSFHyperlink hyperlink; + + // Try with a cell reference + hyperlink = creationHelper.createHyperlink(Hyperlink.LINK_URL); + sheet.addHyperlink(hyperlink); + hyperlink.setAddress("http://myurl"); + hyperlink.setCellReference("B4"); + assertEquals(3, hyperlink.getFirstRow()); + assertEquals(1, hyperlink.getFirstColumn()); + assertEquals(3, hyperlink.getLastRow()); + assertEquals(1, hyperlink.getLastColumn()); + + // Try with explicit rows / columns + hyperlink = creationHelper.createHyperlink(Hyperlink.LINK_URL); + sheet.addHyperlink(hyperlink); + hyperlink.setAddress("http://myurl"); + hyperlink.setFirstRow(5); + hyperlink.setFirstColumn(3); + + assertEquals(5, hyperlink.getFirstRow()); + assertEquals(3, hyperlink.getFirstColumn()); + assertEquals(5, hyperlink.getLastRow()); + assertEquals(3, hyperlink.getLastColumn()); + } private void checkValue(XSSFWorkbook excel, String expect) { XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(excel);