From 4841ed0d4709755837cc5bfa8f10b0e6897b79f0 Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Sun, 6 Sep 2009 11:35:01 +0000 Subject: [PATCH] Fixed PPT parser to tolerate Comment2000 containers with missing comment text, see Bugzilla 44770 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@811814 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../apache/poi/hslf/record/Comment2000.java | 70 +++++++++++-------- .../poi/hslf/record/TestComment2000.java | 28 ++++++++ 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 019186771..449f54d16 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -33,6 +33,7 @@ + 44770 - Fixed PPT parser to tolerate Comment2000 containers with missing comment text 47773 - Fix for extraction paragraphs and sections from headers/footers with XWPFWordExtractor 47727 - Support for extraction of header / footer images in HWPF moved all test data to a top-level directory diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000.java b/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000.java index 0a65cdbff..2714bad29 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Comment2000.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.OutputStream; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.POILogger; /** * This class represents a comment on a slide, in the format used by @@ -32,10 +33,24 @@ public final class Comment2000 extends RecordContainer { private static long _type = 12000; // Links to our more interesting children - private CString authorRecord; - private CString authorInitialsRecord; - private CString commentRecord; - private Comment2000Atom commentAtom; + + /** + * An optional string that specifies the name of the author of the presentation comment. + */ + private CString authorRecord; + /** + * An optional string record that specifies the text of the presentation comment + */ + private CString authorInitialsRecord; + /** + * An optional string record that specifies the initials of the author of the presentation comment + */ + private CString commentRecord; + + /** + * A Comment2000Atom record that specifies the settings for displaying the presentation comment + */ + private Comment2000Atom commentAtom; /** * Returns the Comment2000Atom of this Comment @@ -46,7 +61,7 @@ public final class Comment2000 extends RecordContainer { * Get the Author of this comment */ public String getAuthor() { - return authorRecord.getText(); + return authorRecord == null ? null : authorRecord.getText(); } /** * Set the Author of this comment @@ -59,7 +74,7 @@ public final class Comment2000 extends RecordContainer { * Get the Author's Initials of this comment */ public String getAuthorInitials() { - return authorInitialsRecord.getText(); + return authorInitialsRecord == null ? null : authorInitialsRecord.getText(); } /** * Set the Author's Initials of this comment @@ -72,7 +87,7 @@ public final class Comment2000 extends RecordContainer { * Get the text of this comment */ public String getText() { - return commentRecord.getText(); + return commentRecord == null ? null : commentRecord.getText(); } /** * Set the text of this comment @@ -100,30 +115,23 @@ public final class Comment2000 extends RecordContainer { * methods. */ private void findInterestingChildren() { - // First child should be the author - if(_children[0] instanceof CString) { - authorRecord = (CString)_children[0]; - } else { - throw new IllegalStateException("First child record wasn't a CString, was of type " + _children[0].getRecordType()); - } - // Second child should be the text - if(_children[1] instanceof CString) { - commentRecord = (CString)_children[1]; - } else { - throw new IllegalStateException("Second child record wasn't a CString, was of type " + _children[1].getRecordType()); - } - // Third child should be the author's initials - if(_children[2] instanceof CString) { - authorInitialsRecord = (CString)_children[2]; - } else { - throw new IllegalStateException("Third child record wasn't a CString, was of type " + _children[2].getRecordType()); - } - // Fourth child should be the comment atom - if(_children[3] instanceof Comment2000Atom) { - commentAtom = (Comment2000Atom)_children[3]; - } else { - throw new IllegalStateException("Fourth child record wasn't a Comment2000Atom, was of type " + _children[3].getRecordType()); - } + + for(Record r : _children){ + if (r instanceof CString){ + CString cs = (CString)r; + int recInstance = cs.getOptions() >> 4; + switch(recInstance){ + case 0: authorRecord = cs; break; + case 1: commentRecord = cs; break; + case 2: authorInitialsRecord = cs; break; + } + } else if (r instanceof Comment2000Atom){ + commentAtom = (Comment2000Atom)r; + } else { + logger.log(POILogger.WARN, "Unexpected record with type="+r.getRecordType()+" in Comment2000: " + r.getClass().getName()); + } + } + } /** diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000.java index a3e1f2d8a..0f7c30b06 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestComment2000.java @@ -192,4 +192,32 @@ public final class TestComment2000 extends TestCase { assertEquals(data_b[i],bn[i]); } } + + /** + * A Comment2000 records with missing commentTextAtom + */ + public void testBug44770() { + byte[] data = { + 0x0F, 0x00, (byte)0xE0, 0x2E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xBA, 0x0F, + 0x08, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x45, 0x00, 0x53, 0x00, 0x53, 0x00, 0x20, + 0x00, (byte)0xBA, 0x0F, 0x02, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x00, (byte)0xE1, 0x2E, + 0x1C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, (byte)0xD9, 0x07, 0x08, 0x00, + 0x01, 0x00, 0x18, 0x00, 0x10, 0x00, 0x1F, 0x00, 0x05, 0x00, (byte)0x80, 0x03, + 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 00 + }; + Comment2000 ca = new Comment2000(data, 0, data.length); + Record[] ch = ca.getChildRecords(); + assertEquals(3, ch.length); + + assertTrue(ch[0] instanceof CString); + assertEquals(0, ((CString)ch[0]).getOptions() >> 4); + assertTrue(ch[1] instanceof CString); + assertEquals(2, ((CString)ch[1]).getOptions() >> 4); + assertTrue(ch[2] instanceof Comment2000Atom); + + assertEquals("NESS", ca.getAuthor()); + assertEquals("N", ca.getAuthorInitials()); + assertNull(ca.getText()); //commentTextAtom is missing + } + }