commits@javamail.java.net

[javamail~mercurial:680] skip unusable Store and Transport classes - bug 6668

From: <shannon_at_java.net>
Date: Sat, 17 Jan 2015 00:14:24 +0000

Project: javamail
Repository: mercurial
Revision: 680
Author: shannon
Date: 2015-01-17 00:08:09 UTC
Link:

Log Message:
------------
Ensure that attachment file names are encoded by default - bug 6638
MimeBodyPart with copied DataHandler doesn't always set encoding - bug 6667
SharedFileInputStream has problems with 2GB+ files - bug 6657
fix possible NPE in copyUIDMessages by removing dead code accidentally left in
skip unusable Store and Transport classes - bug 6668

(fix inspired by Jason)


Revisions:
----------
676
677
678
679
680


Modified Paths:
---------------
doc/release/CHANGES.txt
mail/src/main/java/javax/mail/internet/MimeBodyPart.java
mail/src/test/java/javax/mail/internet/ParameterListTestSuite.java
mail/src/test/java/javax/mail/internet/MimeBodyPartTest.java
mail/src/main/java/javax/mail/util/SharedFileInputStream.java
mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
mail/src/main/java/javax/mail/Session.java


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


Diffs:
------
diff -r c2a7b6497852 -r f09bb142c9a4 doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Mon Dec 01 14:29:28 2014 -0800
+++ b/doc/release/CHANGES.txt Fri Dec 19 16:09:59 2014 -0800
@@ -25,6 +25,7 @@
 K 6526 Date search terms result in wrong greater-than SEARCH commands for IMAP
 K 6535 address similar to (x)<y>(z) will throw StringIndexOutOfBoundsException
 K 6551 Update logging demos to use the new 1.5.2 features
+K 6638 attachment filenames aren't being encoded by default
 
 
                   CHANGES IN THE 1.5.2 RELEASE

diff -r c2a7b6497852 -r f09bb142c9a4 mail/src/main/java/javax/mail/internet/MimeBodyPart.java
--- a/mail/src/main/java/javax/mail/internet/MimeBodyPart.java Mon Dec 01 14:29:28 2014 -0800
+++ b/mail/src/main/java/javax/mail/internet/MimeBodyPart.java Fri Dec 19 16:09:59 2014 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2014 Oracle and/or its affiliates. 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
@@ -1275,7 +1275,14 @@
         String s = part.getHeader("Content-Disposition", null);
         ContentDisposition cd =
                 new ContentDisposition(s == null ? Part.ATTACHMENT : s);
- cd.setParameter("filename", name);
+ // ensure that the filename is encoded if necessary
+ String charset = MimeUtility.getDefaultMIMECharset();
+ ParameterList p = cd.getParameterList();
+ if (p == null) {
+ p = new ParameterList();
+ cd.setParameterList(p);
+ }
+ p.set("filename", name, charset);
         part.setHeader("Content-Disposition", cd.toString());
 
         /*
@@ -1288,7 +1295,13 @@
             if (s != null) {
                 try {
                     ContentType cType = new ContentType(s);
- cType.setParameter("name", name);
+ // ensure that the filename is encoded if necessary
+ p = cType.getParameterList();
+ if (p == null) {
+ p = new ParameterList();
+ cType.setParameterList(p);
+ }
+ p.set("name", name, charset);
                     part.setHeader("Content-Type", cType.toString());
                 } catch (ParseException pex) { } // ignore it
             }
@@ -1528,14 +1541,22 @@
                  * satisfy older MUAs (DtMail, Roam and probably
                  * a bunch of others).
                  */
- String s = part.getHeader("Content-Disposition", null);
- if (s != null) {
- // Parse the header ..
- ContentDisposition cd = new ContentDisposition(s);
- String filename = cd.getParameter("filename");
- if (filename != null) {
- cType.setParameter("name", filename);
- type = cType.toString();
+ if (setContentTypeFileName) {
+ String s = part.getHeader("Content-Disposition", null);
+ if (s != null) {
+ // Parse the header ..
+ ContentDisposition cd = new ContentDisposition(s);
+ String filename = cd.getParameter("filename");
+ if (filename != null) {
+ ParameterList p = cType.getParameterList();
+ if (p == null) {
+ p = new ParameterList();
+ cType.setParameterList(p);
+ }
+ p.set("name", filename,
+ MimeUtility.getDefaultMIMECharset());
+ type = cType.toString();
+ }
                     }
                 }
                 

diff -r c2a7b6497852 -r f09bb142c9a4 mail/src/test/java/javax/mail/internet/NonAsciiFileNames.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/javax/mail/internet/NonAsciiFileNames.java Fri Dec 19 16:09:59 2014 -0800
@@ -0,0 +1,102 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2009-2014 Oracle and/or its affiliates. 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_1_1.html
+ * or packager/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 packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [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 org.junit.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test that non-ASCII file names are encoded by default.
+ */
+public class NonAsciiFileNames {
+
+ private static String charset;
+
+ @BeforeClass
+ public static void before() {
+ System.out.println("NonAsciiFileNames");
+ charset = System.getProperty("mail.mime.charset");
+ System.setProperty("mail.mime.charset", "utf-8");
+ }
+
+ /**
+ * Test that non-ASCII filenames are encoded by default.
+ */
+ @Test
+ public void testNonAsciiFileName() throws Exception {
+ MimeBodyPart mbp = new MimeBodyPart();
+ mbp.setText("test\n");
+ mbp.setFileName("test\u00a1\u00a2\u00a3");
+ MimeBodyPart.updateHeaders(mbp);
+
+ String s = mbp.getHeader("Content-Disposition", null);
+ assertTrue("Content-Disposition filename", s.indexOf("filename*") >= 0);
+ s = mbp.getHeader("Content-Type", null);
+ assertTrue("Content-Type name", s.indexOf("name*") >= 0);
+ }
+
+ /**
+ * Test that non-ASCII filenames are encoded by default.
+ * Make sure an existing Content-Type header is updated.
+ */
+ @Test
+ public void testNonAsciiFileNameWithContentType() throws Exception {
+ MimeBodyPart mbp = new MimeBodyPart();
+ mbp.setText("test\n");
+ mbp.setHeader("Content-Type", "text/x-test");
+ mbp.setFileName("test\u00a1\u00a2\u00a3");
+ MimeBodyPart.updateHeaders(mbp);
+
+ String s = mbp.getHeader("Content-Disposition", null);
+ assertTrue("Content-Disposition filename", s.indexOf("filename*") >= 0);
+ s = mbp.getHeader("Content-Type", null);
+ assertTrue("Content-Type name", s.indexOf("name*") >= 0);
+ }
+
+ @AfterClass
+ public static void after() {
+ if (charset == null)
+ System.clearProperty("mail.mime.charset");
+ else
+ System.setProperty("mail.mime.charset", charset);
+ }
+}

diff -r c2a7b6497852 -r f09bb142c9a4 mail/src/test/java/javax/mail/internet/ParameterListTestSuite.java
--- a/mail/src/test/java/javax/mail/internet/ParameterListTestSuite.java Mon Dec 01 14:29:28 2014 -0800
+++ b/mail/src/test/java/javax/mail/internet/ParameterListTestSuite.java Fri Dec 19 16:09:59 2014 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2009-2010 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009-2014 Oracle and/or its affiliates. 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
@@ -55,6 +55,7 @@
     ParameterListTests.class,
     WindowsFileNames.class,
     AppleFileNames.class,
+ NonAsciiFileNames.class,
     DecodeParameters.class,
     ParametersNoStrict.class
 })


diff -r f09bb142c9a4 -r d8558ab3c6ee doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Fri Dec 19 16:09:59 2014 -0800
+++ b/doc/release/CHANGES.txt Fri Jan 16 15:23:52 2015 -0800
@@ -26,6 +26,7 @@
 K 6535 address similar to (x)<y>(z) will throw StringIndexOutOfBoundsException
 K 6551 Update logging demos to use the new 1.5.2 features
 K 6638 attachment filenames aren't being encoded by default
+K 6667 MimeBodyPart with copied DataHandler doesn't always set encoding
 
 
                   CHANGES IN THE 1.5.2 RELEASE

diff -r f09bb142c9a4 -r d8558ab3c6ee mail/src/main/java/javax/mail/internet/MimeBodyPart.java
--- a/mail/src/main/java/javax/mail/internet/MimeBodyPart.java Fri Dec 19 16:09:59 2014 -0800
+++ b/mail/src/main/java/javax/mail/internet/MimeBodyPart.java Fri Jan 16 15:23:52 2015 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. 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
@@ -1491,14 +1491,19 @@
                 MimePartDataHandler mdh = (MimePartDataHandler)dh;
                 MimePart mpart = mdh.getPart();
                 if (mpart != part) {
+ if (needCTHeader)
+ part.setHeader("Content-Type", mpart.getContentType());
                     // XXX - can't change the encoding of the data from the
                     // other part without decoding and reencoding it, so
- // we just force it to match the original
- setEncoding(part, mpart.getEncoding());
- if (needCTHeader)
- part.setHeader("Content-Type", mpart.getContentType());
- }
- return;
+ // we just force it to match the original, but if the
+ // original has no encoding we'll consider reencoding it
+ String enc = mpart.getEncoding();
+ if (enc != null) {
+ setEncoding(part, enc);
+ return;
+ }
+ } else
+ return;
             }
 
             // Content-Transfer-Encoding, but only if we don't
@@ -1599,23 +1604,16 @@
         try {
             /*
              * If the data for this part comes from a stream,
+ * and is already encoded,
              * just copy it to the output stream without decoding
              * and reencoding it.
              */
             DataHandler dh = part.getDataHandler();
             if (dh instanceof MimePartDataHandler) {
- // call getContentStream to give subclass a chance to
- // provide the data on demand
- is = ((MimePartDataHandler)dh).getContentStream();
- /*
- if (part instanceof MimeBodyPart) {
- MimeBodyPart mbp = (MimeBodyPart)part;
- is = mbp.getContentStream();
- } else if (part instanceof MimeMessage) {
- MimeMessage msg = (MimeMessage)part;
- is = msg.getContentStream();
- }
- */
+ MimePartDataHandler mpdh = (MimePartDataHandler)dh;
+ MimePart mpart = mpdh.getPart();
+ if (mpart.getEncoding() != null)
+ is = mpdh.getContentStream();
             }
             if (is != null) {
                 // now copy the data to the output stream

diff -r f09bb142c9a4 -r d8558ab3c6ee mail/src/test/java/javax/mail/internet/MimeBodyPartTest.java
--- a/mail/src/test/java/javax/mail/internet/MimeBodyPartTest.java Fri Dec 19 16:09:59 2014 -0800
+++ b/mail/src/test/java/javax/mail/internet/MimeBodyPartTest.java Fri Jan 16 15:23:52 2015 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011-2015 Oracle and/or its affiliates. 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
@@ -108,7 +108,7 @@
 
     /**
      * Test that copying a DataHandler from one message to another
- * by setting the "dh" filed in a subclass has the desired effect.
+ * by setting the "dh" field in a subclass has the desired effect.
      */
     @Test
     public void testSetDataHandler() throws Exception {
@@ -135,6 +135,37 @@
         assertEquals("test part", getString(mbp.getInputStream()));
     }
 
+ /**
+ * Test that a MimeBodyPart created from a stream with unencoded data
+ * will have the data be encoded when the data is copied to another
+ * MimeBodyPart by copying the DataHandler.
+ */
+ @Test
+ public void testEncodingCopiedDataHandler() throws Exception {
+ String part =
+ "Content-Type: application/x-test\n" +
+ "\n" +
+ "\u0001\u0002\u0003" +
+ "\n";
+ InputStream in = new ByteArrayInputStream(part.getBytes("iso-8859-1"));
+ MimeBodyPart mbp = new MimeBodyPart(in);
+ in.close();
+ MimeBodyPart mbp2 = new MimeBodyPart() {
+ public void setDataHandler(DataHandler dh)
+ throws MessagingException {
+ super.setDataHandler(dh);
+ updateHeaders();
+ }
+ };
+ mbp2.setDataHandler(mbp.getDataHandler());
+ assertEquals("base64", mbp2.getEncoding());
+ // ensure the data is correct by reading the first byte
+ in = mbp2.getInputStream();
+ assertEquals(1, in.read());
+ in.close();
+ }
+
+
     private static MimeMessage createMessage(Session s)
                                 throws MessagingException {
         String content =


diff -r d8558ab3c6ee -r 9cf6ce42613b doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Fri Jan 16 15:23:52 2015 -0800
+++ b/doc/release/CHANGES.txt Fri Jan 16 15:32:44 2015 -0800
@@ -26,6 +26,7 @@
 K 6535 address similar to (x)<y>(z) will throw StringIndexOutOfBoundsException
 K 6551 Update logging demos to use the new 1.5.2 features
 K 6638 attachment filenames aren't being encoded by default
+K 6657 SharedFileInputStream has problems with 2GB+ files
 K 6667 MimeBodyPart with copied DataHandler doesn't always set encoding
 
 

diff -r d8558ab3c6ee -r 9cf6ce42613b mail/src/main/java/javax/mail/util/SharedFileInputStream.java
--- a/mail/src/main/java/javax/mail/util/SharedFileInputStream.java Fri Jan 16 15:23:52 2015 -0800
+++ b/mail/src/main/java/javax/mail/util/SharedFileInputStream.java Fri Jan 16 15:32:44 2015 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. 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
@@ -516,7 +516,7 @@
         if (end == -1)
             end = datalen;
         return new SharedFileInputStream(sf,
- this.start + (int)start, (int)(end - start), bufsize);
+ this.start + start, end - start, bufsize);
     }
 
     // for testing...


diff -r 9cf6ce42613b -r 67a74046792b mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Fri Jan 16 15:32:44 2015 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Fri Jan 16 15:35:36 2015 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. 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
@@ -1970,7 +1970,7 @@
                      * to fetch them from the server.
                      *
                      * Assume the common case is that the messages are
- * in in order by UID. Map the returned source
+ * in order by UID. Map the returned source
                      * UIDs to their corresponding Message objects.
                      * Step through the msgs array looking for the
                      * Message object in the returned source message
@@ -1990,19 +1990,6 @@
                     // XXX - could inline/optimize this
                     Message[] srcmsgs = getMessagesByUID(srcuids);
                     AppendUID[] result = new AppendUID[msgs.length];
- for (int i = 0; i < srcmsgs.length; i++) {
- int j = i;
- do {
- if (msgs[j] == srcmsgs[i]) {
- result[j] = new AppendUID(
- cuid.uidvalidity, dstuids[i]);
- break;
- }
- j++;
- if (j >= msgs.length)
- j = 0;
- } while (j != i);
- }
                     for (int i = 0; i < msgs.length; i++) {
                         int j = i;
                         do {
@@ -2012,7 +1999,7 @@
                                 break;
                             }
                             j++;
- if (j >= msgs.length)
+ if (j >= srcmsgs.length)
                                 j = 0;
                         } while (j != i);
                     }


diff -r 67a74046792b -r 9e42fb16000d doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Fri Jan 16 15:35:36 2015 -0800
+++ b/doc/release/CHANGES.txt Fri Jan 16 16:08:09 2015 -0800
@@ -28,6 +28,7 @@
 K 6638 attachment filenames aren't being encoded by default
 K 6657 SharedFileInputStream has problems with 2GB+ files
 K 6667 MimeBodyPart with copied DataHandler doesn't always set encoding
+K 6668 skip unusable Store and Transport classes
 
 
                   CHANGES IN THE 1.5.2 RELEASE

diff -r 67a74046792b -r 9e42fb16000d mail/src/main/java/javax/mail/Session.java
--- a/mail/src/main/java/javax/mail/Session.java Fri Jan 16 15:35:36 2015 -0800
+++ b/mail/src/main/java/javax/mail/Session.java Fri Jan 16 16:08:09 2015 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. 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
@@ -587,12 +587,8 @@
         if (provider == null || provider.getType() != Provider.Type.STORE ) {
             throw new NoSuchProviderException("invalid provider");
         }
-
- try {
- return (Store) getService(provider, url);
- } catch (ClassCastException cce) {
- throw new NoSuchProviderException("incorrect class");
- }
+
+ return getService(provider, url, Store.class);
     }
 
     /**
@@ -738,11 +734,7 @@
             throw new NoSuchProviderException("invalid provider");
         }
 
- try {
- return (Transport) getService(provider, url);
- } catch (ClassCastException cce) {
- throw new NoSuchProviderException("incorrect class");
- }
+ return getService(provider, url, Transport.class);
     }
 
     /**
@@ -752,12 +744,14 @@
      *
      * @param provider which provider to use
      * @param url which URLName to use (can be null)
+ * @param type the service type (class)
      * @exception NoSuchProviderException thrown when the class cannot be
      * found or when it does not have the correct constructor
      * (Session, URLName), or if it is not derived from
      * Service.
      */
- private Object getService(Provider provider, URLName url)
+ private <T extends Service> T getService(Provider provider, URLName url,
+ Class<T> type)
                                         throws NoSuchProviderException {
         // need a provider and url
         if (provider == null) {
@@ -791,15 +785,22 @@
                 } catch (ClassNotFoundException ex) {
                     // ignore it
                 }
- if (serviceClass == null)
+ if (serviceClass == null || !type.isAssignableFrom(serviceClass))
                 serviceClass =
                     Class.forName(provider.getClassName(), false, cl);
+
+ if (!type.isAssignableFrom(serviceClass))
+ throw new ClassCastException(
+ type.getName() + " " + serviceClass.getName());
         } catch (Exception ex1) {
             // That didn't work, now try the "system" class loader.
             // (Need both of these because JDK 1.1 class loaders
             // may not delegate to their parent class loader.)
             try {
                 serviceClass = Class.forName(provider.getClassName());
+ if (!type.isAssignableFrom(serviceClass))
+ throw new ClassCastException(
+ type.getName() + " " + serviceClass.getName());
             } catch (Exception ex) {
                 // Nothing worked, give up.
                 logger.log(Level.FINE, "Exception loading provider", ex);
@@ -820,7 +821,7 @@
             throw new NoSuchProviderException(provider.getProtocol());
         }
 
- return service;
+ return type.cast(service);
     }
 
     /**