Adding conditional formatting with certain set of ranges gets stuck in endless loop. Test code to reproduce: Workbook workbook = new HSSFWorkbook(); Sheet sheet = workbook.createSheet(); CellRangeAddress[] ranges = new CellRangeAddress[] { CellRangeAddress.valueOf("C9:D30"), CellRangeAddress.valueOf("C7:C31") }; ConditionalFormattingRule rule = sheet.getSheetConditionalFormatting().createConditionalFormattingRule("$A$1>0"); sheet.getSheetConditionalFormatting().addConditionalFormatting(ranges, rule); Debugging shows that code gets stuck in org.apache.poi.hssf.record.cf.CellRangeUtil.mergeCellRanges(List) method on repeated merging/unmerging regions.
Does this happen for XSSF too? (That'll help us narrow down if it's common code that's broken, or HSSF specific code that's the problem)
I verified that this happens for XSSF too because the same CellRangeUtil class is used.
Stacktrace when it hangs: CellRangeUtil.mergeCellRanges(List) line: 118 CellRangeUtil.mergeCellRanges(CellRangeAddress[]) line: 101 CFHeaderRecord.<init>(CellRangeAddress[], int) line: 45 CFRecordsAggregate.<init>(CellRangeAddress[], CFRuleRecord[]) line: 72 HSSFSheetConditionalFormatting.addConditionalFormatting(CellRangeAddress[], HSSFConditionalFormattingRule[]) line: 155 HSSFSheetConditionalFormatting.addConditionalFormatting(CellRangeAddress[], HSSFConditionalFormattingRule) line: 172 HSSFSheetConditionalFormatting.addConditionalFormatting(CellRangeAddress[], ConditionalFormattingRule) line: 182 TestHSSFConditionalFormatting(BaseTestConditionalFormatting).testBug55380() line: 698
A simplified reproducer is as follows: public void testMergeCellRanges55380() { CellRangeAddress cr1 = CellRangeAddress.valueOf("C9:D30"); CellRangeAddress cr2 = CellRangeAddress.valueOf("C7:C31"); CellRangeAddress[] cr3 = CellRangeUtil.mergeCellRanges(new CellRangeAddress[]{cr1, cr2}); // endless loop... assertEquals(2, cr3.length); assertEquals("C9:D30", cr3[0].formatAsString()); assertEquals("C7:C31", cr3[1].formatAsString()); }
It happens with Overlapping Regions (i.e. not enclosing/inside and not no_intersection), the handling of this case is quite complex and seems to be buggy, I would propose to simply remove this for now as it only would be able to merge some rare cases and obviously does not do that well anyway right now. Any objections to the removal of this code-pieces, i.e. resolveRangeOverlap() and related methods?
For now I have removed merging of overlapping regions to avoid the endless loops in the implementation of the mergeCellRanges(). None of the unit tests stepped into the method, so the code was untested and probably never fully worked at all or was broken sometimes back by other changes.