diff --git a/src/java/org/apache/poi/hssf/record/CFRuleRecord.java b/src/java/org/apache/poi/hssf/record/CFRuleRecord.java index 867ecec63..4cf83efce 100644 --- a/src/java/org/apache/poi/hssf/record/CFRuleRecord.java +++ b/src/java/org/apache/poi/hssf/record/CFRuleRecord.java @@ -17,14 +17,16 @@ package org.apache.poi.hssf.record; +import java.util.Arrays; + import org.apache.poi.hssf.model.HSSFFormulaParser; import org.apache.poi.hssf.record.cf.BorderFormatting; import org.apache.poi.hssf.record.cf.FontFormatting; import org.apache.poi.hssf.record.cf.PatternFormatting; -import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.ss.formula.Formula; import org.apache.poi.ss.formula.FormulaType; +import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.util.BitField; import org.apache.poi.util.BitFieldFactory; import org.apache.poi.util.LittleEndianOutput; @@ -460,12 +462,13 @@ public final class CFRuleRecord extends StandardRecord { } protected int getDataSize() { - return 12 + + int i = 12 + (containsFontFormattingBlock()?_fontFormatting.getRawRecord().length:0)+ (containsBorderFormattingBlock()?8:0)+ (containsPatternFormattingBlock()?4:0)+ getFormulaSize(field_17_formula1)+ - getFormulaSize(field_18_formula2) + getFormulaSize(field_18_formula2); + return i ; } @@ -473,20 +476,20 @@ public final class CFRuleRecord extends StandardRecord { public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("[CFRULE]\n"); - buffer.append(" .condition_type ="+field_1_condition_type); - buffer.append(" OPTION FLAGS=0x"+Integer.toHexString(getOptions())); - if (false) { - if (containsFontFormattingBlock()) { - buffer.append(_fontFormatting.toString()); - } - if (containsBorderFormattingBlock()) { - buffer.append(_borderFormatting.toString()); - } - if (containsPatternFormattingBlock()) { - buffer.append(_patternFormatting.toString()); - } - buffer.append("[/CFRULE]\n"); + buffer.append(" .condition_type =").append(field_1_condition_type).append("\n"); + buffer.append(" OPTION FLAGS=0x").append(Integer.toHexString(getOptions())).append("\n"); + if (containsFontFormattingBlock()) { + buffer.append(_fontFormatting.toString()).append("\n"); } + if (containsBorderFormattingBlock()) { + buffer.append(_borderFormatting.toString()).append("\n"); + } + if (containsPatternFormattingBlock()) { + buffer.append(_patternFormatting.toString()).append("\n"); + } + buffer.append(" Formula 1 =").append(Arrays.toString(field_17_formula1.getTokens())).append("\n"); + buffer.append(" Formula 2 =").append(Arrays.toString(field_18_formula2.getTokens())).append("\n"); + buffer.append("[/CFRULE]\n"); return buffer.toString(); } @@ -504,7 +507,7 @@ public final class CFRuleRecord extends StandardRecord { rec._patternFormatting = (PatternFormatting) _patternFormatting.clone(); } rec.field_17_formula1 = field_17_formula1.copy(); - rec.field_18_formula2 = field_17_formula1.copy(); + rec.field_18_formula2 = field_18_formula2.copy(); return rec; } diff --git a/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java index d7f43bd2a..c5da21875 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java @@ -17,6 +17,7 @@ package org.apache.poi.hssf.record; +import static org.junit.Assert.assertArrayEquals; import junit.framework.AssertionFailedError; import junit.framework.TestCase; @@ -24,12 +25,12 @@ import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator; import org.apache.poi.hssf.record.cf.BorderFormatting; import org.apache.poi.hssf.record.cf.FontFormatting; import org.apache.poi.hssf.record.cf.PatternFormatting; -import org.apache.poi.ss.formula.ptg.Ptg; -import org.apache.poi.ss.formula.ptg.RefNPtg; -import org.apache.poi.ss.formula.ptg.RefPtg; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.formula.ptg.Ptg; +import org.apache.poi.ss.formula.ptg.RefNPtg; +import org.apache.poi.ss.formula.ptg.RefPtg; import org.apache.poi.util.LittleEndian; /** @@ -351,4 +352,17 @@ public final class TestCFRuleRecord extends TestCase { byte[] data = rr.serialize(); TestcaseRecordInputStream.confirmRecordEncoding(CFRuleRecord.sid, DATA_REFN, data); } + + public void testBug53691() { + HSSFWorkbook workbook = new HSSFWorkbook(); + HSSFSheet sheet = workbook.createSheet(); + + CFRuleRecord record = CFRuleRecord.create(sheet, ComparisonOperator.BETWEEN, "2", "5"); + + CFRuleRecord clone = (CFRuleRecord) record.clone(); + + byte [] serializedRecord = record.serialize(); + byte [] serializedClone = clone.serialize(); + assertArrayEquals(serializedRecord, serializedClone); + } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java index 943ebd004..8cd3cbaac 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java @@ -18,8 +18,14 @@ package org.apache.poi.hssf.usermodel; +import java.io.FileNotFoundException; +import java.io.IOException; + import org.apache.poi.hssf.HSSFITestDataProvider; import org.apache.poi.ss.usermodel.BaseTestConditionalFormatting; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.SheetConditionalFormatting; +import org.apache.poi.ss.usermodel.Workbook; /** * @@ -33,4 +39,70 @@ public final class TestHSSFConditionalFormatting extends BaseTestConditionalForm public void testRead(){ testRead("WithConditionalFormatting.xls"); } + + public void test53691() throws IOException { + SheetConditionalFormatting cf; + final Workbook wb; + wb = HSSFITestDataProvider.instance.openSampleWorkbook("53691.xls"); + /* + FileInputStream s = new FileInputStream("C:\\temp\\53691bbadfixed.xls"); + try { + wb = new HSSFWorkbook(s); + } finally { + s.close(); + } + + wb.removeSheetAt(1);*/ + + // initially it is good + writeTemp53691(wb, "agood"); + + // clone sheet corrupts it + Sheet sheet = wb.cloneSheet(0); + writeTemp53691(wb, "bbad"); + + // removing the sheet makes it good again + wb.removeSheetAt(wb.getSheetIndex(sheet)); + writeTemp53691(wb, "cgood"); + + // cloning again and removing the conditional formatting makes it good again + sheet = wb.cloneSheet(0); + removeConditionalFormatting(sheet); + writeTemp53691(wb, "dgood"); + + // cloning the conditional formatting manually makes it bad again + cf = sheet.getSheetConditionalFormatting(); + SheetConditionalFormatting scf = wb.getSheetAt(0).getSheetConditionalFormatting(); + for (int j = 0; j < scf.getNumConditionalFormattings(); j++) { + cf.addConditionalFormatting(scf.getConditionalFormattingAt(j)); + } + writeTemp53691(wb, "ebad"); + + // remove all conditional formatting for comparing BIFF output + removeConditionalFormatting(sheet); + removeConditionalFormatting(wb.getSheetAt(0)); + writeTemp53691(wb, "fgood"); + } + + private void removeConditionalFormatting(Sheet sheet) { + SheetConditionalFormatting cf = sheet.getSheetConditionalFormatting(); + for (int j = 0; j < cf.getNumConditionalFormattings(); j++) { + cf.removeConditionalFormatting(j); + } + } + + private void writeTemp53691(Workbook wb, String suffix) throws FileNotFoundException, + IOException { + // assert that we can write/read it in memory + Workbook wbBack = HSSFITestDataProvider.instance.writeOutAndReadBack(wb); + assertNotNull(wbBack); + + /* Just necessary for local testing... */ + /*OutputStream out = new FileOutputStream("C:\\temp\\53691" + suffix + ".xls"); + try { + wb.write(out); + } finally { + out.close(); + }*/ + } } diff --git a/test-data/spreadsheet/53691.xls b/test-data/spreadsheet/53691.xls new file mode 100644 index 000000000..5c20dc54e Binary files /dev/null and b/test-data/spreadsheet/53691.xls differ