From: Andreas Beeker Date: Wed, 8 Jan 2020 00:49:39 +0000 (+0000) Subject: #63955 - HMEFContentsExtractor fails to extract content from winmail.dat X-Git-Tag: REL_4_1_2~33 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f7fe4b0d59b8030f16400ea064e7826da835e078;p=poi.git #63955 - HMEFContentsExtractor fails to extract content from winmail.dat added example file - optimized junit tests git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1872480 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java b/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java index 1220c23f32..c52591bf1d 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java @@ -17,7 +17,9 @@ package org.apache.poi.hmef; +import static org.apache.poi.hmef.TestHMEFMessage.openSample; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import java.io.IOException; import java.text.DateFormat; @@ -25,29 +27,23 @@ import java.text.SimpleDateFormat; import java.util.List; import java.util.Locale; -import org.apache.poi.POIDataSamples; import org.apache.poi.util.LocaleUtil; -import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; public final class TestAttachments { - protected static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); + private static HMEFMessage quick; - - private HMEFMessage quick; - - @Before - public void setUp() throws Exception { - quick = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); + @BeforeClass + public static void setUp() throws IOException { + quick = openSample("quick-winmail.dat"); } /** * Check the file is as we expect */ @Test - public void testCounts() throws Exception { + public void testCounts() { // Should have 5 attachments assertEquals(5, quick.getAttachments().size()); } @@ -56,7 +52,7 @@ public final class TestAttachments { * Check some basic bits about the attachments */ @Test - public void testBasicAttachments() throws Exception { + public void testBasicAttachments() { List attachments = quick.getAttachments(); // Word first @@ -90,26 +86,22 @@ public final class TestAttachments { * the right values for key things */ @Test - public void testAttachmentDetails() throws Exception { + public void testAttachmentDetails() { List attachments = quick.getAttachments(); + assertEquals(5, attachments.size()); // Pick a predictable date format + timezone DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss", Locale.UK); fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); - // They should all have the same date on them - assertEquals("28-Apr-2010 12:40:56", fmt.format(attachments.get(0).getModifiedDate())); - assertEquals("28-Apr-2010 12:40:56", fmt.format(attachments.get(1).getModifiedDate())); - assertEquals("28-Apr-2010 12:40:56", fmt.format(attachments.get(2).getModifiedDate())); - assertEquals("28-Apr-2010 12:40:56", fmt.format(attachments.get(3).getModifiedDate())); - assertEquals("28-Apr-2010 12:40:56", fmt.format(attachments.get(4).getModifiedDate())); - - // They should all have a 3512 byte metafile rendered version - assertEquals(3512, attachments.get(0).getRenderedMetaFile().length); - assertEquals(3512, attachments.get(1).getRenderedMetaFile().length); - assertEquals(3512, attachments.get(2).getRenderedMetaFile().length); - assertEquals(3512, attachments.get(3).getRenderedMetaFile().length); - assertEquals(3512, attachments.get(4).getRenderedMetaFile().length); + for (Attachment attachment : attachments) { + // They should all have the same date on them + assertEquals("28-Apr-2010 12:40:56", fmt.format(attachment.getModifiedDate())); + // They should all have a 3512 byte metafile rendered version + byte[] meta = attachment.getRenderedMetaFile(); + assertNotNull(meta); + assertEquals(3512, meta.length); + } } /** diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/TestBugs.java b/src/scratchpad/testcases/org/apache/poi/hmef/TestBugs.java index 27d69f69f0..24f3259380 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/TestBugs.java @@ -16,40 +16,41 @@ ==================================================================== */ package org.apache.poi.hmef; +import static org.apache.poi.hmef.TestHMEFMessage.openSample; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import org.apache.poi.POIDataSamples; +import java.io.IOException; +import java.util.List; + import org.apache.poi.hmef.attribute.MAPIAttribute; import org.apache.poi.hmef.attribute.TNEFAttribute; import org.apache.poi.hmef.attribute.TNEFProperty; import org.apache.poi.hsmf.datatypes.MAPIProperty; import org.apache.poi.util.LittleEndian; - import org.junit.Test; public class TestBugs { @Test - public void test52400ReadSimpleTNEF() throws Exception { - POIDataSamples samples = POIDataSamples.getHMEFInstance(); - String testFile = "bug52400-winmail-simple.dat"; - HMEFMessage tnefDat = new HMEFMessage(samples.openResourceAsStream(testFile)); + public void test52400ReadSimpleTNEF() throws IOException { + HMEFMessage tnefDat = openSample("bug52400-winmail-simple.dat"); MAPIAttribute bodyHtml = tnefDat.getMessageMAPIAttribute(MAPIProperty.BODY_HTML); + assertNotNull(bodyHtml); String bodyStr = new String(bodyHtml.getData(), getEncoding(tnefDat)); assertTrue(bodyStr.contains("This is the message body.")); } - + @Test - public void test52400ReadAttachedTNEF() throws Exception { - POIDataSamples samples = POIDataSamples.getHMEFInstance(); - String testFile = "bug52400-winmail-with-attachments.dat"; - HMEFMessage tnefDat = new HMEFMessage(samples.openResourceAsStream(testFile)); + public void test52400ReadAttachedTNEF() throws IOException { + HMEFMessage tnefDat = openSample("bug52400-winmail-with-attachments.dat"); MAPIAttribute bodyHtml = tnefDat.getMessageMAPIAttribute(MAPIProperty.BODY_HTML); + assertNotNull(bodyHtml); String bodyStr = new String(bodyHtml.getData(), getEncoding(tnefDat)); assertTrue(bodyStr.contains("There are also two attachments.")); assertEquals(2, tnefDat.getAttachments().size()); } - + private String getEncoding(HMEFMessage tnefDat) { TNEFAttribute oemCP = tnefDat.getMessageAttribute(TNEFProperty.ID_OEMCODEPAGE); MAPIAttribute cpId = tnefDat.getMessageMAPIAttribute(MAPIProperty.INTERNET_CPID); @@ -66,4 +67,15 @@ public class TestBugs { default: return "cp"+codePage; } } + + @Test + public void bug63955() throws IOException { + HMEFMessage tnefDat = openSample("bug63955-winmail.dat"); + List atts = tnefDat.getMessageMAPIAttributes(); + assertEquals(96, atts.size()); + MAPIAttribute bodyHtml = tnefDat.getMessageMAPIAttribute(MAPIProperty.BODY_HTML); + assertNotNull(bodyHtml); + String bodyStr = new String(bodyHtml.getData(), getEncoding(tnefDat)); + assertEquals(1697, bodyStr.length()); + } } diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/TestCompressedRTF.java b/src/scratchpad/testcases/org/apache/poi/hmef/TestCompressedRTF.java index 8c4edf564c..04fa813732 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/TestCompressedRTF.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/TestCompressedRTF.java @@ -17,6 +17,7 @@ package org.apache.poi.hmef; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -24,6 +25,7 @@ import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import org.apache.poi.POIDataSamples; import org.apache.poi.hmef.attribute.MAPIAttribute; @@ -69,32 +71,36 @@ public final class TestCompressedRTF { // Now Look at the code - assertEquals((byte) 0x07, data[16 + 0]); // Flag: cccUUUUU - assertEquals((byte) 0x00, data[16 + 1]); // c1a: offset 0 / 0x000 - assertEquals((byte) 0x06, data[16 + 2]); // c1b: length 6+2 -> {\rtf1\a - assertEquals((byte) 0x01, data[16 + 3]); // c2a: offset 16 / 0x010 - assertEquals((byte) 0x01, data[16 + 4]); // c2b: length 1+2 -> def - assertEquals((byte) 0x0b, data[16 + 5]); // c3a: offset 182 / 0xb6 - assertEquals((byte) 0x60, data[16 + 6]); // c3b: length 0+2 -> la - assertEquals((byte) 0x6e, data[16 + 7]); // n - assertEquals((byte) 0x67, data[16 + 8]); // g - assertEquals((byte) 0x31, data[16 + 9]); // 1 - assertEquals((byte) 0x30, data[16 + 10]); // 0 - assertEquals((byte) 0x32, data[16 + 11]); // 2 - - assertEquals((byte) 0x66, data[16 + 12]); // Flag: UccUUccU - assertEquals((byte) 0x35, data[16 + 13]); // 5 - assertEquals((byte) 0x00, data[16 + 14]); // c2a: offset 6 / 0x006 - assertEquals((byte) 0x64, data[16 + 15]); // c2b: length 4+2 -> \ansi\a - assertEquals((byte) 0x00, data[16 + 16]); // c3a: offset 7 / 0x007 - assertEquals((byte) 0x72, data[16 + 17]); // c3b: length 2+2 -> nsi - assertEquals((byte) 0x63, data[16 + 18]); // c - assertEquals((byte) 0x70, data[16 + 19]); // p - assertEquals((byte) 0x0d, data[16 + 20]); // c6a: offset 221 / 0x0dd - assertEquals((byte) 0xd0, data[16 + 21]); // c6b: length 0+2 -> g1 - assertEquals((byte) 0x0e, data[16 + 22]); // c7a: offset 224 / 0x0e0 - assertEquals((byte) 0x00, data[16 + 23]); // c7b: length 0+2 -> 25 - assertEquals((byte) 0x32, data[16 + 24]); // 2 + byte[] exp = { + (byte) 0x07, // Flag: cccUUUUU + (byte) 0x00, // c1a: offset 0 / 0x000 + (byte) 0x06, // c1b: length 6+2 -> {\rtf1\a + (byte) 0x01, // c2a: offset 16 / 0x010 + (byte) 0x01, // c2b: length 1+2 -> def + (byte) 0x0b, // c3a: offset 182 / 0xb6 + (byte) 0x60, // c3b: length 0+2 -> la + (byte) 0x6e, // n + (byte) 0x67, // g + (byte) 0x31, // 1 + (byte) 0x30, // 0 + (byte) 0x32, // 2 + + (byte) 0x66, // Flag: UccUUccU + (byte) 0x35, // 5 + (byte) 0x00, // c2a: offset 6 / 0x006 + (byte) 0x64, // c2b: length 4+2 -> \ansi\a + (byte) 0x00, // c3a: offset 7 / 0x007 + (byte) 0x72, // c3b: length 2+2 -> nsi + (byte) 0x63, // c + (byte) 0x70, // p + (byte) 0x0d, // c6a: offset 221 / 0x0dd + (byte) 0xd0, // c6b: length 0+2 -> g1 + (byte) 0x0e, // c7a: offset 224 / 0x0e0 + (byte) 0x00, // c7b: length 0+2 -> 25 + (byte) 0x32, // 2 + }; + + assertArrayEquals(exp, Arrays.copyOfRange(data, 16, 16+25)); } /** @@ -119,7 +125,7 @@ public final class TestCompressedRTF { // Decompress it CompressedRTF comp = new CompressedRTF(); byte[] decomp = comp.decompress(new ByteArrayInputStream(data)); - String decompStr = new String(decomp, StandardCharsets.US_ASCII); + String decompStr = new String(decomp, StandardCharsets.US_ASCII); // Test assertEquals(block1.length(), decomp.length); @@ -142,16 +148,14 @@ public final class TestCompressedRTF { MAPIRtfAttribute rtfAttr = (MAPIRtfAttribute) attr; // Truncate to header + flag + data for flag + flag + data - byte[] data = new byte[16 + 12 + 13]; - System.arraycopy(rtfAttr.getRawData(), 0, data, 0, data.length); + byte[] data = Arrays.copyOf(rtfAttr.getRawData(), 16 + 12 + 13); // Decompress it CompressedRTF comp = new CompressedRTF(); byte[] decomp = comp.decompress(new ByteArrayInputStream(data)); - String decompStr = new String(decomp, StandardCharsets.US_ASCII); + String decompStr = new String(decomp, StandardCharsets.US_ASCII); // Test - assertEquals(block2.length(), decomp.length); assertEquals(block2, decompStr); } @@ -185,20 +189,13 @@ public final class TestCompressedRTF { // Will have been padded though assertEquals(expected.length + 2, decomp.length); - byte[] tmp = new byte[expected.length]; - System.arraycopy(decomp, 0, tmp, 0, tmp.length); - decomp = tmp; // By byte - assertEquals(expected.length, decomp.length); - for (int i = 0; i < expected.length; i++) { - assertEquals(expected[i], decomp[i]); - } + assertArrayEquals(expected, Arrays.copyOf(decomp, expected.length)); // By String String expString = new String(expected, StandardCharsets.US_ASCII); String decompStr = rtfAttr.getDataString(); - assertEquals(expString.length(), decompStr.length()); assertEquals(expString, decompStr); } } diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java b/src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java index 903742c6c8..91ee3a38a3 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java @@ -17,11 +17,11 @@ package org.apache.poi.hmef; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -33,30 +33,25 @@ import org.apache.poi.POIDataSamples; import org.apache.poi.hmef.attribute.MAPIAttribute; import org.apache.poi.hmef.attribute.MAPIRtfAttribute; import org.apache.poi.hmef.attribute.MAPIStringAttribute; +import org.apache.poi.hmef.attribute.TNEFAttribute; import org.apache.poi.hmef.attribute.TNEFProperty; import org.apache.poi.hsmf.datatypes.MAPIProperty; import org.apache.poi.hsmf.datatypes.Types; import org.apache.poi.util.IOUtils; import org.apache.poi.util.LittleEndian; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public final class TestHMEFMessage { - protected static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); + private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); - @Test - public void testOpen() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - assertNotNull(msg); - } + @Rule + public ExpectedException thrown = ExpectedException.none(); @Test public void testCounts() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); + HMEFMessage msg = openSample("quick-winmail.dat"); // Should have 4 attributes on the message assertEquals(4, msg.getMessageAttributes().size()); @@ -82,9 +77,7 @@ public final class TestHMEFMessage { @Test public void testBasicMessageAttributes() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); + HMEFMessage msg = openSample("quick-winmail.dat"); // Should have version, codepage, class and MAPI assertEquals(4, msg.getMessageAttributes().size()); @@ -104,21 +97,18 @@ public final class TestHMEFMessage { assertNull(msg.getMessageAttribute(TNEFProperty.ID_ATTACHDATA)); // Now check the details of one or two - assertEquals( - 0x010000, - LittleEndian.getInt(msg.getMessageAttribute(TNEFProperty.ID_TNEFVERSION).getData()) - ); - assertEquals( - "IPM.Microsoft Mail.Note\0", - new String(msg.getMessageAttribute(TNEFProperty.ID_MESSAGECLASS).getData(), StandardCharsets.US_ASCII) - ); + TNEFAttribute version = msg.getMessageAttribute(TNEFProperty.ID_TNEFVERSION); + assertNotNull(version); + assertEquals(0x010000, LittleEndian.getInt(version.getData())); + + TNEFAttribute msgCls = msg.getMessageAttribute(TNEFProperty.ID_MESSAGECLASS); + assertNotNull(msgCls); + assertEquals("IPM.Microsoft Mail.Note\0", new String(msgCls.getData(), StandardCharsets.US_ASCII)); } @Test public void testBasicMessageMAPIAttributes() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); + HMEFMessage msg = openSample("quick-winmail.dat"); assertEquals("This is a test message", msg.getSubject()); assertEquals("{\\rtf1", msg.getBody().substring(0, 6)); @@ -130,19 +120,18 @@ public final class TestHMEFMessage { */ @Test public void testMessageContents() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); + HMEFMessage msg = openSample("quick-winmail.dat"); // Firstly by byte MAPIRtfAttribute rtf = (MAPIRtfAttribute) msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); + assertNotNull(rtf); assertContents("message.rtf", rtf.getData()); // Then by String String contents = msg.getBody(); // It's all low bytes - byte[] contentsBytes = contents.getBytes(StandardCharsets.US_ASCII); + byte[] contentsBytes = contents.getBytes(StandardCharsets.US_ASCII); assertContents("message.rtf", contentsBytes); // try to get a message id that does not exist @@ -151,8 +140,7 @@ public final class TestHMEFMessage { @Test public void testMessageSample1() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("winmail-sample1.dat")); + HMEFMessage msg = openSample("winmail-sample1.dat"); // Firstly by byte MAPIRtfAttribute rtf = (MAPIRtfAttribute) msg @@ -164,7 +152,7 @@ public final class TestHMEFMessage { String contents = msg.getBody(); //System.out.println(contents); // It's all low bytes - byte[] contentsBytes = contents.getBytes(StandardCharsets.US_ASCII); + byte[] contentsBytes = contents.getBytes(StandardCharsets.US_ASCII); // assertContents("message.rtf", contentsBytes); assertNotNull(contentsBytes); @@ -174,13 +162,11 @@ public final class TestHMEFMessage { @Test public void testInvalidMessage() throws Exception { - InputStream str = new ByteArrayInputStream(new byte[]{0, 0, 0, 0}); - try { - assertNotNull(new HMEFMessage(str)); - fail("Should catch an exception here"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("TNEF signature not detected in file, expected 574529400 but got 0")); - } + InputStream str = new ByteArrayInputStream(new byte[4]); + + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("TNEF signature not detected in file, expected 574529400 but got 0"); + new HMEFMessage(str); } @Test @@ -213,21 +199,16 @@ public final class TestHMEFMessage { // invalid level LittleEndian.putUShort(90, out); - byte[] bytes = out.toByteArray(); - InputStream str = new ByteArrayInputStream(bytes); - try { - assertNotNull(new HMEFMessage(str)); - fail("Should catch an exception here"); - } catch (IllegalStateException e) { - assertTrue(e.getMessage().contains("Unhandled level 90")); - } + InputStream str = new ByteArrayInputStream(out.toByteArray()); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Unhandled level 90"); + new HMEFMessage(str); } @Test - public void testCustomProperty() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); + public void testCustomProperty() throws IOException { + HMEFMessage msg = openSample("quick-winmail.dat"); // Should have non-standard properties with IDs 0xE28 and 0xE29 boolean hasE28 = false; @@ -236,8 +217,8 @@ public final class TestHMEFMessage { if (attr.getProperty().id == 0xe28) hasE28 = true; if (attr.getProperty().id == 0xe29) hasE29 = true; } - assertTrue(hasE28); - assertTrue(hasE29); + assertTrue(hasE28); + assertTrue(hasE29); // Ensure we can fetch those as custom ones MAPIProperty propE28 = MAPIProperty.createCustom(0xe28, Types.ASCII_STRING, "Custom E28"); @@ -245,22 +226,22 @@ public final class TestHMEFMessage { assertNotNull(msg.getMessageMAPIAttribute(propE28)); assertNotNull(msg.getMessageMAPIAttribute(propE29)); - assertEquals(MAPIStringAttribute.class, msg.getMessageMAPIAttribute(propE28).getClass()); - assertEquals( - "Zimbra - Mark Rogers", - ((MAPIStringAttribute) msg.getMessageMAPIAttribute(propE28)).getDataString().substring(10) - ); + MAPIStringAttribute propE28b = (MAPIStringAttribute)msg.getMessageMAPIAttribute(propE28); + assertNotNull(propE28b); + assertEquals(MAPIStringAttribute.class, propE28b.getClass()); + assertEquals("Zimbra - Mark Rogers", propE28b.getDataString().substring(10)); } - static void assertContents(String filename, byte[] actual) - throws IOException { + static HMEFMessage openSample(String filename) throws IOException { + try (InputStream is = _samples.openResourceAsStream(filename)) { + return new HMEFMessage(is); + } + } + + static void assertContents(String filename, byte[] actual) throws IOException { try (InputStream stream = _samples.openResourceAsStream("quick-contents/" + filename)) { byte[] expected = IOUtils.toByteArray(stream); - - assertEquals(expected.length, actual.length); - for (int i = 0; i < expected.length; i++) { - assertEquals("Byte " + i + " wrong", expected[i], actual[i]); - } + assertArrayEquals(expected, actual); } } diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java index 675a455cc6..be76876743 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java @@ -31,27 +31,20 @@ import org.apache.poi.hmef.HMEFMessage; import org.apache.poi.hsmf.datatypes.MAPIProperty; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LocaleUtil; -import org.junit.After; import org.junit.Before; import org.junit.Test; public final class TestMAPIAttributes { private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); private HMEFMessage quick; - private InputStream stream; @Before public void setUp() throws Exception { - stream = _samples.openResourceAsStream("quick-winmail.dat"); - quick = new HMEFMessage(stream); - } - - @After - public void tearDown() throws Exception { - stream.close(); + try (InputStream stream = _samples.openResourceAsStream("quick-winmail.dat")) { + quick = new HMEFMessage(stream); + } } - /** * Test counts */ diff --git a/test-data/hmef/bug63955-winmail.dat b/test-data/hmef/bug63955-winmail.dat new file mode 100644 index 0000000000..5693c53222 Binary files /dev/null and b/test-data/hmef/bug63955-winmail.dat differ