You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ce...@apache.org on 2013/11/03 13:43:43 UTC

svn commit: r1538353 - in /poi/trunk: src/scratchpad/src/org/apache/poi/hmef/ src/scratchpad/src/org/apache/poi/hmef/dev/ src/scratchpad/testcases/org/apache/poi/hmef/ test-data/hmef/

Author: centic
Date: Sun Nov  3 12:43:42 2013
New Revision: 1538353

URL: http://svn.apache.org/r1538353
Log:
Bug 52400: fix handling some types of TNEF files, make HMEFMessage.HEADER_SIGNATURE int as it is handled as int everywhere, move .dat files to HMEF sample dir, cover some border cases in HMEFMessage, add another .dat sample file

Added:
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestBugs.java
    poi/trunk/test-data/hmef/bug52400-winmail-simple.dat
    poi/trunk/test-data/hmef/bug52400-winmail-with-attachments.dat
    poi/trunk/test-data/hmef/winmail-sample1.dat
Modified:
    poi/trunk/src/scratchpad/src/org/apache/poi/hmef/HMEFMessage.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hmef/HMEFMessage.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hmef/HMEFMessage.java?rev=1538353&r1=1538352&r2=1538353&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hmef/HMEFMessage.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hmef/HMEFMessage.java Sun Nov  3 12:43:42 2013
@@ -39,7 +39,7 @@ import org.apache.poi.util.LittleEndian;
  *   http://search.cpan.org/dist/Convert-TNEF/
  */
 public final class HMEFMessage {
-   public static final long HEADER_SIGNATURE = 0x223e9f78;
+   public static final int HEADER_SIGNATURE = 0x223e9f78;
    
    private int fileId; 
    private List<TNEFAttribute> messageAttributes = new ArrayList<TNEFAttribute>();
@@ -48,7 +48,7 @@ public final class HMEFMessage {
    
    public HMEFMessage(InputStream inp) throws IOException {
       // Check the signature matches
-      long sig = LittleEndian.readInt(inp);
+      int sig = LittleEndian.readInt(inp);
       if(sig != HEADER_SIGNATURE) {
          throw new IllegalArgumentException(
                "TNEF signature not detected in file, " +
@@ -60,42 +60,59 @@ public final class HMEFMessage {
       fileId = LittleEndian.readUShort(inp);
       
       // Now begin processing the contents
-      process(inp, 0);
+      process(inp);
    }
    
-   private void process(InputStream inp, int lastLevel) throws IOException {
-      // Fetch the level
-      int level = inp.read();
-      if(level == TNEFProperty.LEVEL_END_OF_FILE) {
-         return;
+   private void process(InputStream inp) throws IOException {
+      int level;
+      do {
+         // Fetch the level
+         level = inp.read();
+
+         // Decide what to attach it to, based on the levels and IDs
+         switch (level) {
+         case TNEFProperty.LEVEL_MESSAGE:
+            processMessage(inp);
+            break;
+         case TNEFProperty.LEVEL_ATTACHMENT:
+            processAttachment(inp);
+            break;
+         // ignore trailing newline
+         case '\r':
+         case '\n':
+         case TNEFProperty.LEVEL_END_OF_FILE:
+            break;
+         default:
+            throw new IllegalStateException("Unhandled level " + level);
+         }
+      } while (level != TNEFProperty.LEVEL_END_OF_FILE);
+   }
+
+   void processMessage(InputStream inp) throws IOException {
+      // Build the attribute
+      TNEFAttribute attr = TNEFAttribute.create(inp);
+
+      messageAttributes.add(attr);
+
+      if (attr instanceof TNEFMAPIAttribute) {
+         TNEFMAPIAttribute tnefMAPI = (TNEFMAPIAttribute) attr;
+         mapiAttributes.addAll(tnefMAPI.getMAPIAttributes());
       }
-    
+   }
+
+   void processAttachment(InputStream inp) throws IOException {
       // Build the attribute
       TNEFAttribute attr = TNEFAttribute.create(inp);
-      
-      // Decide what to attach it to, based on the levels and IDs
-      if(level == TNEFProperty.LEVEL_MESSAGE) {
-         messageAttributes.add(attr);
-         
-         if(attr instanceof TNEFMAPIAttribute) {
-            TNEFMAPIAttribute tnefMAPI = (TNEFMAPIAttribute)attr;
-            mapiAttributes.addAll( tnefMAPI.getMAPIAttributes() );
-         }
-      } else if(level == TNEFProperty.LEVEL_ATTACHMENT) {
-         // Previous attachment or a new one?
-         if(attachments.size() == 0 || attr.getProperty() == TNEFProperty.ID_ATTACHRENDERDATA) {
-            attachments.add(new Attachment());
-         }
-         
-         // Save the attribute for it
-         Attachment attach = attachments.get(attachments.size()-1);
-         attach.addAttribute(attr);
-      } else {
-         throw new IllegalStateException("Unhandled level " + level);
+
+      // Previous attachment or a new one?
+      if (attachments.isEmpty()
+         || attr.getProperty() == TNEFProperty.ID_ATTACHRENDERDATA) {
+         attachments.add(new Attachment());
       }
-      
-      // Handle the next one down
-      process(inp, level);
+
+      // Save the attribute for it
+      Attachment attach = attachments.get(attachments.size() - 1);
+      attach.addAttribute(attr);
    }
    
    /**

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java?rev=1538353&r1=1538352&r2=1538353&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java Sun Nov  3 12:43:42 2013
@@ -23,8 +23,8 @@ import java.io.InputStream;
 import java.util.List;
 
 import org.apache.poi.hmef.HMEFMessage;
-import org.apache.poi.hmef.attribute.TNEFAttribute;
 import org.apache.poi.hmef.attribute.MAPIAttribute;
+import org.apache.poi.hmef.attribute.TNEFAttribute;
 import org.apache.poi.hmef.attribute.TNEFDateAttribute;
 import org.apache.poi.hmef.attribute.TNEFProperty;
 import org.apache.poi.hmef.attribute.TNEFStringAttribute;
@@ -62,7 +62,7 @@ public final class HMEFDumper {
       this.inp = inp;
       
       // Check the signature matches
-      long sig = LittleEndian.readInt(inp);
+      int sig = LittleEndian.readInt(inp);
       if(sig != HMEFMessage.HEADER_SIGNATURE) {
          throw new IllegalArgumentException(
                "TNEF signature not detected in file, " +

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestBugs.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestBugs.java?rev=1538353&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestBugs.java (added)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestBugs.java Sun Nov  3 12:43:42 2013
@@ -0,0 +1,48 @@
+package org.apache.poi.hmef;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hmef.attribute.MAPIAttribute;
+import org.apache.poi.hmef.attribute.TNEFAttribute;
+import org.apache.poi.hmef.attribute.TNEFProperty;
+import org.apache.poi.hsmf.datatypes.MAPIProperty;
+import org.apache.poi.util.LittleEndian;
+
+public class TestBugs extends TestCase {
+    public void test52400ReadSimpleTNEF() throws Exception {
+        POIDataSamples samples = POIDataSamples.getHMEFInstance();
+        String testFile = "bug52400-winmail-simple.dat";
+        HMEFMessage tnefDat    = new HMEFMessage(samples.openResourceAsStream(testFile));
+        MAPIAttribute bodyHtml = tnefDat.getMessageMAPIAttribute(MAPIProperty.BODY_HTML);
+        String bodyStr = new String(bodyHtml.getData(), getEncoding(tnefDat));
+        assertTrue(bodyStr.contains("This is the message body."));
+    }
+    
+    public void test52400ReadAttachedTNEF() throws Exception {
+        POIDataSamples samples = POIDataSamples.getHMEFInstance();
+        String testFile = "bug52400-winmail-with-attachments.dat";
+        HMEFMessage tnefDat    = new HMEFMessage(samples.openResourceAsStream(testFile));
+        MAPIAttribute bodyHtml = tnefDat.getMessageMAPIAttribute(MAPIProperty.BODY_HTML);
+        String bodyStr = new String(bodyHtml.getData(), getEncoding(tnefDat));
+        assertTrue(bodyStr.contains("There are also two attachments."));
+        assertEquals(2, tnefDat.getAttachments().size());
+    }
+    
+    private String getEncoding(HMEFMessage tnefDat) {
+        TNEFAttribute oemCP = tnefDat.getMessageAttribute(TNEFProperty.ID_OEMCODEPAGE);
+        MAPIAttribute cpId = tnefDat.getMessageMAPIAttribute(MAPIProperty.INTERNET_CPID);
+        int codePage = 1252;
+        if (oemCP != null) {
+            codePage = LittleEndian.getInt(oemCP.getData());
+        } else if (cpId != null) {
+            codePage =  LittleEndian.getInt(cpId.getData());
+        }
+        switch (codePage) {
+        // see http://en.wikipedia.org/wiki/Code_page for more
+        case 1252: return "Windows-1252";
+        case 20127: return "US-ASCII";
+        default: return "cp"+codePage;
+        }
+    }
+}

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java?rev=1538353&r1=1538352&r2=1538353&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java Sun Nov  3 12:43:42 2013
@@ -17,6 +17,10 @@
 
 package org.apache.poi.hmef;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
 import org.apache.poi.hmef.attribute.MAPIRtfAttribute;
 import org.apache.poi.hmef.attribute.TNEFProperty;
 import org.apache.poi.hsmf.datatypes.MAPIProperty;
@@ -119,5 +123,80 @@ public final class TestHMEFMessage exten
       // 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"));
+	   }
    }
 }
+

Added: poi/trunk/test-data/hmef/bug52400-winmail-simple.dat
URL: http://svn.apache.org/viewvc/poi/trunk/test-data/hmef/bug52400-winmail-simple.dat?rev=1538353&view=auto
==============================================================================
Files poi/trunk/test-data/hmef/bug52400-winmail-simple.dat (added) and poi/trunk/test-data/hmef/bug52400-winmail-simple.dat Sun Nov  3 12:43:42 2013 differ

Added: poi/trunk/test-data/hmef/bug52400-winmail-with-attachments.dat
URL: http://svn.apache.org/viewvc/poi/trunk/test-data/hmef/bug52400-winmail-with-attachments.dat?rev=1538353&view=auto
==============================================================================
Files poi/trunk/test-data/hmef/bug52400-winmail-with-attachments.dat (added) and poi/trunk/test-data/hmef/bug52400-winmail-with-attachments.dat Sun Nov  3 12:43:42 2013 differ

Added: poi/trunk/test-data/hmef/winmail-sample1.dat
URL: http://svn.apache.org/viewvc/poi/trunk/test-data/hmef/winmail-sample1.dat?rev=1538353&view=auto
==============================================================================
Files poi/trunk/test-data/hmef/winmail-sample1.dat (added) and poi/trunk/test-data/hmef/winmail-sample1.dat Sun Nov  3 12:43:42 2013 differ



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org