Bug 41246 - AIOOBE with missing notes entries

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1553760 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2013-12-27 23:42:34 +00:00
parent 42933d40bc
commit ad6a8a3cd1
5 changed files with 74 additions and 33 deletions

View File

@ -274,11 +274,11 @@ public final class HSLFSlideShow extends POIDocument {
HashMap<Integer,Integer> offset2id = new HashMap<Integer,Integer>(); HashMap<Integer,Integer> offset2id = new HashMap<Integer,Integer>();
while (usrOffset != 0){ while (usrOffset != 0){
UserEditAtom usr = (UserEditAtom) Record.buildRecordAtOffset(docstream, usrOffset); UserEditAtom usr = (UserEditAtom) Record.buildRecordAtOffset(docstream, usrOffset);
lst.add(Integer.valueOf(usrOffset)); lst.add(usrOffset);
int psrOffset = usr.getPersistPointersOffset(); int psrOffset = usr.getPersistPointersOffset();
PersistPtrHolder ptr = (PersistPtrHolder)Record.buildRecordAtOffset(docstream, psrOffset); PersistPtrHolder ptr = (PersistPtrHolder)Record.buildRecordAtOffset(docstream, psrOffset);
lst.add(Integer.valueOf(psrOffset)); lst.add(psrOffset);
Hashtable<Integer,Integer> entries = ptr.getSlideLocationsLookup(); Hashtable<Integer,Integer> entries = ptr.getSlideLocationsLookup();
for(Integer id : entries.keySet()) { for(Integer id : entries.keySet()) {
Integer offset = entries.get(id); Integer offset = entries.get(id);

View File

@ -203,20 +203,24 @@ public final class SlideShow {
_sheetIdToCoreRecordsLookup.put(allIDs[i], i); _sheetIdToCoreRecordsLookup.put(allIDs[i], i);
} }
Map<Integer,Integer> mostRecentByBytesRev = new HashMap<Integer,Integer>(mostRecentByBytes.size());
for (Map.Entry<Integer,Integer> me : mostRecentByBytes.entrySet()) {
mostRecentByBytesRev.put(me.getValue(), me.getKey());
}
// Now convert the byte offsets back into record offsets // Now convert the byte offsets back into record offsets
for (Record record : _hslfSlideShow.getRecords()) { for (Record record : _hslfSlideShow.getRecords()) {
if (record instanceof PositionDependentRecord) { if (!(record instanceof PositionDependentRecord)) continue;
PositionDependentRecord pdr = (PositionDependentRecord) record; PositionDependentRecord pdr = (PositionDependentRecord) record;
int recordAt = pdr.getLastOnDiskOffset(); int recordAt = pdr.getLastOnDiskOffset();
// Is it one we care about? Integer thisID = mostRecentByBytesRev.get(recordAt);
for (Integer thisID : allIDs) {
int thatRecordAt = mostRecentByBytes.get(thisID); if (thisID == null) continue;
if (thatRecordAt == recordAt) {
// Bingo. Now, where do we store it? // Bingo. Now, where do we store it?
Integer storeAtI = _sheetIdToCoreRecordsLookup.get(thisID); int storeAt = _sheetIdToCoreRecordsLookup.get(thisID);
int storeAt = storeAtI.intValue();
// Tell it its Sheet ID, if it cares // Tell it its Sheet ID, if it cares
if (pdr instanceof PositionDependentRecordContainer) { if (pdr instanceof PositionDependentRecordContainer) {
@ -227,9 +231,6 @@ public final class SlideShow {
// Finally, save the record // Finally, save the record
_mostRecentCoreRecords[storeAt] = record; _mostRecentCoreRecords[storeAt] = record;
} }
}
}
}
// Now look for the interesting records in there // Now look for the interesting records in there
for (Record record : _mostRecentCoreRecords) { for (Record record : _mostRecentCoreRecords) {
@ -265,9 +266,9 @@ public final class SlideShow {
* the refID * the refID
*/ */
private Record getCoreRecordForRefID(int refID) { private Record getCoreRecordForRefID(int refID) {
Integer coreRecordId = _sheetIdToCoreRecordsLookup.get(Integer.valueOf(refID)); Integer coreRecordId = _sheetIdToCoreRecordsLookup.get(refID);
if (coreRecordId != null) { if (coreRecordId != null) {
Record r = _mostRecentCoreRecords[coreRecordId.intValue()]; Record r = _mostRecentCoreRecords[coreRecordId];
return r; return r;
} }
logger.log(POILogger.ERROR, logger.log(POILogger.ERROR,
@ -361,7 +362,15 @@ public final class SlideShow {
Record r = getCoreRecordForSAS(notesSets[i]); Record r = getCoreRecordForSAS(notesSets[i]);
// Ensure it really is a notes record // Ensure it really is a notes record
if (r instanceof org.apache.poi.hslf.record.Notes) { if (r == null || r instanceof org.apache.poi.hslf.record.Notes) {
if (r == null) {
logger.log(POILogger.WARN, "A Notes SlideAtomSet at " + i
+ " said its record was at refID "
+ notesSets[i].getSlidePersistAtom().getRefID()
+ ", but that record didn't exist - record ignored.");
}
// we need to add also null-records, otherwise the index references to other existing
// don't work anymore
org.apache.poi.hslf.record.Notes notesRecord = (org.apache.poi.hslf.record.Notes) r; org.apache.poi.hslf.record.Notes notesRecord = (org.apache.poi.hslf.record.Notes) r;
notesRecordsL.add(notesRecord); notesRecordsL.add(notesRecord);
@ -410,9 +419,11 @@ public final class SlideShow {
// Notes first // Notes first
_notes = new Notes[notesRecords.length]; _notes = new Notes[notesRecords.length];
for (int i = 0; i < _notes.length; i++) { for (int i = 0; i < _notes.length; i++) {
if (notesRecords[i] != null) {
_notes[i] = new Notes(notesRecords[i]); _notes[i] = new Notes(notesRecords[i]);
_notes[i].setSlideShow(this); _notes[i].setSlideShow(this);
} }
}
// Then slides // Then slides
_slides = new Slide[slidesRecords.length]; _slides = new Slide[slidesRecords.length];
for (int i = 0; i < _slides.length; i++) { for (int i = 0; i < _slides.length; i++) {
@ -425,12 +436,13 @@ public final class SlideShow {
// 0 if slide has no notes. // 0 if slide has no notes.
int noteId = slidesRecords[i].getSlideAtom().getNotesID(); int noteId = slidesRecords[i].getSlideAtom().getNotesID();
if (noteId != 0) { if (noteId != 0) {
Integer notesPos = (Integer) slideIdToNotes.get(Integer.valueOf(noteId)); Integer notesPos = slideIdToNotes.get(noteId);
if (notesPos != null) if (notesPos != null) {
notes = _notes[notesPos.intValue()]; notes = _notes[notesPos];
else } else {
logger.log(POILogger.ERROR, "Notes not found for noteId=" + noteId); logger.log(POILogger.ERROR, "Notes not found for noteId=" + noteId);
} }
}
// Now, build our slide // Now, build our slide
_slides[i] = new Slide(slidesRecords[i], notes, sas, slideIdentifier, (i + 1)); _slides[i] = new Slide(slidesRecords[i], notes, sas, slideIdentifier, (i + 1));

View File

@ -17,6 +17,7 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -27,7 +28,9 @@ import java.util.Set;
import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.HSLFSlideShow; import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.HSLFTestDataSamples;
import org.apache.poi.hslf.exceptions.OldPowerPointFormatException; import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
import org.apache.poi.hslf.model.Background; import org.apache.poi.hslf.model.Background;
import org.apache.poi.hslf.model.Fill; import org.apache.poi.hslf.model.Fill;
@ -42,7 +45,6 @@ import org.apache.poi.hslf.model.TextBox;
import org.apache.poi.hslf.model.TextRun; import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.model.TextShape; import org.apache.poi.hslf.model.TextShape;
import org.apache.poi.hslf.model.TitleMaster; import org.apache.poi.hslf.model.TitleMaster;
import org.apache.poi.POIDataSamples;
/** /**
* Testcases for bugs entered in bugzilla * Testcases for bugs entered in bugzilla
@ -406,4 +408,31 @@ public final class TestBugs extends TestCase {
} }
} }
} }
/**
* Bug 41246: AIOOB with illegal note references
*/
public void test41246a() throws Exception {
InputStream fis = _slTests.openResourceAsStream("41246-1.ppt");
HSLFSlideShow hslf = new HSLFSlideShow(fis);
fis.close();
SlideShow ppt = new SlideShow(hslf);
assertTrue("No Exceptions while reading file", true);
ppt = HSLFTestDataSamples.writeOutAndReadBack(ppt);
assertTrue("No Exceptions while rewriting file", true);
}
public void test41246b() throws Exception {
InputStream fis = _slTests.openResourceAsStream("41246-2.ppt");
HSLFSlideShow hslf = new HSLFSlideShow(fis);
fis.close();
SlideShow ppt = new SlideShow(hslf);
assertTrue("No Exceptions while reading file", true);
ppt = HSLFTestDataSamples.writeOutAndReadBack(ppt);
assertTrue("No Exceptions while rewriting file", true);
}
} }

Binary file not shown.

Binary file not shown.