mirror of https://github.com/apache/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
This commit is contained in:
parent
713a69afdb
commit
2eee474063
|
@ -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<Integer, MAPIType> builtInTypes = new HashMap<>();
|
||||
private static Map<Integer, MAPIType> customTypes = new HashMap<>();
|
||||
private static final Map<Integer, MAPIType> builtInTypes = new HashMap<>();
|
||||
private static final Map<Integer, MAPIType> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 extends HMEFTest {
|
||||
private HMEFMessage quick;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
quick = new HMEFMessage(
|
||||
_samples.openResourceAsStream("quick-winmail.dat")
|
||||
);
|
||||
}
|
||||
public final class TestAttachments {
|
||||
protected static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
|
||||
|
||||
/**
|
||||
* 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<Attachment> 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<Attachment> 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<Attachment> 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));
|
||||
}
|
||||
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<Attachment> 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<Attachment> 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<Attachment> 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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
HMEFMessage msg;
|
||||
try (InputStream is = _samples.openResourceAsStream("quick-winmail.dat")) {
|
||||
msg = new HMEFMessage(is);
|
||||
}
|
||||
|
||||
// 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);
|
||||
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")
|
||||
);
|
||||
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;
|
||||
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);
|
||||
// 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<expected.length; i++) {
|
||||
assertEquals(expected[i], decomp[i]);
|
||||
}
|
||||
|
||||
// By String
|
||||
String expString = new String(expected, "ASCII");
|
||||
String decompStr = rtfAttr.getDataString();
|
||||
assertEquals(expString.length(), decompStr.length());
|
||||
assertEquals(expString, decompStr);
|
||||
} finally {
|
||||
stream.close();
|
||||
}
|
||||
final 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;
|
||||
|
||||
final byte[] expected;
|
||||
try (InputStream stream = _samples.openResourceAsStream("quick-contents/message.rtf")) {
|
||||
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 < expected.length; i++) {
|
||||
assertEquals(expected[i], decomp[i]);
|
||||
}
|
||||
|
||||
// By String
|
||||
String expString = new String(expected, "ASCII");
|
||||
String decompStr = rtfAttr.getDataString();
|
||||
assertEquals(expString.length(), decompStr.length());
|
||||
assertEquals(expString, decompStr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,217 +17,251 @@
|
|||
|
||||
package org.apache.poi.hmef;
|
||||
|
||||
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;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
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.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.Test;
|
||||
|
||||
public final class TestHMEFMessage extends HMEFTest {
|
||||
public void testOpen() throws Exception {
|
||||
HMEFMessage msg = new HMEFMessage(
|
||||
public final class TestHMEFMessage {
|
||||
protected static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
|
||||
|
||||
@Test
|
||||
public void testOpen() throws Exception {
|
||||
HMEFMessage msg = new HMEFMessage(
|
||||
_samples.openResourceAsStream("quick-winmail.dat")
|
||||
);
|
||||
);
|
||||
|
||||
assertNotNull(msg);
|
||||
}
|
||||
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));
|
||||
}
|
||||
@Test
|
||||
public void testCounts() throws Exception {
|
||||
HMEFMessage msg = new HMEFMessage(
|
||||
_samples.openResourceAsStream("quick-winmail.dat")
|
||||
);
|
||||
|
||||
/**
|
||||
* 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"));
|
||||
// Should have 4 attributes on the message
|
||||
assertEquals(4, msg.getMessageAttributes().size());
|
||||
|
||||
// Firstly by byte
|
||||
MAPIRtfAttribute rtf = (MAPIRtfAttribute) msg
|
||||
.getMessageMAPIAttribute(MAPIProperty.RTF_COMPRESSED);
|
||||
// assertContents("message.rtf", rtf.getData());
|
||||
assertNotNull(rtf);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
@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")
|
||||
);
|
||||
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
public final class TestMAPIAttributes {
|
||||
private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
|
||||
private HMEFMessage quick;
|
||||
private InputStream stream;
|
||||
|
||||
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);
|
||||
}
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
stream = _samples.openResourceAsStream("quick-winmail.dat");
|
||||
quick = new HMEFMessage(stream);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
stream.close();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
stream.close();
|
||||
/**
|
||||
* Test counts
|
||||
*/
|
||||
@Test
|
||||
public void testCounts() throws Exception {
|
||||
// Message should have 54
|
||||
assertEquals(54, quick.getMessageMAPIAttributes().size());
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
// 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,
|
||||
|
||||
/**
|
||||
* 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()
|
||||
);
|
||||
}
|
||||
// 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);
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
// Create it
|
||||
int level = bais.read();
|
||||
assertEquals(1, level);
|
||||
TNEFAttribute attr = TNEFAttribute.create(bais);
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
// 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());
|
||||
|
||||
assertEquals("quick.doc", quick.getAttachments().get(0).getLongFilename());
|
||||
assertEquals(".doc", quick.getAttachments().get(0).getExtension());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
public final class TestTNEFAttributes {
|
||||
private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
|
||||
private HMEFMessage quick;
|
||||
|
||||
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());
|
||||
}
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
try (InputStream is = _samples.openResourceAsStream("quick-winmail.dat")) {
|
||||
quick = new HMEFMessage(is);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,31 +20,38 @@
|
|||
==================================================================== */
|
||||
package org.apache.poi.hmef.dev;
|
||||
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.apache.poi.POIDataSamples;
|
||||
import org.apache.poi.util.NullOutputStream;
|
||||
import org.junit.Test;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue