commits@javamail.java.net

[javamail~mercurial:264] Ignore encoding for composite content when writing message.

From: <shannon_at_kenai.com>
Date: Sun, 21 Feb 2010 19:53:51 +0000

Project: javamail
Repository: mercurial
Revision: 264
Author: shannon
Date: 2010-02-20 00:32:14 UTC
Link:

Log Message:
------------
Fix typo in javadoc.
Ignore encoding for composite content when writing message.


Revisions:
----------
263
264


Modified Paths:
---------------
mail/src/main/java/javax/mail/internet/MimeBodyPart.java
doc/release/CHANGES.txt
mail/src/main/java/com/sun/mail/imap/IMAPBodyPart.java
mail/src/main/java/javax/mail/internet/MimePartDataSource.java
mail/src/main/java/javax/mail/internet/package.html


Added Paths:
------------
mail/src/test/java/javax/mail/internet/RestrictEncodingTest.java


Diffs:
------
diff -r b139d18e7395 -r 89075cfbdcbe mail/src/main/java/javax/mail/internet/MimeBodyPart.java
--- a/mail/src/main/java/javax/mail/internet/MimeBodyPart.java Wed Feb 03 15:00:42 2010 -0800
+++ b/mail/src/main/java/javax/mail/internet/MimeBodyPart.java Wed Feb 10 17:51:11 2010 -0800
@@ -492,7 +492,7 @@
      * the "Content-Type" header field of this body part.
      * Returns <code>null</code> if both are absent. <p>
      *
- * If the <code>mail.mime.encodefilename</code> System property
+ * If the <code>mail.mime.decodefilename</code> System property
      * is set to true, the {_at_link MimeUtility#decodeText
      * MimeUtility.decodeText} method will be used to decode the
      * filename. While such encoding is not supported by the MIME


diff -r 89075cfbdcbe -r 2201d882950b doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Wed Feb 10 17:51:11 2010 -0800
+++ b/doc/release/CHANGES.txt Fri Feb 19 16:32:14 2010 -0800
@@ -36,6 +36,7 @@
 <no id> add mail.mime.allowencodedmessages System property
 <no id> add support for SASL authentication to SMTP provider
 <no id> add SMTPSenderFailedException to indicate problems with sender address
+<no id> ignore encoding for composite content when writing message
 
 
                   CHANGES IN THE 1.4.3 RELEASE

diff -r 89075cfbdcbe -r 2201d882950b mail/src/main/java/com/sun/mail/imap/IMAPBodyPart.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPBodyPart.java Wed Feb 10 17:51:11 2010 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPBodyPart.java Fri Feb 19 16:32:14 2010 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved.
  *
  * The contents of this file are subject to the terms of either the GNU
  * General Public License Version 2 only ("GPL") or the Common Development
@@ -48,7 +48,7 @@
 import com.sun.mail.imap.protocol.*;
 
 /**
- * This class
+ * An IMAP body part.
  *
  * @author John Mani
  */
@@ -64,6 +64,9 @@
 
     private boolean headersLoaded = false;
 
+ private static final boolean decodeFileName =
+ PropUtil.getBooleanSystemProperty("mail.mime.decodefilename", false);
+
     protected IMAPBodyPart(BODYSTRUCTURE bs, String sid, IMAPMessage message) {
         super();
         this.bs = bs;
@@ -146,6 +149,13 @@
             filename = bs.dParams.get("filename");
         if (filename == null && bs.cParams != null)
             filename = bs.cParams.get("name");
+ if (decodeFileName && filename != null) {
+ try {
+ filename = MimeUtility.decodeText(filename);
+ } catch (UnsupportedEncodingException ex) {
+ throw new MessagingException("Can't decode filename", ex);
+ }
+ }
         return filename;
     }
 

diff -r 89075cfbdcbe -r 2201d882950b mail/src/main/java/javax/mail/internet/MimeBodyPart.java
--- a/mail/src/main/java/javax/mail/internet/MimeBodyPart.java Wed Feb 10 17:51:11 2010 -0800
+++ b/mail/src/main/java/javax/mail/internet/MimeBodyPart.java Fri Feb 19 16:32:14 2010 -0800
@@ -90,6 +90,9 @@
         PropUtil.getBooleanSystemProperty("mail.mime.encodefilename", false);
     private static final boolean decodeFileName =
         PropUtil.getBooleanSystemProperty("mail.mime.decodefilename", false);
+ private static final boolean ignoreMultipartEncoding =
+ PropUtil.getBooleanSystemProperty(
+ "mail.mime.ignoremultipartencoding", true);
 
     // Paranoia:
     // allow this last minute change to be disabled if it causes problems
@@ -1264,6 +1267,44 @@
         part.setHeader("Content-Transfer-Encoding", encoding);
     }
 
+ /**
+ * Restrict the encoding to values allowed for the
+ * Content-Type of the specified MimePart. Returns
+ * either the original encoding or null.
+ */
+ static String restrictEncoding(MimePart part, String encoding)
+ throws MessagingException {
+ if (!ignoreMultipartEncoding || encoding == null)
+ return encoding;
+
+ if (encoding.equalsIgnoreCase("7bit") ||
+ encoding.equalsIgnoreCase("8bit") ||
+ encoding.equalsIgnoreCase("binary"))
+ return encoding; // these encodings are always valid
+
+ String type = part.getContentType();
+ if (type == null)
+ return encoding;
+
+ try {
+ /*
+ * multipart and message types aren't allowed to have
+ * encodings except for the three mentioned above.
+ * If it's one of these types, ignore the encoding.
+ */
+ ContentType cType = new ContentType(type);
+ if (cType.match("multipart/*"))
+ return null;
+ if (cType.match("message/*") &&
+ !PropUtil.getBooleanSystemProperty(
+ "mail.mime.allowencodedmessages", false))
+ return null;
+ } catch (ParseException pex) {
+ // ignore it
+ }
+ return encoding;
+ }
+
     static void updateHeaders(MimePart part) throws MessagingException {
         DataHandler dh = part.getDataHandler();
         if (dh == null) // Huh ?
@@ -1426,7 +1467,8 @@
                 while ((len = is.read(buf)) > 0)
                     os.write(buf, 0, len);
             } else {
- os = MimeUtility.encode(os, part.getEncoding());
+ os = MimeUtility.encode(os,
+ restrictEncoding(part, part.getEncoding()));
                 part.getDataHandler().writeTo(os);
             }
         } finally {

diff -r 89075cfbdcbe -r 2201d882950b mail/src/main/java/javax/mail/internet/MimePartDataSource.java
--- a/mail/src/main/java/javax/mail/internet/MimePartDataSource.java Wed Feb 10 17:51:11 2010 -0800
+++ b/mail/src/main/java/javax/mail/internet/MimePartDataSource.java Fri Feb 19 16:32:14 2010 -0800
@@ -61,10 +61,6 @@
 
     private MessageContext context;
 
- private static final boolean ignoreMultipartEncoding =
- PropUtil.getBooleanSystemProperty(
- "mail.mime.ignoremultipartencoding", true);
-
     /**
      * Constructor, that constructs a DataSource from a MimePart.
      */
@@ -99,7 +95,8 @@
             else
                 throw new MessagingException("Unknown part");
             
- String encoding = restrictEncoding(part.getEncoding(), part);
+ String encoding =
+ MimeBodyPart.restrictEncoding(part, part.getEncoding());
             if (encoding != null)
                 return MimeUtility.decode(is, encoding);
             else
@@ -110,45 +107,6 @@
     }
 
     /**
- * Restrict the encoding to values allowed for the
- * Content-Type of the specified MimePart. Returns
- * either the original encoding or null.
- */
- private static String restrictEncoding(String encoding, MimePart part)
- throws MessagingException {
- if (!ignoreMultipartEncoding || encoding == null)
- return encoding;
-
- if (encoding.equalsIgnoreCase("7bit") ||
- encoding.equalsIgnoreCase("8bit") ||
- encoding.equalsIgnoreCase("binary"))
- return encoding; // these encodings are always valid
-
- String type = part.getContentType();
- if (type == null)
- return encoding;
-
- try {
- /*
- * multipart and message types aren't allowed to have
- * encodings except for the three mentioned above.
- * If it's one of these types, ignore the encoding.
- */
- ContentType cType = new ContentType(type);
- if (cType.match("multipart/*"))
- return null;
- if (cType.match("message/*") &&
- !PropUtil.getBooleanSystemProperty(
- "mail.mime.allowencodedmessages", false))
- return null;
- } catch (ParseException pex) {
- // ignore it
- }
- return encoding;
- }
-
-
- /**
      * DataSource method to return an output stream. <p>
      *
      * This implementation throws the UnknownServiceException.

diff -r 89075cfbdcbe -r 2201d882950b mail/src/main/java/javax/mail/internet/package.html
--- a/mail/src/main/java/javax/mail/internet/package.html Wed Feb 10 17:51:11 2010 -0800
+++ b/mail/src/main/java/javax/mail/internet/package.html Fri Feb 19 16:32:14 2010 -0800
@@ -401,6 +401,19 @@
 </TR>
 
 <TR>
+<TD>mail.mime. ignoremultipartencoding</TD>
+<TD>boolean</TD>
+<TD>
+The MIME spec does not allow body parts of type multipart/* to be encoded.
+The Content-Transfer-Encoding header is ignored in this case.
+Setting this System property to <code>"false"</code> will
+cause the Content-Transfer-Encoding header to be honored for multipart
+content.
+The default value of this property is true.
+</TD>
+</TR>
+
+<TR>
 <TD>mail.mime.allowencodedmessages</TD>
 <TD>boolean</TD>
 <TD>

diff -r 89075cfbdcbe -r 2201d882950b mail/src/test/java/javax/mail/internet/RestrictEncodingTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/javax/mail/internet/RestrictEncodingTest.java Fri Feb 19 16:32:14 2010 -0800
@@ -0,0 +1,129 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.mail.internet;
+
+import java.io.StringBufferInputStream;
+import java.util.Properties;
+
+import javax.mail.Session;
+import javax.mail.MessagingException;
+import javax.mail.BodyPart;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import org.junit.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test that the Content-Transfer-Encoding header is ignored
+ * for composite parts.
+ *
+ * XXX - We don't test any of the properties that control this behavior.
+ */
+public class RestrictEncodingTest {
+
+ private static Session s = Session.getInstance(new Properties());
+
+ @Test
+ public void testMultipart() throws Exception {
+ MimeMessage m = createMessage();
+ MimeMultipart mp = (MimeMultipart)m.getContent();
+ assertEquals(2, mp.getCount());
+
+ BodyPart bp = mp.getBodyPart(0);
+ assertEquals("first part=\n", bp.getContent());
+ }
+
+ @Test
+ public void testMessage() throws Exception {
+ MimeMessage m = createMessage();
+ MimeMultipart mp = (MimeMultipart)m.getContent();
+
+ BodyPart bp = mp.getBodyPart(1);
+ MimeMessage m2 = (MimeMessage)bp.getContent();
+ assertEquals("message=\n", m2.getContent());
+ }
+
+ @Test
+ public void testWrite() throws Exception {
+ MimeMessage m = new MimeMessage(s);
+ MimeMultipart mp = new MimeMultipart();
+ MimeBodyPart mbp = new MimeBodyPart();
+ mbp.setText("first part");
+ mp.addBodyPart(mbp);
+ MimeMessage m2 = new MimeMessage(s);
+ m2.setSubject("example");
+ m2.setText("message=\n");
+ mbp = new MimeBodyPart();
+ mbp.setContent(m2, "message/rfc822");
+ mbp.setHeader("Content-Transfer-Encoding", "quoted-printable");
+ mp.addBodyPart(mbp);
+ m.setContent(mp);
+ m.setHeader("Content-Transfer-Encoding", "quoted-printable");
+
+ m = new MimeMessage(m); // copy it
+ mp = (MimeMultipart)m.getContent();
+
+ BodyPart bp = mp.getBodyPart(1);
+ m2 = (MimeMessage)bp.getContent();
+ assertEquals("message=\n", m2.getContent());
+ }
+
+ private static MimeMessage createMessage() throws MessagingException {
+ String content =
+ "Mime-Version: 1.0\n" +
+ "Content-Type: multipart/mixed; boundary=\"=3D\"\n" +
+ "Content-Transfer-Encoding: quoted-printable\n" +
+ "\n" +
+ "--=3D\n" +
+ "\n" +
+ "first part=\n" +
+ "\n" +
+ "--=3D\n" +
+ "Content-Type: message/rfc822\n" +
+ "Content-Transfer-Encoding: quoted-printable\n" +
+ "\n" +
+ "Subject: example\n" +
+ "\n" +
+ "message=\n" +
+ "\n" +
+ "--=3D--\n";
+
+ return new MimeMessage(s, new StringBufferInputStream(content));
+ }
+}