Bug 56914 - XSSFRowShifter.updateConditionalFormatting throws IOOBE when there are more than 1 CTConditionalFormatting

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1622759 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2014-09-05 19:07:32 +00:00
parent 314b9f60de
commit 68639e749a
3 changed files with 29 additions and 24 deletions

View File

@ -131,19 +131,13 @@ public class XSSFSheetConditionalFormatting implements SheetConditionalFormattin
if (cfRules.length > 3) { if (cfRules.length > 3) {
throw new IllegalArgumentException("Number of rules must not exceed 3"); throw new IllegalArgumentException("Number of rules must not exceed 3");
} }
XSSFConditionalFormattingRule[] hfRules;
if(cfRules instanceof XSSFConditionalFormattingRule[]) hfRules = (XSSFConditionalFormattingRule[])cfRules;
else {
hfRules = new XSSFConditionalFormattingRule[cfRules.length];
System.arraycopy(cfRules, 0, hfRules, 0, hfRules.length);
}
CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(regions); CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(regions);
CTConditionalFormatting cf = _sheet.getCTWorksheet().addNewConditionalFormatting(); CTConditionalFormatting cf = _sheet.getCTWorksheet().addNewConditionalFormatting();
List<String> refs = new ArrayList<String>(); List<String> refs = new ArrayList<String>();
for(CellRangeAddress a : mergeCellRanges) refs.add(a.formatAsString()); for(CellRangeAddress a : mergeCellRanges) refs.add(a.formatAsString());
cf.setSqref(refs); cf.setSqref(refs);
int priority = 1; int priority = 1;
for(CTConditionalFormatting c : _sheet.getCTWorksheet().getConditionalFormattingArray()){ for(CTConditionalFormatting c : _sheet.getCTWorksheet().getConditionalFormattingArray()){
priority += c.sizeOfCfRuleArray(); priority += c.sizeOfCfRuleArray();

View File

@ -226,12 +226,12 @@ public final class XSSFRowShifter {
XSSFWorkbook wb = sheet.getWorkbook(); XSSFWorkbook wb = sheet.getWorkbook();
int sheetIndex = wb.getSheetIndex(sheet); int sheetIndex = wb.getSheetIndex(sheet);
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
CTWorksheet ctWorksheet = sheet.getCTWorksheet(); CTWorksheet ctWorksheet = sheet.getCTWorksheet();
int cfCount = ctWorksheet.sizeOfConditionalFormattingArray(); CTConditionalFormatting[] conditionalFormattingArray = ctWorksheet.getConditionalFormattingArray();
for(int j = 0; j< cfCount; j++){ // iterate backwards due to possible calls to ctWorksheet.removeConditionalFormatting(j)
CTConditionalFormatting cf = ctWorksheet.getConditionalFormattingArray(j); for (int j = conditionalFormattingArray.length - 1; j >= 0; j--) {
CTConditionalFormatting cf = conditionalFormattingArray[j];
ArrayList<CellRangeAddress> cellRanges = new ArrayList<CellRangeAddress>(); ArrayList<CellRangeAddress> cellRanges = new ArrayList<CellRangeAddress>();
for (Object stRef : cf.getSqref()) { for (Object stRef : cf.getSqref()) {
@ -267,9 +267,9 @@ public final class XSSFRowShifter {
} }
for(CTCfRule cfRule : cf.getCfRuleArray()){ for(CTCfRule cfRule : cf.getCfRuleArray()){
int formulaCount = cfRule.sizeOfFormulaArray(); String[] formulaArray = cfRule.getFormulaArray();
for (int i = 0; i < formulaCount; i++) { for (int i = 0; i < formulaArray.length; i++) {
String formula = cfRule.getFormulaArray(i); String formula = formulaArray[i];
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex); Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex);
if (shifter.adjustFormula(ptgs, sheetIndex)) { if (shifter.adjustFormula(ptgs, sheetIndex)) {
String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);

View File

@ -390,7 +390,6 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
} }
public void testShiftRows() { public void testShiftRows() {
Workbook wb = _testDataProvider.createWorkbook(); Workbook wb = _testDataProvider.createWorkbook();
Sheet sheet = wb.createSheet(); Sheet sheet = wb.createSheet();
@ -403,30 +402,42 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
PatternFormatting patternFmt = rule1.createPatternFormatting(); PatternFormatting patternFmt = rule1.createPatternFormatting();
patternFmt.setFillBackgroundColor(IndexedColors.YELLOW.index); patternFmt.setFillBackgroundColor(IndexedColors.YELLOW.index);
ConditionalFormattingRule [] cfRules = { rule1, };
ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(
ComparisonOperator.BETWEEN, "SUM(A10:A15)", "1+SUM(B16:B30)");
BorderFormatting borderFmt = rule2.createBorderFormatting();
borderFmt.setBorderDiagonal((short) 2);
CellRangeAddress [] regions = { CellRangeAddress [] regions = {
new CellRangeAddress(2, 4, 0, 0), // A3:A5 new CellRangeAddress(2, 4, 0, 0), // A3:A5
}; };
sheetCF.addConditionalFormatting(regions, cfRules); sheetCF.addConditionalFormatting(regions, rule1);
sheetCF.addConditionalFormatting(regions, rule2);
// This row-shift should destroy the CF region // This row-shift should destroy the CF region
sheet.shiftRows(10, 20, -9); sheet.shiftRows(10, 20, -9);
assertEquals(0, sheetCF.getNumConditionalFormattings()); assertEquals(0, sheetCF.getNumConditionalFormattings());
// re-add the CF // re-add the CF
sheetCF.addConditionalFormatting(regions, cfRules); sheetCF.addConditionalFormatting(regions, rule1);
sheetCF.addConditionalFormatting(regions, rule2);
// This row shift should only affect the formulas // This row shift should only affect the formulas
sheet.shiftRows(14, 17, 8); sheet.shiftRows(14, 17, 8);
ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0); ConditionalFormatting cf1 = sheetCF.getConditionalFormattingAt(0);
assertEquals("SUM(A10:A23)", cf.getRule(0).getFormula1()); assertEquals("SUM(A10:A23)", cf1.getRule(0).getFormula1());
assertEquals("1+SUM(B24:B30)", cf.getRule(0).getFormula2()); assertEquals("1+SUM(B24:B30)", cf1.getRule(0).getFormula2());
ConditionalFormatting cf2 = sheetCF.getConditionalFormattingAt(1);
assertEquals("SUM(A10:A23)", cf2.getRule(0).getFormula1());
assertEquals("1+SUM(B24:B30)", cf2.getRule(0).getFormula2());
sheet.shiftRows(0, 8, 21); sheet.shiftRows(0, 8, 21);
cf = sheetCF.getConditionalFormattingAt(0); cf1 = sheetCF.getConditionalFormattingAt(0);
assertEquals("SUM(A10:A21)", cf.getRule(0).getFormula1()); assertEquals("SUM(A10:A21)", cf1.getRule(0).getFormula1());
assertEquals("1+SUM(#REF!)", cf.getRule(0).getFormula2()); assertEquals("1+SUM(#REF!)", cf1.getRule(0).getFormula2());
cf2 = sheetCF.getConditionalFormattingAt(1);
assertEquals("SUM(A10:A21)", cf2.getRule(0).getFormula1());
assertEquals("1+SUM(#REF!)", cf2.getRule(0).getFormula2());
} }
protected void testRead(String filename){ protected void testRead(String filename){