From 72d018c3925afa73b41a47dac72e7ca3dc621dae Mon Sep 17 00:00:00 2001 From: Josh Micich Date: Mon, 8 Sep 2008 19:49:03 +0000 Subject: [PATCH] Additional fix for 45720 - bug in HSSFWorkbook.findExistingBuiltinNameRecordIdx git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@693221 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hssf/model/Workbook.java | 6 +++- .../apache/poi/hssf/record/NameRecord.java | 15 ++++----- .../poi/hssf/usermodel/HSSFWorkbook.java | 8 +---- .../org/apache/poi/hssf/data/testRRaC.xls | Bin 0 -> 20480 bytes .../poi/hssf/usermodel/TestHSSFWorkbook.java | 29 ++++++++++++++++++ 5 files changed, 43 insertions(+), 15 deletions(-) create mode 100644 src/testcases/org/apache/poi/hssf/data/testRRaC.xls diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java index 7db37b253a..fad9e4d0ba 100644 --- a/src/java/org/apache/poi/hssf/model/Workbook.java +++ b/src/java/org/apache/poi/hssf/model/Workbook.java @@ -2466,6 +2466,10 @@ public final class Workbook implements Model { int aggLoc = sheet.aggregateDrawingRecords(drawingManager, false); if(aggLoc != -1) { EscherAggregate agg = (EscherAggregate) sheet.findFirstRecordBySid(EscherAggregate.sid); + EscherContainerRecord escherContainer = agg.getEscherContainer(); + if (escherContainer == null) { + return; + } EscherDggRecord dgg = drawingManager.getDgg(); @@ -2475,7 +2479,7 @@ public final class Workbook implements Model { dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1); EscherDgRecord dg = null; - for(Iterator it = agg.getEscherContainer().getChildRecords().iterator(); it.hasNext();) { + for(Iterator it = escherContainer.getChildRecords().iterator(); it.hasNext();) { Object er = it.next(); if(er instanceof EscherDgRecord) { dg = (EscherDgRecord)er; diff --git a/src/java/org/apache/poi/hssf/record/NameRecord.java b/src/java/org/apache/poi/hssf/record/NameRecord.java index b12a3c6ad7..18e2126d54 100644 --- a/src/java/org/apache/poi/hssf/record/NameRecord.java +++ b/src/java/org/apache/poi/hssf/record/NameRecord.java @@ -82,8 +82,9 @@ public final class NameRecord extends Record { private short field_1_option_flag; private byte field_2_keyboard_shortcut; - private short field_5_index_to_sheet; // unused: see field_6 - /** the one based sheet number. Zero if this is a global name */ + /** One-based extern index of sheet (resolved via LinkTable). Zero if this is a global name */ + private short field_5_externSheetIndex_plus1; + /** the one based sheet number. */ private int field_6_sheetNumber; private boolean field_11_nameIsMultibyte; private byte field_12_built_in_code; @@ -144,7 +145,7 @@ public final class NameRecord extends Record { /** * For named ranges, and built-in names - * @return the 1-based sheet number. Zero if this is a global name + * @return the 1-based sheet number. */ public int getSheetNumber() { @@ -384,7 +385,7 @@ public final class NameRecord extends Record { LittleEndian.putByte(data, 7 + offset, getNameTextLength()); // Note - LittleEndian.putUShort(data, 8 + offset, Ptg.getEncodedSizeWithoutArrayData(field_13_name_definition)); - LittleEndian.putUShort(data, 10 + offset, field_5_index_to_sheet); + LittleEndian.putUShort(data, 10 + offset, field_5_externSheetIndex_plus1); LittleEndian.putUShort(data, 12 + offset, field_6_sheetNumber); LittleEndian.putByte(data, 14 + offset, field_7_length_custom_menu); LittleEndian.putByte(data, 15 + offset, field_8_length_description_text); @@ -557,7 +558,7 @@ public final class NameRecord extends Record { field_2_keyboard_shortcut = in.readByte(); int field_3_length_name_text = in.readByte(); int field_4_length_name_definition = in.readShort(); - field_5_index_to_sheet = in.readShort(); + field_5_externSheetIndex_plus1 = in.readShort(); field_6_sheetNumber = in.readUShort(); int field_7_length_custom_menu = in.readUByte(); int field_8_length_description_text = in.readUByte(); @@ -649,8 +650,8 @@ public final class NameRecord extends Record { sb.append(" .option flags = ").append(HexDump.shortToHex(field_1_option_flag)).append("\n"); sb.append(" .keyboard shortcut = ").append(HexDump.byteToHex(field_2_keyboard_shortcut)).append("\n"); sb.append(" .length of the name = ").append(getNameTextLength()).append("\n"); - sb.append(" .unused = ").append( field_5_index_to_sheet ).append("\n"); - sb.append(" .index to sheet (1-based, 0=Global) = ").append( field_6_sheetNumber ).append("\n"); + sb.append(" .extSheetIx(1-based, 0=Global)= ").append( field_5_externSheetIndex_plus1 ).append("\n"); + sb.append(" .sheetTabIx = ").append(field_6_sheetNumber ).append("\n"); sb.append(" .Menu text length = ").append(field_14_custom_menu_text.length()).append("\n"); sb.append(" .Description text length= ").append(field_15_description_text.length()).append("\n"); sb.append(" .Help topic text length = ").append(field_16_help_topic_text.length()).append("\n"); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index a227c43d11..3dd31d7a04 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -1042,13 +1042,7 @@ public class HSSFWorkbook extends POIDocument if (!r.isBuiltInName() || r.getBuiltInName() != builtinCode) { continue; } - if(r.getSheetNumber() == 0) { - //ignore "GLOBAL" name records - continue; - } - int externIndex = r.getSheetNumber() -1; - int nameRecordSheetIndex = workbook.getSheetIndexFromExternSheetIndex(externIndex); - if (nameRecordSheetIndex == sheetIndex) { + if (r.getSheetNumber() -1 == sheetIndex) { return defNameIndex; } } diff --git a/src/testcases/org/apache/poi/hssf/data/testRRaC.xls b/src/testcases/org/apache/poi/hssf/data/testRRaC.xls new file mode 100644 index 0000000000000000000000000000000000000000..25939e85f6e3b0698d4a2a1062ece21d805802d7 GIT binary patch literal 20480 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 AF8}}l literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java index 1717aeff65..6fb08f4ee3 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java @@ -527,4 +527,33 @@ public final class TestHSSFWorkbook extends TestCase { } } } + + /** + * Test to make sure that NameRecord.getSheetNumber() is interpreted as a + * 1-based sheet tab index (not a 1-based extern sheet index) + */ + public void testFindBuiltInNameRecord() { + // testRRaC has multiple (3) built-in name records + // The second print titles name record has getSheetNumber()==4 + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("testRRaC.xls"); + NameRecord nr; + assertEquals(3, wb.getWorkbook().getNumNames()); + nr = wb.getWorkbook().getNameRecord(2); + // TODO - render full row and full column refs properly + assertEquals("Sheet2!$A$1:$IV$1", nr.getAreaReference(wb)); // 1:1 + + try { + wb.setRepeatingRowsAndColumns(3, 4, 5, 8, 11); + } catch (RuntimeException e) { + if (e.getMessage().equals("Builtin (7) already exists for sheet (4)")) { + // there was a problem in the code which locates the existing print titles name record + throw new RuntimeException("Identified bug 45720b"); + } + throw e; + } + wb = HSSFTestDataSamples.writeOutAndReadBack(wb); + assertEquals(3, wb.getWorkbook().getNumNames()); + nr = wb.getWorkbook().getNameRecord(2); + assertEquals("Sheet2!E:F,Sheet2!$A$9:$IV$12", nr.getAreaReference(wb)); // E:F,9:12 + } } -- 2.39.5