Browse Source

Bug 66425: Avoid a ClassCastException found via oss-fuzz

We try to avoid throwing ClassCastException, but it was possible
to trigger one here with a specially crafted input-file

Also rework test a bit to use try-with-resources and proper formatting

Should fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61221

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1911494 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_5_2_4
Dominik Stadler 9 months ago
parent
commit
1e8e95c3a6

+ 54
- 56
poi-scratchpad/src/main/java/org/apache/poi/hsmf/datatypes/Chunks.java View File

@@ -194,67 +194,65 @@ public final class Chunks implements ChunkGroupWithProperties {
public void record(Chunk chunk) {
// Work out what MAPIProperty this corresponds to
MAPIProperty prop = MAPIProperty.get(chunk.getChunkId());
if (prop == MAPIProperty.UNKNOWN) {
long id = (chunk.getChunkId() << 16) + (long)chunk.getType().getId();
prop = unknownProperties.get(id);
if (prop == null) {
prop = MAPIProperty.createCustom(chunk.getChunkId(), chunk.getType(), chunk.getEntryName());
unknownProperties.put(id, prop);
try {
if (prop == MAPIProperty.UNKNOWN) {
long id = (chunk.getChunkId() << 16) + (long) chunk.getType().getId();
prop = unknownProperties.get(id);
if (prop == null) {
prop = MAPIProperty.createCustom(chunk.getChunkId(), chunk.getType(), chunk.getEntryName());
unknownProperties.put(id, prop);
}
}
}

// Assign it for easy lookup, as best we can
if (prop == MAPIProperty.MESSAGE_CLASS) {
messageClass = (StringChunk) chunk;
} else if (prop == MAPIProperty.INTERNET_MESSAGE_ID) {
messageId = (StringChunk) chunk;
} else if (prop == MAPIProperty.MESSAGE_SUBMISSION_ID) {
// TODO - parse
submissionChunk = (MessageSubmissionChunk) chunk;
} else if (prop == MAPIProperty.RECEIVED_BY_ADDRTYPE) {
sentByServerType = (StringChunk) chunk;
} else if (prop == MAPIProperty.TRANSPORT_MESSAGE_HEADERS) {
messageHeaders = (StringChunk) chunk;
}

else if (prop == MAPIProperty.CONVERSATION_TOPIC) {
conversationTopic = (StringChunk) chunk;
} else if (prop == MAPIProperty.SUBJECT) {
subjectChunk = (StringChunk) chunk;
} /*else if (prop == MAPIProperty.ORIGINAL_SUBJECT) {
// Assign it for easy lookup, as best we can
if (prop == MAPIProperty.MESSAGE_CLASS) {
messageClass = (StringChunk) chunk;
} else if (prop == MAPIProperty.INTERNET_MESSAGE_ID) {
messageId = (StringChunk) chunk;
} else if (prop == MAPIProperty.MESSAGE_SUBMISSION_ID) {
// TODO - parse
submissionChunk = (MessageSubmissionChunk) chunk;
} else if (prop == MAPIProperty.RECEIVED_BY_ADDRTYPE) {
sentByServerType = (StringChunk) chunk;
} else if (prop == MAPIProperty.TRANSPORT_MESSAGE_HEADERS) {
messageHeaders = (StringChunk) chunk;
} else if (prop == MAPIProperty.CONVERSATION_TOPIC) {
conversationTopic = (StringChunk) chunk;
} else if (prop == MAPIProperty.SUBJECT) {
subjectChunk = (StringChunk) chunk;
} /*else if (prop == MAPIProperty.ORIGINAL_SUBJECT) {
// TODO
}*/

else if (prop == MAPIProperty.DISPLAY_TO) {
displayToChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.DISPLAY_CC) {
displayCCChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.DISPLAY_BCC) {
displayBCCChunk = (StringChunk) chunk;
}

else if (prop == MAPIProperty.SENDER_EMAIL_ADDRESS) {
emailFromChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.SENDER_NAME) {
displayFromChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.BODY) {
textBodyChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.BODY_HTML) {
if (chunk instanceof StringChunk) {
htmlBodyChunkString = (StringChunk) chunk;
}
if (chunk instanceof ByteChunk) {
htmlBodyChunkBinary = (ByteChunk) chunk;
}*/ else if (prop == MAPIProperty.DISPLAY_TO) {
displayToChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.DISPLAY_CC) {
displayCCChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.DISPLAY_BCC) {
displayBCCChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.SENDER_EMAIL_ADDRESS) {
emailFromChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.SENDER_NAME) {
displayFromChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.BODY) {
textBodyChunk = (StringChunk) chunk;
} else if (prop == MAPIProperty.BODY_HTML) {
if (chunk instanceof StringChunk) {
htmlBodyChunkString = (StringChunk) chunk;
}
if (chunk instanceof ByteChunk) {
htmlBodyChunkBinary = (ByteChunk) chunk;
}
} else if (prop == MAPIProperty.RTF_COMPRESSED) {
rtfBodyChunk = (ByteChunk) chunk;
} else if (chunk instanceof MessagePropertiesChunk) {
messageProperties = (MessagePropertiesChunk) chunk;
}
} else if (prop == MAPIProperty.RTF_COMPRESSED) {
rtfBodyChunk = (ByteChunk) chunk;
} else if (chunk instanceof MessagePropertiesChunk) {
messageProperties = (MessagePropertiesChunk) chunk;
}

// And add to the main list
allChunks.computeIfAbsent(prop, k -> new ArrayList<>());
allChunks.get(prop).add(chunk);
// And add to the main list
allChunks.computeIfAbsent(prop, k -> new ArrayList<>());
allChunks.get(prop).add(chunk);
} catch (ClassCastException e) {
throw new IllegalArgumentException("Property and type of chunk did not match, had property " + prop + " and type of chunk: " + chunk.getClass());
}
}

@Override

+ 291
- 290
poi-scratchpad/src/test/java/org/apache/poi/hsmf/parsers/TestPOIFSChunkParser.java View File

@@ -21,6 +21,7 @@ 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;
@@ -48,294 +49,294 @@ import org.junit.jupiter.api.Test;
* Tests to verify that the chunk parser works properly
*/
public final class TestPOIFSChunkParser {
private final POIDataSamples samples = POIDataSamples.getHSMFInstance();
@Test
void testFindsCore() throws IOException, ChunkNotFoundException {
POIFSFileSystem simple = new POIFSFileSystem(samples.getFile("quick.msg"), true);
// Check a few core things are present
simple.getRoot().getEntry(
(new StringChunk(MAPIProperty.SUBJECT.id, Types.ASCII_STRING)).getEntryName()
);
simple.getRoot().getEntry(
(new StringChunk(MAPIProperty.SENDER_NAME.id, Types.ASCII_STRING)).getEntryName()
);
// Now load the file
MAPIMessage msg = new MAPIMessage(simple);
assertEquals("Kevin Roast", msg.getDisplayTo());
assertEquals("Kevin Roast", msg.getDisplayFrom());
assertEquals("Test the content transformer", msg.getSubject());
// Check date too
Calendar calExp = LocaleUtil.getLocaleCalendar(2007,5,14,9,42,55);
Calendar calAct = msg.getMessageDate();
assertEquals( calExp, calAct );
msg.close();
simple.close();
}
@Test
void testFindsRecips() throws IOException, ChunkNotFoundException {
POIFSFileSystem simple = new POIFSFileSystem(samples.getFile("quick.msg"), true);
simple.getRoot().getEntry("__recip_version1.0_#00000000");
ChunkGroup[] groups = POIFSChunkParser.parse(simple.getRoot());
assertEquals(3, groups.length);
assertTrue(groups[0] instanceof Chunks);
assertTrue(groups[1] instanceof RecipientChunks);
assertTrue(groups[2] instanceof NameIdChunks);
RecipientChunks recips = (RecipientChunks)groups[1];
assertEquals("kevin.roast@alfresco.org", recips.getRecipientSMTPChunk().getValue());
assertEquals("/O=HOSTEDSERVICE2/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=Kevin.roast@ben",
recips.getRecipientEmailChunk().getValue());
String search = new String(recips.getRecipientSearchChunk().getValue(), StandardCharsets.US_ASCII);
assertEquals("CN=KEVIN.ROAST@BEN\0", search.substring(search.length()-19));
// Now via MAPIMessage
MAPIMessage msg = new MAPIMessage(simple);
assertNotNull(msg.getRecipientDetailsChunks());
assertEquals(1, msg.getRecipientDetailsChunks().length);
assertEquals("kevin.roast@alfresco.org", msg.getRecipientDetailsChunks()[0].getRecipientSMTPChunk().getValue());
assertEquals("kevin.roast@alfresco.org", msg.getRecipientDetailsChunks()[0].getRecipientEmailAddress());
assertEquals("Kevin Roast", msg.getRecipientDetailsChunks()[0].getRecipientName());
assertEquals("kevin.roast@alfresco.org", msg.getRecipientEmailAddress());
// Try both SMTP and EX files for recipient
assertEquals("EX", msg.getRecipientDetailsChunks()[0].getDeliveryTypeChunk().getValue());
assertEquals("kevin.roast@alfresco.org", msg.getRecipientDetailsChunks()[0].getRecipientSMTPChunk().getValue());
assertEquals("/O=HOSTEDSERVICE2/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=Kevin.roast@ben",
msg.getRecipientDetailsChunks()[0].getRecipientEmailChunk().getValue());
msg.close();
simple.close();
// Now look at another message
simple = new POIFSFileSystem(samples.getFile("simple_test_msg.msg"), true);
msg = new MAPIMessage(simple);
assertNotNull(msg.getRecipientDetailsChunks());
assertEquals(1, msg.getRecipientDetailsChunks().length);
assertEquals("SMTP", msg.getRecipientDetailsChunks()[0].getDeliveryTypeChunk().getValue());
assertNull(msg.getRecipientDetailsChunks()[0].getRecipientSMTPChunk());
assertNull(msg.getRecipientDetailsChunks()[0].getRecipientNameChunk());
assertEquals("travis@overwrittenstack.com", msg.getRecipientDetailsChunks()[0].getRecipientEmailChunk().getValue());
assertEquals("travis@overwrittenstack.com", msg.getRecipientEmailAddress());
msg.close();
simple.close();
}
@Test
void testFindsMultipleRecipients() throws IOException, ChunkNotFoundException {
POIFSFileSystem multiple = new POIFSFileSystem(samples.getFile("example_received_unicode.msg"), true);
multiple.getRoot().getEntry("__recip_version1.0_#00000000");
multiple.getRoot().getEntry("__recip_version1.0_#00000001");
multiple.getRoot().getEntry("__recip_version1.0_#00000002");
multiple.getRoot().getEntry("__recip_version1.0_#00000003");
multiple.getRoot().getEntry("__recip_version1.0_#00000004");
multiple.getRoot().getEntry("__recip_version1.0_#00000005");
ChunkGroup[] groups = POIFSChunkParser.parse(multiple.getRoot());
assertEquals(9, groups.length);
assertTrue(groups[0] instanceof Chunks);
assertTrue(groups[1] instanceof RecipientChunks);
assertTrue(groups[2] instanceof RecipientChunks);
assertTrue(groups[3] instanceof RecipientChunks);
assertTrue(groups[4] instanceof RecipientChunks);
assertTrue(groups[5] instanceof AttachmentChunks);
assertTrue(groups[6] instanceof RecipientChunks);
assertTrue(groups[7] instanceof RecipientChunks);
assertTrue(groups[8] instanceof NameIdChunks);
// In FS order initially
RecipientChunks[] chunks = new RecipientChunks[] {
(RecipientChunks)groups[1],
(RecipientChunks)groups[2],
(RecipientChunks)groups[3],
(RecipientChunks)groups[4],
(RecipientChunks)groups[6],
(RecipientChunks)groups[7],
};
assertEquals(6, chunks.length);
assertEquals(0, chunks[0].getRecipientNumber());
assertEquals(2, chunks[1].getRecipientNumber());
assertEquals(4, chunks[2].getRecipientNumber());
assertEquals(5, chunks[3].getRecipientNumber());
assertEquals(3, chunks[4].getRecipientNumber());
assertEquals(1, chunks[5].getRecipientNumber());
// Check
assertEquals("'Ashutosh Dandavate'", chunks[0].getRecipientName());
assertEquals("ashutosh.dandavate@alfresco.com", chunks[0].getRecipientEmailAddress());
assertEquals("'Mike Farman'", chunks[1].getRecipientName());
assertEquals("mikef@alfresco.com", chunks[1].getRecipientEmailAddress());
assertEquals("nick.burch@alfresco.com", chunks[2].getRecipientName());
assertEquals("nick.burch@alfresco.com", chunks[2].getRecipientEmailAddress());
assertEquals("'Roy Wetherall'", chunks[3].getRecipientName());
assertEquals("roy.wetherall@alfresco.com", chunks[3].getRecipientEmailAddress());
assertEquals("nickb@alfresco.com", chunks[4].getRecipientName());
assertEquals("nickb@alfresco.com", chunks[4].getRecipientEmailAddress());
assertEquals("'Paul Holmes-Higgin'", chunks[5].getRecipientName());
assertEquals("paul.hh@alfresco.com", chunks[5].getRecipientEmailAddress());
// Now sort, and re-check
Arrays.sort(chunks, new RecipientChunksSorter());
assertEquals("'Ashutosh Dandavate'", chunks[0].getRecipientName());
assertEquals("ashutosh.dandavate@alfresco.com", chunks[0].getRecipientEmailAddress());
assertEquals("'Paul Holmes-Higgin'", chunks[1].getRecipientName());
assertEquals("paul.hh@alfresco.com", chunks[1].getRecipientEmailAddress());
assertEquals("'Mike Farman'", chunks[2].getRecipientName());
assertEquals("mikef@alfresco.com", chunks[2].getRecipientEmailAddress());
assertEquals("nickb@alfresco.com", chunks[3].getRecipientName());
assertEquals("nickb@alfresco.com", chunks[3].getRecipientEmailAddress());
assertEquals("nick.burch@alfresco.com", chunks[4].getRecipientName());
assertEquals("nick.burch@alfresco.com", chunks[4].getRecipientEmailAddress());
assertEquals("'Roy Wetherall'", chunks[5].getRecipientName());
assertEquals("roy.wetherall@alfresco.com", chunks[5].getRecipientEmailAddress());
// Finally check on message
MAPIMessage msg = new MAPIMessage(multiple);
assertEquals(6, msg.getRecipientEmailAddressList().length);
assertEquals(6, msg.getRecipientNamesList().length);
assertEquals("'Ashutosh Dandavate'", msg.getRecipientNamesList()[0]);
assertEquals("'Paul Holmes-Higgin'", msg.getRecipientNamesList()[1]);
assertEquals("'Mike Farman'", msg.getRecipientNamesList()[2]);
assertEquals("nickb@alfresco.com", msg.getRecipientNamesList()[3]);
assertEquals("nick.burch@alfresco.com", msg.getRecipientNamesList()[4]);
assertEquals("'Roy Wetherall'", msg.getRecipientNamesList()[5]);
assertEquals("ashutosh.dandavate@alfresco.com", msg.getRecipientEmailAddressList()[0]);
assertEquals("paul.hh@alfresco.com", msg.getRecipientEmailAddressList()[1]);
assertEquals("mikef@alfresco.com", msg.getRecipientEmailAddressList()[2]);
assertEquals("nickb@alfresco.com", msg.getRecipientEmailAddressList()[3]);
assertEquals("nick.burch@alfresco.com", msg.getRecipientEmailAddressList()[4]);
assertEquals("roy.wetherall@alfresco.com", msg.getRecipientEmailAddressList()[5]);
msg.close();
multiple.close();
}
@Test
void testFindsNameId() throws IOException {
POIFSFileSystem simple = new POIFSFileSystem(samples.getFile("quick.msg"), true);
simple.getRoot().getEntry("__nameid_version1.0");
ChunkGroup[] groups = POIFSChunkParser.parse(simple.getRoot());
assertEquals(3, groups.length);
assertTrue(groups[0] instanceof Chunks);
assertTrue(groups[1] instanceof RecipientChunks);
assertTrue(groups[2] instanceof NameIdChunks);
NameIdChunks nameId = (NameIdChunks)groups[2];
assertEquals(10, nameId.getAll().length);
// Now via MAPIMessage
MAPIMessage msg = new MAPIMessage(simple);
assertNotNull(msg.getNameIdChunks());
assertEquals(10, msg.getNameIdChunks().getAll().length);
msg.close();
simple.close();
}
@Test
void testFindsAttachments() throws IOException, ChunkNotFoundException {
POIFSFileSystem with = new POIFSFileSystem(samples.getFile("attachment_test_msg.msg"), true);
POIFSFileSystem without = new POIFSFileSystem(samples.getFile("quick.msg"), true);
AttachmentChunks attachment;
// Check raw details on the one with
with.getRoot().getEntry("__attach_version1.0_#00000000");
with.getRoot().getEntry("__attach_version1.0_#00000001");
POIFSChunkParser.parse(with.getRoot());
ChunkGroup[] groups = POIFSChunkParser.parse(with.getRoot());
assertEquals(5, groups.length);
assertTrue(groups[0] instanceof Chunks);
assertTrue(groups[1] instanceof RecipientChunks);
assertTrue(groups[2] instanceof AttachmentChunks);
assertTrue(groups[3] instanceof AttachmentChunks);
assertTrue(groups[4] instanceof NameIdChunks);
attachment = (AttachmentChunks)groups[2];
assertEquals("TEST-U~1.DOC", attachment.getAttachFileName().toString());
assertEquals("test-unicode.doc", attachment.getAttachLongFileName().toString());
assertEquals(24064, attachment.getAttachData().getValue().length);
attachment = (AttachmentChunks)groups[3];
assertEquals("pj1.txt", attachment.getAttachFileName().toString());
assertEquals("pj1.txt", attachment.getAttachLongFileName().toString());
assertEquals(89, attachment.getAttachData().getValue().length);
// Check raw details on one without
assertFalse(without.getRoot().hasEntry("__attach_version1.0_#00000000"));
assertFalse(without.getRoot().hasEntry("__attach_version1.0_#00000001"));
// One with, from the top
MAPIMessage msgWith = new MAPIMessage(with);
assertEquals(2, msgWith.getAttachmentFiles().length);
attachment = msgWith.getAttachmentFiles()[0];
assertEquals("TEST-U~1.DOC", attachment.getAttachFileName().toString());
assertEquals("test-unicode.doc", attachment.getAttachLongFileName().toString());
assertEquals(24064, attachment.getAttachData().getValue().length);
attachment = msgWith.getAttachmentFiles()[1];
assertEquals("pj1.txt", attachment.getAttachFileName().toString());
assertEquals("pj1.txt", attachment.getAttachLongFileName().toString());
assertEquals(89, attachment.getAttachData().getValue().length);
// Plus check core details are there
assertEquals("'nicolas1.23456@free.fr'", msgWith.getDisplayTo());
assertEquals("Nicolas1 23456", msgWith.getDisplayFrom());
assertEquals("test pi\u00e8ce jointe 1", msgWith.getSubject());
// One without, from the top
MAPIMessage msgWithout = new MAPIMessage(without);
// No attachments
assertEquals(0, msgWithout.getAttachmentFiles().length);
// But has core details
assertEquals("Kevin Roast", msgWithout.getDisplayTo());
assertEquals("Kevin Roast", msgWithout.getDisplayFrom());
assertEquals("Test the content transformer", msgWithout.getSubject());
msgWithout.close();
msgWith.close();
without.close();
with.close();
}
/**
* Bugzilla #51873 - Outlook 2002 files created with dragging and
* dropping files to the disk include a non-standard named streams
* such as "Olk10SideProps_0001"
*/
@Test
void testOlk10SideProps() throws IOException, ChunkNotFoundException {
POIFSFileSystem poifs = new POIFSFileSystem(samples.getFile("51873.msg"), true);
MAPIMessage msg = new MAPIMessage(poifs);
// Check core details came through
assertEquals("bubba@bubbasmith.com", msg.getDisplayTo());
assertEquals("Test with Olk10SideProps_ Chunk", msg.getSubject());
msg.close();
poifs.close();
}
private final POIDataSamples samples = POIDataSamples.getHSMFInstance();
@Test
void testFindsCore() throws IOException, ChunkNotFoundException {
try (POIFSFileSystem simple = new POIFSFileSystem(samples.getFile("quick.msg"), true)) {
// Check a few core things are present
simple.getRoot().getEntry(
(new StringChunk(MAPIProperty.SUBJECT.id, Types.ASCII_STRING)).getEntryName()
);
simple.getRoot().getEntry(
(new StringChunk(MAPIProperty.SENDER_NAME.id, Types.ASCII_STRING)).getEntryName()
);
// Now load the file
try (MAPIMessage msg = new MAPIMessage(simple)) {
assertEquals("Kevin Roast", msg.getDisplayTo());
assertEquals("Kevin Roast", msg.getDisplayFrom());
assertEquals("Test the content transformer", msg.getSubject());
// Check date too
Calendar calExp = LocaleUtil.getLocaleCalendar(2007, 5, 14, 9, 42, 55);
Calendar calAct = msg.getMessageDate();
assertEquals(calExp, calAct);
}
}
}
@Test
void testFindsRecips() throws IOException, ChunkNotFoundException {
try (POIFSFileSystem simple = new POIFSFileSystem(samples.getFile("quick.msg"), true)) {
simple.getRoot().getEntry("__recip_version1.0_#00000000");
ChunkGroup[] groups = POIFSChunkParser.parse(simple.getRoot());
assertEquals(3, groups.length);
assertTrue(groups[0] instanceof Chunks);
assertTrue(groups[1] instanceof RecipientChunks);
assertTrue(groups[2] instanceof NameIdChunks);
RecipientChunks recips = (RecipientChunks) groups[1];
assertEquals("kevin.roast@alfresco.org", recips.getRecipientSMTPChunk().getValue());
assertEquals("/O=HOSTEDSERVICE2/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=Kevin.roast@ben",
recips.getRecipientEmailChunk().getValue());
String search = new String(recips.getRecipientSearchChunk().getValue(), StandardCharsets.US_ASCII);
assertEquals("CN=KEVIN.ROAST@BEN\0", search.substring(search.length() - 19));
// Now via MAPIMessage
try (MAPIMessage msg = new MAPIMessage(simple)) {
assertNotNull(msg.getRecipientDetailsChunks());
assertEquals(1, msg.getRecipientDetailsChunks().length);
assertEquals("kevin.roast@alfresco.org", msg.getRecipientDetailsChunks()[0].getRecipientSMTPChunk().getValue());
assertEquals("kevin.roast@alfresco.org", msg.getRecipientDetailsChunks()[0].getRecipientEmailAddress());
assertEquals("Kevin Roast", msg.getRecipientDetailsChunks()[0].getRecipientName());
assertEquals("kevin.roast@alfresco.org", msg.getRecipientEmailAddress());
// Try both SMTP and EX files for recipient
assertEquals("EX", msg.getRecipientDetailsChunks()[0].getDeliveryTypeChunk().getValue());
assertEquals("kevin.roast@alfresco.org", msg.getRecipientDetailsChunks()[0].getRecipientSMTPChunk().getValue());
assertEquals("/O=HOSTEDSERVICE2/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=Kevin.roast@ben",
msg.getRecipientDetailsChunks()[0].getRecipientEmailChunk().getValue());
}
}
// Now look at another message
try (POIFSFileSystem simple = new POIFSFileSystem(samples.getFile("simple_test_msg.msg"), true)) {
try (MAPIMessage msg = new MAPIMessage(simple)) {
assertNotNull(msg.getRecipientDetailsChunks());
assertEquals(1, msg.getRecipientDetailsChunks().length);
assertEquals("SMTP", msg.getRecipientDetailsChunks()[0].getDeliveryTypeChunk().getValue());
assertNull(msg.getRecipientDetailsChunks()[0].getRecipientSMTPChunk());
assertNull(msg.getRecipientDetailsChunks()[0].getRecipientNameChunk());
assertEquals("travis@overwrittenstack.com",
msg.getRecipientDetailsChunks()[0].getRecipientEmailChunk().getValue());
assertEquals("travis@overwrittenstack.com", msg.getRecipientEmailAddress());
}
}
}
@Test
void testFindsMultipleRecipients() throws IOException, ChunkNotFoundException {
try (POIFSFileSystem multiple = new POIFSFileSystem(samples.getFile("example_received_unicode.msg"), true)) {
multiple.getRoot().getEntry("__recip_version1.0_#00000000");
multiple.getRoot().getEntry("__recip_version1.0_#00000001");
multiple.getRoot().getEntry("__recip_version1.0_#00000002");
multiple.getRoot().getEntry("__recip_version1.0_#00000003");
multiple.getRoot().getEntry("__recip_version1.0_#00000004");
multiple.getRoot().getEntry("__recip_version1.0_#00000005");
ChunkGroup[] groups = POIFSChunkParser.parse(multiple.getRoot());
assertEquals(9, groups.length);
assertTrue(groups[0] instanceof Chunks);
assertTrue(groups[1] instanceof RecipientChunks);
assertTrue(groups[2] instanceof RecipientChunks);
assertTrue(groups[3] instanceof RecipientChunks);
assertTrue(groups[4] instanceof RecipientChunks);
assertTrue(groups[5] instanceof AttachmentChunks);
assertTrue(groups[6] instanceof RecipientChunks);
assertTrue(groups[7] instanceof RecipientChunks);
assertTrue(groups[8] instanceof NameIdChunks);
// In FS order initially
RecipientChunks[] chunks = new RecipientChunks[] {
(RecipientChunks) groups[1],
(RecipientChunks) groups[2],
(RecipientChunks) groups[3],
(RecipientChunks) groups[4],
(RecipientChunks) groups[6],
(RecipientChunks) groups[7],
};
assertEquals(6, chunks.length);
assertEquals(0, chunks[0].getRecipientNumber());
assertEquals(2, chunks[1].getRecipientNumber());
assertEquals(4, chunks[2].getRecipientNumber());
assertEquals(5, chunks[3].getRecipientNumber());
assertEquals(3, chunks[4].getRecipientNumber());
assertEquals(1, chunks[5].getRecipientNumber());
// Check
assertEquals("'Ashutosh Dandavate'", chunks[0].getRecipientName());
assertEquals("ashutosh.dandavate@alfresco.com", chunks[0].getRecipientEmailAddress());
assertEquals("'Mike Farman'", chunks[1].getRecipientName());
assertEquals("mikef@alfresco.com", chunks[1].getRecipientEmailAddress());
assertEquals("nick.burch@alfresco.com", chunks[2].getRecipientName());
assertEquals("nick.burch@alfresco.com", chunks[2].getRecipientEmailAddress());
assertEquals("'Roy Wetherall'", chunks[3].getRecipientName());
assertEquals("roy.wetherall@alfresco.com", chunks[3].getRecipientEmailAddress());
assertEquals("nickb@alfresco.com", chunks[4].getRecipientName());
assertEquals("nickb@alfresco.com", chunks[4].getRecipientEmailAddress());
assertEquals("'Paul Holmes-Higgin'", chunks[5].getRecipientName());
assertEquals("paul.hh@alfresco.com", chunks[5].getRecipientEmailAddress());
// Now sort, and re-check
Arrays.sort(chunks, new RecipientChunksSorter());
assertEquals("'Ashutosh Dandavate'", chunks[0].getRecipientName());
assertEquals("ashutosh.dandavate@alfresco.com", chunks[0].getRecipientEmailAddress());
assertEquals("'Paul Holmes-Higgin'", chunks[1].getRecipientName());
assertEquals("paul.hh@alfresco.com", chunks[1].getRecipientEmailAddress());
assertEquals("'Mike Farman'", chunks[2].getRecipientName());
assertEquals("mikef@alfresco.com", chunks[2].getRecipientEmailAddress());
assertEquals("nickb@alfresco.com", chunks[3].getRecipientName());
assertEquals("nickb@alfresco.com", chunks[3].getRecipientEmailAddress());
assertEquals("nick.burch@alfresco.com", chunks[4].getRecipientName());
assertEquals("nick.burch@alfresco.com", chunks[4].getRecipientEmailAddress());
assertEquals("'Roy Wetherall'", chunks[5].getRecipientName());
assertEquals("roy.wetherall@alfresco.com", chunks[5].getRecipientEmailAddress());
// Finally check on message
try (MAPIMessage msg = new MAPIMessage(multiple)) {
assertEquals(6, msg.getRecipientEmailAddressList().length);
assertEquals(6, msg.getRecipientNamesList().length);
assertEquals("'Ashutosh Dandavate'", msg.getRecipientNamesList()[0]);
assertEquals("'Paul Holmes-Higgin'", msg.getRecipientNamesList()[1]);
assertEquals("'Mike Farman'", msg.getRecipientNamesList()[2]);
assertEquals("nickb@alfresco.com", msg.getRecipientNamesList()[3]);
assertEquals("nick.burch@alfresco.com", msg.getRecipientNamesList()[4]);
assertEquals("'Roy Wetherall'", msg.getRecipientNamesList()[5]);
assertEquals("ashutosh.dandavate@alfresco.com", msg.getRecipientEmailAddressList()[0]);
assertEquals("paul.hh@alfresco.com", msg.getRecipientEmailAddressList()[1]);
assertEquals("mikef@alfresco.com", msg.getRecipientEmailAddressList()[2]);
assertEquals("nickb@alfresco.com", msg.getRecipientEmailAddressList()[3]);
assertEquals("nick.burch@alfresco.com", msg.getRecipientEmailAddressList()[4]);
assertEquals("roy.wetherall@alfresco.com", msg.getRecipientEmailAddressList()[5]);
}
}
}
@Test
void testFindsNameId() throws IOException {
try (POIFSFileSystem simple = new POIFSFileSystem(samples.getFile("quick.msg"), true)) {
simple.getRoot().getEntry("__nameid_version1.0");
ChunkGroup[] groups = POIFSChunkParser.parse(simple.getRoot());
assertEquals(3, groups.length);
assertTrue(groups[0] instanceof Chunks);
assertTrue(groups[1] instanceof RecipientChunks);
assertTrue(groups[2] instanceof NameIdChunks);
NameIdChunks nameId = (NameIdChunks) groups[2];
assertEquals(10, nameId.getAll().length);
// Now via MAPIMessage
try (MAPIMessage msg = new MAPIMessage(simple)) {
assertNotNull(msg.getNameIdChunks());
assertEquals(10, msg.getNameIdChunks().getAll().length);
}
}
}
@Test
void testFindsAttachments() throws IOException, ChunkNotFoundException {
try (POIFSFileSystem with = new POIFSFileSystem(samples.getFile("attachment_test_msg.msg"), true);
POIFSFileSystem without = new POIFSFileSystem(samples.getFile("quick.msg"), true)) {
AttachmentChunks attachment;
// Check raw details on the one with
with.getRoot().getEntry("__attach_version1.0_#00000000");
with.getRoot().getEntry("__attach_version1.0_#00000001");
POIFSChunkParser.parse(with.getRoot());
ChunkGroup[] groups = POIFSChunkParser.parse(with.getRoot());
assertEquals(5, groups.length);
assertTrue(groups[0] instanceof Chunks);
assertTrue(groups[1] instanceof RecipientChunks);
assertTrue(groups[2] instanceof AttachmentChunks);
assertTrue(groups[3] instanceof AttachmentChunks);
assertTrue(groups[4] instanceof NameIdChunks);
attachment = (AttachmentChunks) groups[2];
assertEquals("TEST-U~1.DOC", attachment.getAttachFileName().toString());
assertEquals("test-unicode.doc", attachment.getAttachLongFileName().toString());
assertEquals(24064, attachment.getAttachData().getValue().length);
attachment = (AttachmentChunks) groups[3];
assertEquals("pj1.txt", attachment.getAttachFileName().toString());
assertEquals("pj1.txt", attachment.getAttachLongFileName().toString());
assertEquals(89, attachment.getAttachData().getValue().length);
// Check raw details on one without
assertFalse(without.getRoot().hasEntry("__attach_version1.0_#00000000"));
assertFalse(without.getRoot().hasEntry("__attach_version1.0_#00000001"));
// One with, from the top
try (MAPIMessage msgWith = new MAPIMessage(with)) {
assertEquals(2, msgWith.getAttachmentFiles().length);
attachment = msgWith.getAttachmentFiles()[0];
assertEquals("TEST-U~1.DOC", attachment.getAttachFileName().toString());
assertEquals("test-unicode.doc", attachment.getAttachLongFileName().toString());
assertEquals(24064, attachment.getAttachData().getValue().length);
attachment = msgWith.getAttachmentFiles()[1];
assertEquals("pj1.txt", attachment.getAttachFileName().toString());
assertEquals("pj1.txt", attachment.getAttachLongFileName().toString());
assertEquals(89, attachment.getAttachData().getValue().length);
// Plus check core details are there
assertEquals("'nicolas1.23456@free.fr'", msgWith.getDisplayTo());
assertEquals("Nicolas1 23456", msgWith.getDisplayFrom());
assertEquals("test pi\u00e8ce jointe 1", msgWith.getSubject());
// One without, from the top
try (MAPIMessage msgWithout = new MAPIMessage(without)) {
// No attachments
assertEquals(0, msgWithout.getAttachmentFiles().length);
// But has core details
assertEquals("Kevin Roast", msgWithout.getDisplayTo());
assertEquals("Kevin Roast", msgWithout.getDisplayFrom());
assertEquals("Test the content transformer", msgWithout.getSubject());
}
}
}
}
/**
* Bugzilla #51873 - Outlook 2002 files created with dragging and
* dropping files to the disk include a non-standard named streams
* such as "Olk10SideProps_0001"
*/
@Test
void testOlk10SideProps() throws IOException, ChunkNotFoundException {
try (POIFSFileSystem poifs = new POIFSFileSystem(samples.getFile("51873.msg"), true)) {
try (MAPIMessage msg = new MAPIMessage(poifs)) {
// Check core details came through
assertEquals("bubba@bubbasmith.com", msg.getDisplayTo());
assertEquals("Test with Olk10SideProps_ Chunk", msg.getSubject());
}
}
}
@Test
void testInvalidChunk() throws IOException {
try (POIFSFileSystem poifs =
new POIFSFileSystem(samples.getFile("clusterfuzz-testcase-minimized-POIHSMFFuzzer-4848576776503296.msg"), true)) {
assertThrows(IllegalArgumentException.class,
() -> new MAPIMessage(poifs));
}
}
}

BIN
test-data/hsmf/clusterfuzz-testcase-minimized-POIHSMFFuzzer-4848576776503296.msg View File


BIN
test-data/spreadsheet/stress.xls View File


Loading…
Cancel
Save