From: Andreas Beeker Date: Sun, 1 Dec 2019 21:06:54 +0000 (+0000) Subject: #63955 - HMEFContentsExtractor fails to extract content from winmail.dat X-Git-Tag: REL_4_1_2~110 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=2eee47406368fdcb016922aa0e6971b14926648f;p=poi.git #63955 - HMEFContentsExtractor fails to extract content from winmail.dat git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1870692 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java index f92c97c220..4c92da4f0f 100644 --- a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java +++ b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java @@ -26,8 +26,8 @@ import java.util.Map; * http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefpropertytype%28v=EXCHG.140%29.aspx */ public final class Types { - private static Map builtInTypes = new HashMap<>(); - private static Map customTypes = new HashMap<>(); + private static final Map builtInTypes = new HashMap<>(); + private static final Map customTypes = new HashMap<>(); /** Unspecified */ public static final MAPIType UNSPECIFIED = new MAPIType(0x0000, @@ -119,7 +119,7 @@ public final class Types { * Is this type a fixed-length type, or a variable-length one? */ public boolean isFixedLength() { - return (length != -1) && (length <= 8); + return ((length != -1) && (length <= 8)) || (id == Types.CLS_ID.id); } public int getId() { @@ -132,8 +132,7 @@ public final class Types { @Override public String toString() { - return id + " / 0x" + asFileEnding() + " - " + name + " @ " - + length; + return id + " / 0x" + asFileEnding() + " - " + name + " @ " + length; } /** diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/HMEFTest.java b/src/scratchpad/testcases/org/apache/poi/hmef/HMEFTest.java deleted file mode 100644 index a43bc3010e..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hmef/HMEFTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hmef; - -import java.io.IOException; -import java.io.InputStream; - -import junit.framework.TestCase; - -import org.apache.poi.POIDataSamples; -import org.apache.poi.util.IOUtils; - -public abstract class HMEFTest extends TestCase { - protected static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); - - protected void assertContents(String filename, Attachment attachment) - throws IOException { - assertEquals(filename, attachment.getLongFilename()); - assertContents(filename, attachment.getContents()); - } - - protected 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]); - } - } - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java b/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java index 87655cb3ae..1220c23f32 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java @@ -17,101 +17,117 @@ package org.apache.poi.hmef; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; import java.text.DateFormat; 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.Test; + +public final class TestAttachments { + protected static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); + + + private HMEFMessage quick; + + @Before + public void setUp() throws Exception { + quick = new HMEFMessage( + _samples.openResourceAsStream("quick-winmail.dat") + ); + } + + /** + * Check the file is as we expect + */ + @Test + public void testCounts() throws Exception { + // Should have 5 attachments + assertEquals(5, quick.getAttachments().size()); + } + + /** + * Check some basic bits about the attachments + */ + @Test + public void testBasicAttachments() throws Exception { + List attachments = quick.getAttachments(); + + // Word first + assertEquals("quick.doc", attachments.get(0).getFilename()); + assertEquals("quick.doc", attachments.get(0).getLongFilename()); + assertEquals(".doc", attachments.get(0).getExtension()); + + // Then HTML + assertEquals("QUICK~1.HTM", attachments.get(1).getFilename()); + assertEquals("quick.html", attachments.get(1).getLongFilename()); + assertEquals(".html", attachments.get(1).getExtension()); + + // Then PDF + assertEquals("quick.pdf", attachments.get(2).getFilename()); + assertEquals("quick.pdf", attachments.get(2).getLongFilename()); + assertEquals(".pdf", attachments.get(2).getExtension()); + + // Then Text + assertEquals("quick.txt", attachments.get(3).getFilename()); + assertEquals("quick.txt", attachments.get(3).getLongFilename()); + assertEquals(".txt", attachments.get(3).getExtension()); + + // And finally XML + assertEquals("quick.xml", attachments.get(4).getFilename()); + assertEquals("quick.xml", attachments.get(4).getLongFilename()); + assertEquals(".xml", attachments.get(4).getExtension()); + } + + /** + * Query the attachments in detail, and check we see + * the right values for key things + */ + @Test + public void testAttachmentDetails() throws Exception { + List attachments = quick.getAttachments(); + + // 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); + } + + /** + * Ensure the attachment contents come back as they should do + */ + @Test + public void testAttachmentContents() throws Exception { + List attachments = quick.getAttachments(); + + assertContents("quick.doc", attachments.get(0)); + assertContents("quick.html", attachments.get(1)); + assertContents("quick.pdf", attachments.get(2)); + assertContents("quick.txt", attachments.get(3)); + assertContents("quick.xml", attachments.get(4)); + } -public final class TestAttachments extends HMEFTest { - private HMEFMessage quick; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - quick = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - } - - /** - * Check the file is as we expect - */ - public void testCounts() throws Exception { - // Should have 5 attachments - assertEquals(5, quick.getAttachments().size()); - } - - /** - * Check some basic bits about the attachments - */ - public void testBasicAttachments() throws Exception { - List attachments = quick.getAttachments(); - - // Word first - assertEquals("quick.doc", attachments.get(0).getFilename()); - assertEquals("quick.doc", attachments.get(0).getLongFilename()); - assertEquals(".doc", attachments.get(0).getExtension()); - - // Then HTML - assertEquals("QUICK~1.HTM", attachments.get(1).getFilename()); - assertEquals("quick.html", attachments.get(1).getLongFilename()); - assertEquals(".html", attachments.get(1).getExtension()); - - // Then PDF - assertEquals("quick.pdf", attachments.get(2).getFilename()); - assertEquals("quick.pdf", attachments.get(2).getLongFilename()); - assertEquals(".pdf", attachments.get(2).getExtension()); - - // Then Text - assertEquals("quick.txt", attachments.get(3).getFilename()); - assertEquals("quick.txt", attachments.get(3).getLongFilename()); - assertEquals(".txt", attachments.get(3).getExtension()); - - // And finally XML - assertEquals("quick.xml", attachments.get(4).getFilename()); - assertEquals("quick.xml", attachments.get(4).getLongFilename()); - assertEquals(".xml", attachments.get(4).getExtension()); - } - - /** - * Query the attachments in detail, and check we see - * the right values for key things - */ - public void testAttachmentDetails() throws Exception { - List attachments = quick.getAttachments(); - - // 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); - } - - /** - * Ensure the attachment contents come back as they should do - */ - public void testAttachmentContents() throws Exception { - List attachments = quick.getAttachments(); - - assertContents("quick.doc", attachments.get(0)); - assertContents("quick.html", attachments.get(1)); - assertContents("quick.pdf", attachments.get(2)); - assertContents("quick.txt", attachments.get(3)); - assertContents("quick.xml", attachments.get(4)); - } + static void assertContents(String filename, Attachment attachment) throws IOException { + assertEquals(filename, attachment.getLongFilename()); + TestHMEFMessage.assertContents(filename, attachment.getContents()); + } } diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/TestCompressedRTF.java b/src/scratchpad/testcases/org/apache/poi/hmef/TestCompressedRTF.java index c010a6bf28..d8781c22c1 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/TestCompressedRTF.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/TestCompressedRTF.java @@ -17,11 +17,13 @@ package org.apache.poi.hmef; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.io.ByteArrayInputStream; import java.io.InputStream; -import junit.framework.TestCase; - import org.apache.poi.POIDataSamples; import org.apache.poi.hmef.attribute.MAPIAttribute; import org.apache.poi.hmef.attribute.MAPIRtfAttribute; @@ -29,166 +31,173 @@ import org.apache.poi.hsmf.datatypes.MAPIProperty; import org.apache.poi.util.IOUtils; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.StringUtil; +import org.junit.Test; -public final class TestCompressedRTF extends TestCase { +public final class TestCompressedRTF { private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); private static final String block1 = "{\\rtf1\\adeflang102"; private static final String block2 = block1 + "5\\ansi\\ansicpg1252"; - + /** * Check that things are as we expected. If this fails, - * then decoding has no hope... + * then decoding has no hope... */ + @Test public void testQuickBasics() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - MAPIAttribute rtfAttr = msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); - assertNotNull(rtfAttr); - assertTrue(rtfAttr instanceof MAPIRtfAttribute); - - // Check the start of the compressed version - byte[] data = ((MAPIRtfAttribute)rtfAttr).getRawData(); - assertEquals(5907, data.length); - - // First 16 bytes is header stuff - // Check it has the length + compressed marker - assertEquals(5907-4, LittleEndian.getShort(data)); - assertEquals( - "LZFu", - StringUtil.getFromCompressedUnicode(data, 8, 4) - ); - - - // 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 + HMEFMessage msg; + try (InputStream is = _samples.openResourceAsStream("quick-winmail.dat")) { + msg = new HMEFMessage(is); + } + + MAPIAttribute rtfAttr = msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); + assertNotNull(rtfAttr); + assertTrue(rtfAttr instanceof MAPIRtfAttribute); + + // Check the start of the compressed version + byte[] data = ((MAPIRtfAttribute) rtfAttr).getRawData(); + assertEquals(5907, data.length); + + // First 16 bytes is header stuff + // Check it has the length + compressed marker + assertEquals(5907 - 4, LittleEndian.getShort(data)); + assertEquals( + "LZFu", + StringUtil.getFromCompressedUnicode(data, 8, 4) + ); + + + // 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 } /** * Check that we can decode the first 8 codes - * (1 flag byte + 8 codes) + * (1 flag byte + 8 codes) */ + @Test public void testFirstBlock() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - MAPIAttribute attr = msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); - assertNotNull(attr); - MAPIRtfAttribute rtfAttr = (MAPIRtfAttribute)attr; - - // Truncate to header + flag + data for flag - byte[] data = new byte[16+12]; - System.arraycopy(rtfAttr.getRawData(), 0, data, 0, data.length); - - // Decompress it - CompressedRTF comp = new CompressedRTF(); - byte[] decomp = comp.decompress(new ByteArrayInputStream(data)); - String decompStr = new String(decomp, "ASCII"); - - // Test - assertEquals(block1.length(), decomp.length); - assertEquals(block1, decompStr); + HMEFMessage msg; + try (InputStream is = _samples.openResourceAsStream("quick-winmail.dat")) { + msg = new HMEFMessage(is); + } + + MAPIAttribute attr = msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); + assertNotNull(attr); + MAPIRtfAttribute rtfAttr = (MAPIRtfAttribute) attr; + + // Truncate to header + flag + data for flag + byte[] data = new byte[16 + 12]; + System.arraycopy(rtfAttr.getRawData(), 0, data, 0, data.length); + + // Decompress it + CompressedRTF comp = new CompressedRTF(); + byte[] decomp = comp.decompress(new ByteArrayInputStream(data)); + String decompStr = new String(decomp, "ASCII"); + + // Test + assertEquals(block1.length(), decomp.length); + assertEquals(block1, decompStr); } /** * Check that we can decode the first 16 codes - * (flag + 8 codes, flag + 8 codes) + * (flag + 8 codes, flag + 8 codes) */ + @Test public void testFirstTwoBlocks() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - MAPIAttribute attr = msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); - assertNotNull(attr); - 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); - - // Decompress it - CompressedRTF comp = new CompressedRTF(); - byte[] decomp = comp.decompress(new ByteArrayInputStream(data)); - String decompStr = new String(decomp, "ASCII"); - - // Test - assertEquals(block2.length(), decomp.length); - assertEquals(block2, decompStr); + HMEFMessage msg; + try (InputStream is = _samples.openResourceAsStream("quick-winmail.dat")) { + msg = new HMEFMessage(is); + } + + MAPIAttribute attr = msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); + assertNotNull(attr); + 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); + + // Decompress it + CompressedRTF comp = new CompressedRTF(); + byte[] decomp = comp.decompress(new ByteArrayInputStream(data)); + String decompStr = new String(decomp, "ASCII"); + + // Test + assertEquals(block2.length(), decomp.length); + assertEquals(block2, decompStr); } /** * Check that we can correctly decode the whole file * TODO Fix what looks like a padding issue */ + @Test public void testFull() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - MAPIAttribute attr = msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); - assertNotNull(attr); - MAPIRtfAttribute rtfAttr = (MAPIRtfAttribute)attr; - - InputStream stream = _samples.openResourceAsStream("quick-contents/message.rtf"); - try { - byte[] expected = IOUtils.toByteArray(stream); - - CompressedRTF comp = new CompressedRTF(); - byte[] data = rtfAttr.getRawData(); - byte[] decomp = comp.decompress(new ByteArrayInputStream(data)); - - // Check the length was as expected - assertEquals(data.length, comp.getCompressedSize() + 16); - assertEquals(expected.length, comp.getDeCompressedSize()); - - // 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= 20); + assertTrue("Should be 20-25 mapi attributes, found " + mapiAttrCount, mapiAttrCount <= 25); + } + } + + @Test + public void testBasicMessageAttributes() throws Exception { + HMEFMessage msg = new HMEFMessage( + _samples.openResourceAsStream("quick-winmail.dat") + ); + + // Should have version, codepage, class and MAPI + assertEquals(4, msg.getMessageAttributes().size()); + assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_TNEFVERSION)); + assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_OEMCODEPAGE)); + assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_MESSAGECLASS)); + assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_MAPIPROPERTIES)); + + // Check the order + assertEquals(TNEFProperty.ID_TNEFVERSION, msg.getMessageAttributes().get(0).getProperty()); + assertEquals(TNEFProperty.ID_OEMCODEPAGE, msg.getMessageAttributes().get(1).getProperty()); + assertEquals(TNEFProperty.ID_MESSAGECLASS, msg.getMessageAttributes().get(2).getProperty()); + assertEquals(TNEFProperty.ID_MAPIPROPERTIES, msg.getMessageAttributes().get(3).getProperty()); + + // Check some that aren't there + assertNull(msg.getMessageAttribute(TNEFProperty.ID_AIDOWNER)); + 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(), "ASCII") + ); + } + + @Test + public void testBasicMessageMAPIAttributes() throws Exception { + HMEFMessage msg = new HMEFMessage( + _samples.openResourceAsStream("quick-winmail.dat") + ); + + assertEquals("This is a test message", msg.getSubject()); + assertEquals("{\\rtf1", msg.getBody().substring(0, 6)); + } + + /** + * Checks that the compressed RTF message contents + * can be correctly extracted + */ + @Test + public void testMessageContents() throws Exception { + HMEFMessage msg = new HMEFMessage( _samples.openResourceAsStream("quick-winmail.dat") - ); - - assertNotNull(msg); - } - - public void testCounts() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - // Should have 4 attributes on the message - assertEquals(4, msg.getMessageAttributes().size()); - - // And should have 54 MAPI attributes on it - assertEquals(54, msg.getMessageMAPIAttributes().size()); - - - // Should have 5 attachments - assertEquals(5, msg.getAttachments().size()); - - // Each attachment should have 6 normal attributes, and - // 20 or so MAPI ones - for(Attachment attach : msg.getAttachments()) { - int attrCount = attach.getAttributes().size(); - int mapiAttrCount = attach.getMAPIAttributes().size(); - - assertEquals(6, attrCount); - assertTrue("Should be 20-25 mapi attributes, found " + mapiAttrCount, mapiAttrCount >= 20); - assertTrue("Should be 20-25 mapi attributes, found " + mapiAttrCount, mapiAttrCount <= 25); - } - } - - public void testBasicMessageAttributes() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - // Should have version, codepage, class and MAPI - assertEquals(4, msg.getMessageAttributes().size()); - assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_TNEFVERSION)); - assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_OEMCODEPAGE)); - assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_MESSAGECLASS)); - assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_MAPIPROPERTIES)); - - // Check the order - assertEquals(TNEFProperty.ID_TNEFVERSION, msg.getMessageAttributes().get(0).getProperty()); - assertEquals(TNEFProperty.ID_OEMCODEPAGE, msg.getMessageAttributes().get(1).getProperty()); - assertEquals(TNEFProperty.ID_MESSAGECLASS, msg.getMessageAttributes().get(2).getProperty()); - assertEquals(TNEFProperty.ID_MAPIPROPERTIES, msg.getMessageAttributes().get(3).getProperty()); - - // Check some that aren't there - assertNull(msg.getMessageAttribute(TNEFProperty.ID_AIDOWNER)); - 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(), "ASCII") - ); - } - - public void testBasicMessageMAPIAttributes() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - assertEquals("This is a test message", msg.getSubject()); - assertEquals("{\\rtf1", msg.getBody().substring(0, 6)); - } - - /** - * Checks that the compressed RTF message contents - * can be correctly extracted - */ - public void testMessageContents() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - // Firstly by byte - MAPIRtfAttribute rtf = (MAPIRtfAttribute) - msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); - assertContents("message.rtf", rtf.getData()); - - // Then by String - String contents = msg.getBody(); - // It's all low bytes - byte[] contentsBytes = contents.getBytes("ASCII"); - assertContents("message.rtf", contentsBytes); - - // try to get a message id that does not exist - assertNull(msg.getMessageMAPIAttribute(MAPIProperty.AB_DEFAULT_DIR)); - } - - public void testMessageSample1() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("winmail-sample1.dat")); - - // Firstly by byte - MAPIRtfAttribute rtf = (MAPIRtfAttribute) msg - .getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); - // assertContents("message.rtf", rtf.getData()); - assertNotNull(rtf); - - // Then by String - String contents = msg.getBody(); - //System.out.println(contents); - // It's all low bytes - byte[] contentsBytes = contents.getBytes("ASCII"); - // assertContents("message.rtf", contentsBytes); - assertNotNull(contentsBytes); - - assertNotNull(msg.getSubject()); - assertNotNull(msg.getBody()); - } - - 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")); - } - } - - - public void testNoData() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - // Header - LittleEndian.putInt(HMEFMessage.HEADER_SIGNATURE, out); - - // field - LittleEndian.putUShort(0, out); - - byte[] bytes = out.toByteArray(); - InputStream str = new ByteArrayInputStream(bytes); - HMEFMessage msg = new HMEFMessage(str); - assertNull(msg.getSubject()); - assertNull(msg.getBody()); - } - - public void testInvalidLevel() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - // Header - LittleEndian.putInt(HMEFMessage.HEADER_SIGNATURE, out); - - // field - LittleEndian.putUShort(0, out); - - // 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")); - } - } - - public void testCustomProperty() throws Exception { - HMEFMessage msg = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - - // Should have non-standard properties with IDs 0xE28 and 0xE29 - boolean hasE28 = false; - boolean hasE29 = false; - for (MAPIAttribute attr : msg.getMessageMAPIAttributes()) { - if (attr.getProperty().id == 0xe28) hasE28 = true; - if (attr.getProperty().id == 0xe29) hasE29 = true; - } - assertEquals(true, hasE28); - assertEquals(true, hasE29); - - // Ensure we can fetch those as custom ones - MAPIProperty propE28 = MAPIProperty.createCustom(0xe28, Types.ASCII_STRING, "Custom E28"); - MAPIProperty propE29 = MAPIProperty.createCustom(0xe29, Types.ASCII_STRING, "Custom E29"); - 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) - ); - } + ); + + // Firstly by byte + MAPIRtfAttribute rtf = (MAPIRtfAttribute) + msg.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); + assertContents("message.rtf", rtf.getData()); + + // Then by String + String contents = msg.getBody(); + // It's all low bytes + byte[] contentsBytes = contents.getBytes("ASCII"); + assertContents("message.rtf", contentsBytes); + + // try to get a message id that does not exist + assertNull(msg.getMessageMAPIAttribute(MAPIProperty.AB_DEFAULT_DIR)); + } + + @Test + public void testMessageSample1() throws Exception { + HMEFMessage msg = new HMEFMessage( + _samples.openResourceAsStream("winmail-sample1.dat")); + + // Firstly by byte + MAPIRtfAttribute rtf = (MAPIRtfAttribute) msg + .getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); + // assertContents("message.rtf", rtf.getData()); + assertNotNull(rtf); + + // Then by String + String contents = msg.getBody(); + //System.out.println(contents); + // It's all low bytes + byte[] contentsBytes = contents.getBytes("ASCII"); + // assertContents("message.rtf", contentsBytes); + assertNotNull(contentsBytes); + + assertNotNull(msg.getSubject()); + assertNotNull(msg.getBody()); + } + + @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")); + } + } + + @Test + public void testNoData() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + // Header + LittleEndian.putInt(HMEFMessage.HEADER_SIGNATURE, out); + + // field + LittleEndian.putUShort(0, out); + + byte[] bytes = out.toByteArray(); + InputStream str = new ByteArrayInputStream(bytes); + HMEFMessage msg = new HMEFMessage(str); + assertNull(msg.getSubject()); + assertNull(msg.getBody()); + } + + @Test + public void testInvalidLevel() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + // Header + LittleEndian.putInt(HMEFMessage.HEADER_SIGNATURE, out); + + // field + LittleEndian.putUShort(0, out); + + // 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")); + } + } + + @Test + public void testCustomProperty() throws Exception { + HMEFMessage msg = new HMEFMessage( + _samples.openResourceAsStream("quick-winmail.dat") + ); + + // Should have non-standard properties with IDs 0xE28 and 0xE29 + boolean hasE28 = false; + boolean hasE29 = false; + for (MAPIAttribute attr : msg.getMessageMAPIAttributes()) { + if (attr.getProperty().id == 0xe28) hasE28 = true; + if (attr.getProperty().id == 0xe29) hasE29 = true; + } + assertEquals(true, hasE28); + assertEquals(true, hasE29); + + // Ensure we can fetch those as custom ones + MAPIProperty propE28 = MAPIProperty.createCustom(0xe28, Types.ASCII_STRING, "Custom E28"); + MAPIProperty propE29 = MAPIProperty.createCustom(0xe29, Types.ASCII_STRING, "Custom E29"); + 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) + ); + } + + 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]); + } + } + } + } 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 7fcad02042..675a455cc6 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java @@ -17,6 +17,9 @@ package org.apache.poi.hmef.attribute; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import java.io.ByteArrayInputStream; import java.io.InputStream; import java.text.DateFormat; @@ -28,159 +31,159 @@ 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(); + } + + + /** + * Test counts + */ + @Test + public void testCounts() throws Exception { + // Message should have 54 + assertEquals(54, quick.getMessageMAPIAttributes().size()); + + // First attachment should have 22 + assertEquals(22, quick.getAttachments().get(0).getMAPIAttributes().size()); + } + + /** + * Test various general ones + */ + @Test + public void testBasics() throws Exception { + // Try constructing two attributes + byte[] data = new byte[]{ + // Level one, id 36867, type 6 + 0x01, 0x03, (byte) 0x90, 0x06, 0x00, + // Length 24 + 0x24, 0x00, 0x00, 0x00, + + // Three attributes + 0x03, 0x00, 0x00, 0x00, + // AlternateRecipientAllowed = 01 00 + 0x0B, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, + // Priority = 00 00 00 00 + 0x03, 0x00, 0x26, 0x00, + 0x00, 0x00, 0x00, 0x00, + // ConversationTopic = Test + 0x1E, 0x00, 0x70, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, + (byte) 'T', (byte) 'e', + (byte) 's', (byte) 't', + // Checksum (may be wrong...) + 0x01, 0x00 + }; + ByteArrayInputStream bais = new ByteArrayInputStream(data); + + // Create it + int level = bais.read(); + assertEquals(1, level); + TNEFAttribute attr = TNEFAttribute.create(bais); + + // Check it + assertNotNull(attr); + assertEquals(TNEFMAPIAttribute.class, attr.getClass()); + + TNEFMAPIAttribute mapi = (TNEFMAPIAttribute) attr; + assertEquals(3, mapi.getMAPIAttributes().size()); + + assertEquals( + MAPIProperty.ALTERNATE_RECIPIENT_ALLOWED, + mapi.getMAPIAttributes().get(0).getProperty() + ); + assertEquals(1, LittleEndian.getUShort( + mapi.getMAPIAttributes().get(0).getData() + )); + + assertEquals( + MAPIProperty.PRIORITY, + mapi.getMAPIAttributes().get(1).getProperty() + ); + assertEquals(0, LittleEndian.getUShort( + mapi.getMAPIAttributes().get(1).getData() + )); + + assertEquals( + MAPIProperty.CONVERSATION_TOPIC, + mapi.getMAPIAttributes().get(2).getProperty() + ); + assertEquals( + "Test", + ((MAPIStringAttribute) mapi.getMAPIAttributes().get(2)).getDataString() + ); + } + + /** + * Test String, Date and RTF ones + */ + @Test + public void testTyped() throws Exception { + MAPIAttribute attr; + + // String + // ConversationTopic -> This is a test message + attr = quick.getMessageMAPIAttribute(MAPIProperty.CONVERSATION_TOPIC); + assertNotNull(attr); + assertEquals(MAPIStringAttribute.class, attr.getClass()); + + MAPIStringAttribute str = (MAPIStringAttribute) attr; + assertEquals("This is a test message", str.getDataString()); + + // Date + // (Unknown/Custom) 32955 -> Wed Dec 15 2010 @ 14:46:31 UTC + attr = null; + for (MAPIAttribute a : quick.getMessageMAPIAttributes()) { + if (a.getProperty().id == 32955) { + attr = a; + break; + } + } + assertNotNull(attr); + assertEquals(MAPIDateAttribute.class, attr.getClass()); + + MAPIDateAttribute date = (MAPIDateAttribute) attr; + DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.UK); + fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); + assertEquals("15-Dec-2010 14:46:31", fmt.format(date.getDate())); + + // RTF + // RtfCompressed -> {\rtf1... + attr = quick.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); + assertNotNull(attr); + assertEquals(MAPIRtfAttribute.class, attr.getClass()); + + MAPIRtfAttribute rtf = (MAPIRtfAttribute) attr; + assertEquals("{\\rtf1", rtf.getDataString().substring(0, 6)); + } + + /** + * Check common ones via helper accessors + */ + @Test + public void testCommon() throws Exception { + assertEquals("This is a test message", quick.getSubject()); -import junit.framework.TestCase; - -public final class TestMAPIAttributes extends TestCase { - private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); - private HMEFMessage quick; - private InputStream stream; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - stream = _samples.openResourceAsStream("quick-winmail.dat"); - quick = new HMEFMessage(stream); - } - - - @Override -protected void tearDown() throws Exception { - stream.close(); - - super.tearDown(); - } - - -/** - * Test counts - */ - public void testCounts() throws Exception { - // Message should have 54 - assertEquals(54, quick.getMessageMAPIAttributes().size()); - - // First attachment should have 22 - assertEquals(22, quick.getAttachments().get(0).getMAPIAttributes().size()); - } - - /** - * Test various general ones - */ - public void testBasics() throws Exception { - // Try constructing two attributes - byte[] data = new byte[] { - // Level one, id 36867, type 6 - 0x01, 0x03, (byte)0x90, 0x06, 0x00, - // Length 24 - 0x24, 0x00, 0x00, 0x00, - - // Three attributes - 0x03, 0x00, 0x00, 0x00, - // AlternateRecipientAllowed = 01 00 - 0x0B, 0x00, 0x02, 0x00, - 0x01, 0x00, 0x00, 0x00, - // Priority = 00 00 00 00 - 0x03, 0x00, 0x26, 0x00, - 0x00, 0x00, 0x00, 0x00, - // ConversationTopic = Test - 0x1E, 0x00, 0x70, 0x00, - 0x01, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, - (byte)'T', (byte)'e', - (byte)'s', (byte)'t', - // Checksum (may be wrong...) - 0x01, 0x00 - }; - ByteArrayInputStream bais = new ByteArrayInputStream(data); - - // Create it - int level = bais.read(); - assertEquals(1, level); - TNEFAttribute attr = TNEFAttribute.create(bais); - - // Check it - assertNotNull(attr); - assertEquals(TNEFMAPIAttribute.class, attr.getClass()); - - TNEFMAPIAttribute mapi = (TNEFMAPIAttribute)attr; - assertEquals(3, mapi.getMAPIAttributes().size()); - - assertEquals( - MAPIProperty.ALTERNATE_RECIPIENT_ALLOWED, - mapi.getMAPIAttributes().get(0).getProperty() - ); - assertEquals(1, LittleEndian.getUShort( - mapi.getMAPIAttributes().get(0).getData() - )); - - assertEquals( - MAPIProperty.PRIORITY, - mapi.getMAPIAttributes().get(1).getProperty() - ); - assertEquals(0, LittleEndian.getUShort( - mapi.getMAPIAttributes().get(1).getData() - )); - - assertEquals( - MAPIProperty.CONVERSATION_TOPIC, - mapi.getMAPIAttributes().get(2).getProperty() - ); - assertEquals( - "Test", - ((MAPIStringAttribute)mapi.getMAPIAttributes().get(2)).getDataString() - ); - } - - /** - * Test String, Date and RTF ones - */ - public void testTyped() throws Exception { - MAPIAttribute attr; - - // String - // ConversationTopic -> This is a test message - attr = quick.getMessageMAPIAttribute(MAPIProperty.CONVERSATION_TOPIC); - assertNotNull(attr); - assertEquals(MAPIStringAttribute.class, attr.getClass()); - - MAPIStringAttribute str = (MAPIStringAttribute)attr; - assertEquals("This is a test message", str.getDataString()); - - // Date - // (Unknown/Custom) 32955 -> Wed Dec 15 2010 @ 14:46:31 UTC - attr = null; - for(MAPIAttribute a : quick.getMessageMAPIAttributes()) { - if(a.getProperty().id == 32955) { - attr = a; - break; - } - } - assertNotNull(attr); - assertEquals(MAPIDateAttribute.class, attr.getClass()); - - MAPIDateAttribute date = (MAPIDateAttribute)attr; - DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.UK); - fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); - assertEquals("15-Dec-2010 14:46:31", fmt.format(date.getDate())); - - // RTF - // RtfCompressed -> {\rtf1... - attr = quick.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED); - assertNotNull(attr); - assertEquals(MAPIRtfAttribute.class, attr.getClass()); - - MAPIRtfAttribute rtf = (MAPIRtfAttribute)attr; - assertEquals("{\\rtf1", rtf.getDataString().substring(0, 6)); - } - - /** - * Check common ones via helper accessors - */ - public void testCommon() throws Exception { - assertEquals("This is a test message", quick.getSubject()); - - assertEquals("quick.doc", quick.getAttachments().get(0).getLongFilename()); - assertEquals(".doc", quick.getAttachments().get(0).getExtension()); - } + assertEquals("quick.doc", quick.getAttachments().get(0).getLongFilename()); + assertEquals(".doc", quick.getAttachments().get(0).getExtension()); + } } diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java index 04004fae23..4f274aa54e 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java @@ -17,7 +17,11 @@ package org.apache.poi.hmef.attribute; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Locale; @@ -28,182 +32,186 @@ 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.Before; +import org.junit.Test; + +public final class TestTNEFAttributes { + private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); + private HMEFMessage quick; + + @Before + public void setUp() throws Exception { + try (InputStream is = _samples.openResourceAsStream("quick-winmail.dat")) { + quick = new HMEFMessage(is); + } + } + + /** + * Test counts + */ + @Test + public void testCounts() throws Exception { + // The message should have 4 attributes + assertEquals(4, quick.getMessageAttributes().size()); + + // Each attachment should have 6 attributes + for (Attachment attach : quick.getAttachments()) { + assertEquals(6, attach.getAttributes().size()); + } + } + + /** + * Test the basics + */ + @Test + public void testBasics() throws Exception { + // An int one + assertEquals( + 0x010000, + LittleEndian.getInt(quick.getMessageAttribute(TNEFProperty.ID_TNEFVERSION).getData()) + ); + + // Claims not to be text, but really is + assertEquals( + "IPM.Microsoft Mail.Note\0", + new String(quick.getMessageAttribute(TNEFProperty.ID_MESSAGECLASS).getData(), "ASCII") + ); + + // Try constructing two attributes + byte[] data = new byte[]{ + // Level one, id 36870, type 8 + 0x01, 0x06, (byte) 0x90, 0x08, 0x00, + // Length 4 + 0x04, 0x00, 0x00, 0x00, + // Data + 0x00, 0x00, 0x01, 0x00, + // Checksum + 0x01, 0x00, + + // level one, id 36871, type 6 + 0x01, 0x07, (byte) 0x90, 0x06, 0x00, + // Length 8 + 0x08, 0x00, 0x00, 0x00, + // Data + (byte) 0xe4, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + // Checksum + (byte) 0xe8, 0x00 + }; + ByteArrayInputStream bais = new ByteArrayInputStream(data); + + // Create them + int level = bais.read(); + assertEquals(1, level); + TNEFAttribute attr1 = TNEFAttribute.create(bais); + + level = bais.read(); + assertEquals(1, level); + TNEFAttribute attr2 = TNEFAttribute.create(bais); + + assertEquals(-1, bais.read()); + + // Check them + assertEquals(TNEFProperty.ID_TNEFVERSION, attr1.getProperty()); + assertEquals(8, attr1.getType()); + assertEquals(4, attr1.getData().length); + assertEquals(0x010000, LittleEndian.getInt(attr1.getData())); + + assertEquals(TNEFProperty.ID_OEMCODEPAGE, attr2.getProperty()); + assertEquals(6, attr2.getType()); + assertEquals(8, attr2.getData().length); + assertEquals(0x04e4, LittleEndian.getInt(attr2.getData())); + } + + /** + * Test string based ones + */ + @Test + public void testString() throws Exception { + TNEFAttribute attr = quick.getAttachments().get(0).getAttribute( + TNEFProperty.ID_ATTACHTITLE + ); + assertNotNull(attr); + assertEquals(TNEFStringAttribute.class, attr.getClass()); + + // It is a null terminated string + assertEquals("quick.doc\u0000", new String(attr.getData(), "ASCII")); + + // But when we ask for the string, that is sorted for us + TNEFStringAttribute str = (TNEFStringAttribute) attr; + assertEquals("quick.doc", str.getString()); + } + + /** + * Test date based ones + */ + @Test + public void testDate() throws Exception { + TNEFAttribute attr = quick.getAttachments().get(0).getAttribute( + TNEFProperty.ID_ATTACHMODIFYDATE + ); + assertNotNull(attr); + assertEquals(TNEFDateAttribute.class, attr.getClass()); + + // It is a series of date parts + // Weds 28th April 2010 @ 12:40:56 UTC + assertEquals(2010, LittleEndian.getUShort(attr.getData(), 0)); + assertEquals(04, LittleEndian.getUShort(attr.getData(), 2)); + assertEquals(28, LittleEndian.getUShort(attr.getData(), 4)); + assertEquals(12, LittleEndian.getUShort(attr.getData(), 6)); + assertEquals(40, LittleEndian.getUShort(attr.getData(), 8)); + assertEquals(56, LittleEndian.getUShort(attr.getData(), 10)); + assertEquals(3, LittleEndian.getUShort(attr.getData(), 12)); // Weds + + // Ask for it as a Java date, and have it converted + // Pick a predictable format + location + timezone + TNEFDateAttribute date = (TNEFDateAttribute) attr; + DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.UK); + fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); + assertEquals("28-Apr-2010 12:40:56", fmt.format(date.getDate())); + } + + /** + * Test a bit of mapi + */ + @Test + public void testMAPI() throws Exception { + // Message MAPI + TNEFAttribute attr = quick.getMessageAttribute( + TNEFProperty.ID_MAPIPROPERTIES + ); + assertNotNull(attr); + assertEquals(TNEFMAPIAttribute.class, attr.getClass()); + + TNEFMAPIAttribute mapi = (TNEFMAPIAttribute) attr; + assertEquals(54, mapi.getMAPIAttributes().size()); + assertEquals( + MAPIProperty.ALTERNATE_RECIPIENT_ALLOWED, + mapi.getMAPIAttributes().get(0).getProperty() + ); + + + // Attribute MAPI + attr = quick.getAttachments().get(0).getAttribute( + TNEFProperty.ID_ATTACHMENT + ); + assertNotNull(attr); + assertEquals(TNEFMAPIAttribute.class, attr.getClass()); + + mapi = (TNEFMAPIAttribute) attr; + assertEquals(22, mapi.getMAPIAttributes().size()); + assertEquals( + MAPIProperty.ATTACH_SIZE, + mapi.getMAPIAttributes().get(0).getProperty() + ); + } -import junit.framework.TestCase; - -public final class TestTNEFAttributes extends TestCase { - private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance(); - private HMEFMessage quick; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - quick = new HMEFMessage( - _samples.openResourceAsStream("quick-winmail.dat") - ); - } - - /** - * Test counts - */ - public void testCounts() throws Exception { - // The message should have 4 attributes - assertEquals(4, quick.getMessageAttributes().size()); - - // Each attachment should have 6 attributes - for(Attachment attach : quick.getAttachments()) { - assertEquals(6, attach.getAttributes().size()); - } - } - - /** - * Test the basics - */ - public void testBasics() throws Exception { - // An int one - assertEquals( - 0x010000, - LittleEndian.getInt( quick.getMessageAttribute(TNEFProperty.ID_TNEFVERSION).getData() ) - ); - - // Claims not to be text, but really is - assertEquals( - "IPM.Microsoft Mail.Note\0", - new String(quick.getMessageAttribute(TNEFProperty.ID_MESSAGECLASS).getData(), "ASCII") - ); - - // Try constructing two attributes - byte[] data = new byte[] { - // Level one, id 36870, type 8 - 0x01, 0x06, (byte)0x90, 0x08, 0x00, - // Length 4 - 0x04, 0x00, 0x00, 0x00, - // Data - 0x00, 0x00, 0x01, 0x00, - // Checksum - 0x01, 0x00, - - // level one, id 36871, type 6 - 0x01, 0x07, (byte)0x90, 0x06, 0x00, - // Length 8 - 0x08, 0x00, 0x00, 0x00, - // Data - (byte)0xe4, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - // Checksum - (byte)0xe8, 0x00 - }; - ByteArrayInputStream bais = new ByteArrayInputStream(data); - - // Create them - int level = bais.read(); - assertEquals(1, level); - TNEFAttribute attr1 = TNEFAttribute.create(bais); - - level = bais.read(); - assertEquals(1, level); - TNEFAttribute attr2 = TNEFAttribute.create(bais); - - assertEquals(-1, bais.read()); - - // Check them - assertEquals(TNEFProperty.ID_TNEFVERSION, attr1.getProperty()); - assertEquals(8, attr1.getType()); - assertEquals(4, attr1.getData().length); - assertEquals(0x010000, LittleEndian.getInt( attr1.getData() )); - - assertEquals(TNEFProperty.ID_OEMCODEPAGE, attr2.getProperty()); - assertEquals(6, attr2.getType()); - assertEquals(8, attr2.getData().length); - assertEquals(0x04e4, LittleEndian.getInt( attr2.getData() )); - } - - /** - * Test string based ones - */ - public void testString() throws Exception { - TNEFAttribute attr = quick.getAttachments().get(0).getAttribute( - TNEFProperty.ID_ATTACHTITLE - ); - assertNotNull(attr); - assertEquals(TNEFStringAttribute.class, attr.getClass()); - - // It is a null terminated string - assertEquals("quick.doc\u0000", new String(attr.getData(), "ASCII")); - - // But when we ask for the string, that is sorted for us - TNEFStringAttribute str = (TNEFStringAttribute)attr; - assertEquals("quick.doc", str.getString()); - } - - /** - * Test date based ones - */ - public void testDate() throws Exception { - TNEFAttribute attr = quick.getAttachments().get(0).getAttribute( - TNEFProperty.ID_ATTACHMODIFYDATE - ); - assertNotNull(attr); - assertEquals(TNEFDateAttribute.class, attr.getClass()); - - // It is a series of date parts - // Weds 28th April 2010 @ 12:40:56 UTC - assertEquals(2010, LittleEndian.getUShort(attr.getData(), 0)); - assertEquals(04, LittleEndian.getUShort(attr.getData(), 2)); - assertEquals(28, LittleEndian.getUShort(attr.getData(), 4)); - assertEquals(12, LittleEndian.getUShort(attr.getData(), 6)); - assertEquals(40, LittleEndian.getUShort(attr.getData(), 8)); - assertEquals(56, LittleEndian.getUShort(attr.getData(), 10)); - assertEquals(3, LittleEndian.getUShort(attr.getData(), 12)); // Weds - - // Ask for it as a Java date, and have it converted - // Pick a predictable format + location + timezone - TNEFDateAttribute date = (TNEFDateAttribute)attr; - DateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.UK); - fmt.setTimeZone(LocaleUtil.TIMEZONE_UTC); - assertEquals("28-Apr-2010 12:40:56", fmt.format(date.getDate())); - } - - /** - * Test a bit of mapi - */ - public void testMAPI() throws Exception { - // Message MAPI - TNEFAttribute attr = quick.getMessageAttribute( - TNEFProperty.ID_MAPIPROPERTIES - ); - assertNotNull(attr); - assertEquals(TNEFMAPIAttribute.class, attr.getClass()); - - TNEFMAPIAttribute mapi = (TNEFMAPIAttribute)attr; - assertEquals(54, mapi.getMAPIAttributes().size()); - assertEquals( - MAPIProperty.ALTERNATE_RECIPIENT_ALLOWED, - mapi.getMAPIAttributes().get(0).getProperty() - ); - - - // Attribute MAPI - attr = quick.getAttachments().get(0).getAttribute( - TNEFProperty.ID_ATTACHMENT - ); - assertNotNull(attr); - assertEquals(TNEFMAPIAttribute.class, attr.getClass()); - - mapi = (TNEFMAPIAttribute)attr; - assertEquals(22, mapi.getMAPIAttributes().size()); - assertEquals( - MAPIProperty.ATTACH_SIZE, - mapi.getMAPIAttributes().get(0).getProperty() - ); - } - - /** - * Test common ones via helpers - */ - public void testCommon() throws Exception { - assertEquals("This is a test message", quick.getSubject()); - assertEquals("quick.doc", quick.getAttachments().get(0).getFilename()); - } + /** + * Test common ones via helpers + */ + @Test + public void testCommon() throws Exception { + assertEquals("This is a test message", quick.getSubject()); + assertEquals("quick.doc", quick.getAttachments().get(0).getFilename()); + } } diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/dev/TestHMEFDumper.java b/src/scratchpad/testcases/org/apache/poi/hmef/dev/TestHMEFDumper.java index 5d956b0cb8..95a7d91460 100644 --- a/src/scratchpad/testcases/org/apache/poi/hmef/dev/TestHMEFDumper.java +++ b/src/scratchpad/testcases/org/apache/poi/hmef/dev/TestHMEFDumper.java @@ -20,31 +20,38 @@ ==================================================================== */ package org.apache.poi.hmef.dev; +import java.io.File; +import java.io.PrintStream; + import org.apache.poi.POIDataSamples; +import org.apache.poi.util.NullOutputStream; import org.junit.Test; -import java.io.File; - public class TestHMEFDumper { @Test(expected = IllegalArgumentException.class) public void noArguments() throws Exception { - HMEFDumper.main(new String[] {}); + doMain(); } @Test public void main() throws Exception { File file = POIDataSamples.getHMEFInstance().getFile("quick-winmail.dat"); - HMEFDumper.main(new String[] { - file.getAbsolutePath() - }); + doMain(file.getAbsolutePath()); } @Test public void mainFull() throws Exception { File file = POIDataSamples.getHMEFInstance().getFile("quick-winmail.dat"); - HMEFDumper.main(new String[] { - "--full", - file.getAbsolutePath() - }); + doMain("--full", file.getAbsolutePath()); + } + + private static void doMain(String... args) throws Exception { + PrintStream ps = System.out; + try { + System.setOut(new PrintStream(new NullOutputStream(), true, "UTF-8")); + HMEFDumper.main(args); + } finally { + System.setOut(ps); + } } } \ No newline at end of file