From: Josh Micich Date: Mon, 8 Sep 2008 19:49:03 +0000 (+0000) Subject: Additional fix for 45720 - bug in HSSFWorkbook.findExistingBuiltinNameRecordIdx X-Git-Tag: REL_3_2_FINAL~82 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=72d018c3925afa73b41a47dac72e7ca3dc621dae;p=poi.git 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 --- 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 0000000000..25939e85f6 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/testRRaC.xls differ 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 + } }