Bug 48846

Summary: TextObjectRecord sometimes become null, so it must be checked before using.
Product: POI Reporter: Tsutomu YANO <benbrand>
Component: HSSFAssignee: POI Developers List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 3.6-FINAL   
Target Milestone: ---   
Hardware: All   
OS: All   
Bug Depends on: 47624    
Bug Blocks:    

Description Tsutomu YANO 2010-03-03 03:00:48 UTC
In findCellComment(Sheet, int, int) method of org.apache.poi.hssf.usermodel.HSSFCell, TextObjectRecord sometimes become null.

-- original code --
        for (Iterator<RecordBase> it = sheet.getRecords().iterator(); it.hasNext();) {
            RecordBase rec = it.next();
            if (rec instanceof NoteRecord) {
                NoteRecord note = (NoteRecord) rec;
                if (note.getRow() == row && note.getColumn() == column) {
                    if(i < noteTxo.size()) {
                        TextObjectRecord txo = noteTxo.get(note.getShapeId());
                        comment = new HSSFComment(note, txo);
                        comment.setRow(note.getRow());
                        comment.setColumn((short) note.getColumn());
                        comment.setAuthor(note.getAuthor());
                        comment.setVisible(note.getFlags() == NoteRecord.NOTE_VISIBLE);
                        comment.setString(txo.getStr());
                    } else {
                        log.log(POILogger.WARN, "Failed to match NoteRecord and TextObjectRecord, row: " + row + ", column: " + column);
                    }
                    break;
                }
                i++;
            } else if (rec instanceof ObjRecord) {
 --- end ------------

With this code, my program crashed with NullPointerException on line of 'comment.setString(txo.getStr());', because a local variable 'txo' is null.
I changed the code like bellow, then the program works correctly.

--- changed code ---
        for (Iterator<RecordBase> it = sheet.getRecords().iterator(); it.hasNext();) {
            RecordBase rec = it.next();
            if (rec instanceof NoteRecord) {
                NoteRecord note = (NoteRecord) rec;
                if (note.getRow() == row && note.getColumn() == column) {
                    if(i < noteTxo.size()) {
                        TextObjectRecord txo = noteTxo.get(note.getShapeId());
                        
                        //NEXT LINE IS ADDED
                        if(txo != null) { // <-- MUST CHECK txo IS NOT NULL.
                            comment = new HSSFComment(note, txo);
                            comment.setRow(note.getRow());
                            comment.setColumn((short) note.getColumn());
                            comment.setAuthor(note.getAuthor());
                            comment.setVisible(note.getFlags() == NoteRecord.NOTE_VISIBLE);
                            comment.setString(txo.getStr());
                        } else {
                            log.log(POILogger.WARN, "Failed to match NoteRecord and TextObjectRecord, row: " + row + ", column: " + column);
                        }

                    } else {
                        log.log(POILogger.WARN, "Failed to match NoteRecord and TextObjectRecord, row: " + row + ", column: " + column);
                    }
                    break;
                }
                i++;
            } else if (rec instanceof ObjRecord) {
--- end ------------

Thanks.
Comment 1 Yegor Kozlov 2010-03-15 06:35:09 UTC
The suggested fix looks OK, but can you upload a sample file that demonstrates the "null  TextObjectRecord"  issue? I would like to have a junit test case for this fix.

Yegor
Comment 2 nothize 2010-03-18 07:57:16 UTC
This issue seems to be related with 47624.

The TextObjectRecord was not removed properly after an EscherAggregate record has came into play. It was supposed to be part of a paired DrawingRecord and TextObjectRecord for a cell comment.
Comment 3 Yegor Kozlov 2010-05-22 12:24:47 UTC
Fixed in r947315

Thanks,
Yegor