diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hsmf/datatypes/PropertiesChunk.java b/poi-scratchpad/src/main/java/org/apache/poi/hsmf/datatypes/PropertiesChunk.java index 91692e3897..7b037f3e5b 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hsmf/datatypes/PropertiesChunk.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hsmf/datatypes/PropertiesChunk.java @@ -209,6 +209,12 @@ public abstract class PropertiesChunk extends Chunk { int id = LittleEndian.readUShort(value); long flags = LittleEndian.readUInt(value); + boolean multivalued = false; + if ((typeID & Types.MULTIVALUED_FLAG) != 0) { + typeID -= Types.MULTIVALUED_FLAG; + multivalued = true; + } + // Turn the Type and ID into helper objects MAPIType type = Types.getById(typeID); MAPIProperty prop = MAPIProperty.get(id); @@ -255,7 +261,7 @@ public abstract class PropertiesChunk extends Chunk { // to another chunk which holds the data itself boolean isPointer = false; int length = type.getLength(); - if (type.isPointer()) { + if (type.isPointer() || multivalued) { isPointer = true; length = 8; } diff --git a/poi-scratchpad/src/test/java/org/apache/poi/hsmf/TestBasics.java b/poi-scratchpad/src/test/java/org/apache/poi/hsmf/TestBasics.java index 83f59bd789..49dea29aff 100644 --- a/poi-scratchpad/src/test/java/org/apache/poi/hsmf/TestBasics.java +++ b/poi-scratchpad/src/test/java/org/apache/poi/hsmf/TestBasics.java @@ -19,13 +19,20 @@ package org.apache.poi.hsmf; import static org.apache.poi.POITestCase.assertContains; import static org.apache.poi.POITestCase.assertStartsWith; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import org.apache.poi.POIDataSamples; import org.apache.poi.hsmf.datatypes.AttachmentChunks; +import org.apache.poi.hsmf.datatypes.Chunks; import org.apache.poi.hsmf.datatypes.DirectoryChunk; +import org.apache.poi.hsmf.datatypes.MAPIProperty; import org.apache.poi.hsmf.exceptions.ChunkNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; @@ -273,4 +280,33 @@ public final class TestBasics { } } } + + @Test + void testBug69315() throws Exception { + POIDataSamples testData = POIDataSamples.getPOIFSInstance(); + try (MAPIMessage mapi = new MAPIMessage(testData.openResourceAsStream("MailSentPropertyMultiple.msg"))) { + assertNotNull(mapi.getAttachmentFiles()); + assertNotNull(mapi.getDisplayBCC()); + assertNotNull(mapi.getMessageDate()); + + Chunks chunks = mapi.getMainChunks(); + assertNotNull(chunks); + assertNotNull(chunks.getRawProperties()); + assertNotNull(chunks.getRawProperties().get(MAPIProperty.CLIENT_SUBMIT_TIME)); + + AttachmentChunks[] attachments = mapi.getAttachmentFiles(); + for (AttachmentChunks attachment : attachments) { + DirectoryChunk chunkDirectory = attachment.getAttachmentDirectory(); + if (chunkDirectory != null) { + MAPIMessage attachmentMSG = chunkDirectory.getAsEmbeddedMessage(); + assertNotNull(attachmentMSG); + String body = attachmentMSG.getTextBody(); + assertNotNull(body); + } + } + + assertNull(mapi.getSummaryInformation()); + assertNull(mapi.getDocumentSummaryInformation()); + } + } } diff --git a/test-data/poifs/MailSentPropertyMultiple.msg b/test-data/poifs/MailSentPropertyMultiple.msg new file mode 100644 index 0000000000..d07feb178e Binary files /dev/null and b/test-data/poifs/MailSentPropertyMultiple.msg differ diff --git a/test-data/spreadsheet/stress.xls b/test-data/spreadsheet/stress.xls index 1667a30b74..e4afaf91d6 100644 Binary files a/test-data/spreadsheet/stress.xls and b/test-data/spreadsheet/stress.xls differ