commits@javamail.java.net

[javamail~mercurial:599] don't swallow error if crypto fails to initialize for NTLM

From: <shannon_at_java.net>
Date: Mon, 7 Oct 2013 23:23:30 +0000

Project: javamail
Repository: mercurial
Revision: 599
Author: shannon
Date: 2013-10-04 23:21:20 UTC
Link:

Log Message:
------------
Unfold address headers before parsing - bug 6102
Account for header length when folding address headers.
Allow use of XGWTRUSTEDAPP with no authzid and thus no LOGIN - bug 6108
support empty IMAP ENVELOPE address list instead of NIL - bug 6125
Replace Vector with List.
add test case for bug 6125
don't swallow error if crypto fails to initialize for NTLM


Revisions:
----------
593
594
595
596
597
598
599


Modified Paths:
---------------
doc/release/CHANGES.txt
mail/src/main/java/javax/mail/internet/InternetAddress.java
mail/src/test/resources/javax/mail/internet/addrlist
mail/src/main/java/javax/mail/internet/MimeMessage.java
mail/src/test/java/javax/mail/internet/MimeMessageTest.java
mail/src/main/java/com/sun/mail/imap/protocol/IMAPSaslAuthenticator.java
mail/src/main/java/com/sun/mail/imap/protocol/ENVELOPE.java
mail/src/main/java/com/sun/mail/imap/protocol/BODYSTRUCTURE.java
mail/src/main/java/com/sun/mail/imap/protocol/FetchResponse.java
mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java
mail/src/main/java/com/sun/mail/imap/protocol/IMAPResponse.java
mail/src/main/java/com/sun/mail/imap/protocol/ListInfo.java
mail/src/main/java/com/sun/mail/imap/protocol/MessageSet.java
mail/src/main/java/com/sun/mail/imap/protocol/Namespaces.java
mail/src/test/java/com/sun/mail/imap/protocol/EnvelopeTest.java
mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java


Diffs:
------
diff -r ed574b6f53ad -r 7ceab621029c doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Tue Sep 10 13:43:27 2013 -0700
+++ b/doc/release/CHANGES.txt Mon Sep 16 13:16:52 2013 -0700
@@ -27,6 +27,7 @@
 K 5989 Empty FROM Field causes Exception
 K 6004 Filename isn't parsed correctly if charset is not set
 K 6072 copying a DataHandler from a parsed message to a new message fails
+K 6102 MimeMessage does not unfold address headers before parsing them
 
 
                   CHANGES IN THE 1.5.0 RELEASE

diff -r ed574b6f53ad -r 7ceab621029c mail/src/main/java/javax/mail/internet/InternetAddress.java
--- a/mail/src/main/java/javax/mail/internet/InternetAddress.java Tue Sep 10 13:43:27 2013 -0700
+++ b/mail/src/main/java/javax/mail/internet/InternetAddress.java Mon Sep 16 13:16:52 2013 -0700
@@ -655,7 +655,7 @@
      */
     public static InternetAddress[] parseHeader(String addresslist,
                                 boolean strict) throws AddressException {
- return parse(addresslist, strict, true);
+ return parse(MimeUtility.unfold(addresslist), strict, true);
     }
 
     /*

diff -r ed574b6f53ad -r 7ceab621029c mail/src/test/resources/javax/mail/internet/addrlist
--- a/mail/src/test/resources/javax/mail/internet/addrlist Tue Sep 10 13:43:27 2013 -0700
+++ b/mail/src/test/resources/javax/mail/internet/addrlist Mon Sep 16 13:16:52 2013 -0700
@@ -310,6 +310,12 @@
 To: "john doe" (john.doe_at_a.com)
 Expect: 1
         john.doe_at_a.com
+Comment: test that headers are unfolded before parsing
+To: "John
+ Smith" <jsmith@
+ crappy-email-archiving-company.com>
+Expect: 1
+ jsmith@ crappy-email-archiving-company.com
 Header: false
 To: (Test) <djoe_at_zimbra.com>,djoe_at_zimbra.com (Test)
 Expect: 2
@@ -739,9 +745,7 @@
         streetwalker!from, streetwalker!id, streetwalker!oak.sunecd.com,
         streetwalker!root, streetwalker!rr, streetwalker!streetwalker.sun.com
 Expect: 24
- 55:55_at_07, 57:18_at_07, 36:39_at_10, 36:42_at_10, streetwalker!1987, streetwalker!5,\
- streetwalker!87, <8710051455.AA08484_at_oak.sunecd.com>, <oak!kinnear>,\
- streetwalker!AA00159;
+ 55:55_at_07, 57:18_at_07, 36:39_at_10, 36:42_at_10, streetwalker!1987, streetwalker!5, streetwalker!87, <8710051455.AA08484_at_oak.sunecd.com>, <oak!kinnear>, streetwalker!AA00159;
         streetwalker!AA08484
         streetwalker!AA16178
         streetwalker!Date:


diff -r 7ceab621029c -r f3321df4baeb mail/src/main/java/javax/mail/internet/MimeMessage.java
--- a/mail/src/main/java/javax/mail/internet/MimeMessage.java Mon Sep 16 13:16:52 2013 -0700
+++ b/mail/src/main/java/javax/mail/internet/MimeMessage.java Mon Sep 16 13:17:20 2013 -0700
@@ -731,7 +731,7 @@
     // Convenience method to set addresses
     private void setAddressHeader(String name, Address[] addresses)
                         throws MessagingException {
- String s = InternetAddress.toString(addresses);
+ String s = InternetAddress.toString(addresses, name.length() + 2);
         if (s == null)
             removeHeader(name);
         else
@@ -751,7 +751,7 @@
             System.arraycopy(a, 0, anew, 0, a.length);
             System.arraycopy(addresses, 0, anew, a.length, addresses.length);
         }
- String s = InternetAddress.toString(anew);
+ String s = InternetAddress.toString(anew, name.length() + 2);
         if (s == null)
             return;
         setHeader(name, s);

diff -r 7ceab621029c -r f3321df4baeb mail/src/test/java/javax/mail/internet/MimeMessageTest.java
--- a/mail/src/test/java/javax/mail/internet/MimeMessageTest.java Mon Sep 16 13:16:52 2013 -0700
+++ b/mail/src/test/java/javax/mail/internet/MimeMessageTest.java Mon Sep 16 13:17:20 2013 -0700
@@ -42,6 +42,7 @@
 
 import java.io.*;
 import java.util.Properties;
+import java.util.Enumeration;
 
 import javax.activation.DataHandler;
 
@@ -50,6 +51,7 @@
 
 import org.junit.*;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test MimeMessage methods.
@@ -98,7 +100,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 {
@@ -117,6 +119,24 @@
         assertEquals("test message", getString(msg.getInputStream()));
     }
 
+ /**
+ * Test that address headers account for the header length when folding.
+ */
+ @Test
+ public void testAddressHeaderFolding() throws Exception {
+ Session s = Session.getInstance(new Properties());
+ MimeMessage msg = new MimeMessage(s);
+ InternetAddress[] addrs = InternetAddress.parse(
+ "long-address1_at_example.com, long-address2_at_example.com, joe_at_foobar.com");
+ msg.setReplyTo(addrs); // use Reply-To because it's a long header name
+ Enumeration e = msg.getMatchingHeaderLines(new String[] { "Reply-To" });
+ String line = (String)e.nextElement();
+ int npos = line.indexOf("\r");
+ // was the line folded where we expected?
+ assertTrue("Header folded",
+ npos > 9 && npos <= 77 && npos < line.length());
+ }
+
     private static MimeMessage createMessage(Session s)
                                 throws MessagingException {
         String content =


diff -r f3321df4baeb -r ebd991ba733b doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Mon Sep 16 13:17:20 2013 -0700
+++ b/doc/release/CHANGES.txt Wed Oct 02 13:33:55 2013 -0700
@@ -28,6 +28,8 @@
 K 6004 Filename isn't parsed correctly if charset is not set
 K 6072 copying a DataHandler from a parsed message to a new message fails
 K 6102 MimeMessage does not unfold address headers before parsing them
+K 6108 When using XGWTRUSTEDAPP mechanism, LOGIN should not be issued if no
+ authzid is specified
 
 
                   CHANGES IN THE 1.5.0 RELEASE

diff -r f3321df4baeb -r ebd991ba733b mail/src/main/java/com/sun/mail/imap/protocol/IMAPSaslAuthenticator.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/IMAPSaslAuthenticator.java Mon Sep 16 13:17:20 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/IMAPSaslAuthenticator.java Wed Oct 02 13:33:55 2013 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2013 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
@@ -168,6 +168,8 @@
         byte[] CRLF = { (byte)'\r', (byte)'\n'};
 
         // Hack for Novell GroupWise XGWTRUSTEDAPP authentication mechanism
+ // http://www.novell.com/developer/documentation/gwimap/?
+ // page=/developer/documentation/gwimap/gwimpenu/data/al7te9j.html
         boolean isXGWTRUSTEDAPP =
             sc.getMechanismName().equals("XGWTRUSTEDAPP") &&
             PropUtil.getBooleanProperty(props,
@@ -248,12 +250,12 @@
 
         /*
          * If we're using the Novell Groupwise XGWTRUSTEDAPP mechanism
- * we always have to issue a LOGIN command to select the user
- * we want to operate as.
+ * to run as a specified authorization ID, we have to issue a
+ * LOGIN command to select the user we want to operate as.
          */
- if (isXGWTRUSTEDAPP) {
+ if (isXGWTRUSTEDAPP && authzid != null) {
             Argument args = new Argument();
- args.writeString(authzid != null ? authzid : u);
+ args.writeString(authzid);
 
             responses = pr.command("LOGIN", args);
 


diff -r ebd991ba733b -r 8146d69ec23a doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Wed Oct 02 13:33:55 2013 -0700
+++ b/doc/release/CHANGES.txt Wed Oct 02 13:39:10 2013 -0700
@@ -30,6 +30,7 @@
 K 6102 MimeMessage does not unfold address headers before parsing them
 K 6108 When using XGWTRUSTEDAPP mechanism, LOGIN should not be issued if no
         authzid is specified
+K 6125 support empty IMAP ENVELOPE address list instead of NIL
 
 
                   CHANGES IN THE 1.5.0 RELEASE

diff -r ebd991ba733b -r 8146d69ec23a mail/src/main/java/com/sun/mail/imap/protocol/ENVELOPE.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/ENVELOPE.java Wed Oct 02 13:33:55 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/ENVELOPE.java Wed Oct 02 13:39:10 2013 -0700
@@ -118,6 +118,16 @@
 
         byte b = r.readByte();
         if (b == '(') {
+ /*
+ * Some broken servers (e.g., Yahoo Mail) return an empty
+ * list instead of NIL. Handle that here even though it
+ * doesn't conform to the IMAP spec.
+ */
+ if (r.peekByte() == ')') {
+ r.skip(1);
+ return null;
+ }
+
             Vector v = new Vector();
 
             do {


diff -r 8146d69ec23a -r bb765b7a2f3a mail/src/main/java/com/sun/mail/imap/protocol/BODYSTRUCTURE.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/BODYSTRUCTURE.java Wed Oct 02 13:39:10 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/BODYSTRUCTURE.java Wed Oct 02 15:12:32 2013 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2013 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
@@ -40,7 +40,8 @@
 
 package com.sun.mail.imap.protocol;
 
-import java.util.Vector;
+import java.util.List;
+import java.util.ArrayList;
 import javax.mail.internet.ParameterList;
 import com.sun.mail.iap.*;
 import com.sun.mail.util.PropUtil;
@@ -103,10 +104,10 @@
                 System.out.println("DEBUG IMAP: parsing multipart");
             type = "multipart";
             processedType = MULTI;
- Vector v = new Vector(1);
+ List<BODYSTRUCTURE> v = new ArrayList<BODYSTRUCTURE>(1);
             int i = 1;
             do {
- v.addElement(new BODYSTRUCTURE(r));
+ v.add(new BODYSTRUCTURE(r));
                 /*
                  * Even though the IMAP spec says there can't be any spaces
                  * between parts, some servers erroneously put a space in
@@ -117,8 +118,7 @@
             } while (r.peekByte() == '(');
 
             // setup bodies.
- bodies = new BODYSTRUCTURE[v.size()];
- v.copyInto(bodies);
+ bodies = v.toArray(new BODYSTRUCTURE[v.size()]);
 
             subtype = r.readString(); // subtype
             if (parseDebug)

diff -r 8146d69ec23a -r bb765b7a2f3a mail/src/main/java/com/sun/mail/imap/protocol/ENVELOPE.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/ENVELOPE.java Wed Oct 02 13:39:10 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/ENVELOPE.java Wed Oct 02 15:12:32 2013 -0700
@@ -40,7 +40,8 @@
 
 package com.sun.mail.imap.protocol;
 
-import java.util.Vector;
+import java.util.List;
+import java.util.ArrayList;
 import java.util.Date;
 import java.io.UnsupportedEncodingException;
 import java.text.ParseException;
@@ -128,21 +129,19 @@
                 return null;
             }
 
- Vector v = new Vector();
+ List<InternetAddress> v = new ArrayList<InternetAddress>();
 
             do {
                 IMAPAddress a = new IMAPAddress(r);
                 // if we see an end-of-group address at the top, ignore it
                 if (!a.isEndOfGroup())
- v.addElement(a);
+ v.add(a);
             } while (r.peekByte() != ')');
 
             // skip the terminating ')' at the end of the addresslist
             r.skip(1);
 
- InternetAddress[] a = new InternetAddress[v.size()];
- v.copyInto(a);
- return a;
+ return v.toArray(new InternetAddress[v.size()]);
         } else if (b == 'N' || b == 'n') { // NIL
             r.skip(2); // skip 'NIL'
             return null;
@@ -182,11 +181,11 @@
             if (groupname == null) // end of group list
                 return;
             // Accumulate a group list. The members of the group
- // are accumulated in a Vector and the corresponding string
+ // are accumulated in a List and the corresponding string
             // representation of the group is accumulated in a StringBuffer.
             StringBuffer sb = new StringBuffer();
             sb.append(groupname).append(':');
- Vector v = new Vector();
+ List<InternetAddress> v = new ArrayList<InternetAddress>();
             while (r.peekByte() != ')') {
                 IMAPAddress a = new IMAPAddress(r);
                 if (a.isEndOfGroup()) // reached end of group
@@ -194,12 +193,11 @@
                 if (v.size() != 0) // if not first element, need a comma
                     sb.append(',');
                 sb.append(a.toString());
- v.addElement(a);
+ v.add(a);
             }
             sb.append(';');
             address = sb.toString();
- grouplist = new IMAPAddress[v.size()];
- v.copyInto(grouplist);
+ grouplist = v.toArray(new IMAPAddress[v.size()]);
         } else {
             if (mb == null || mb.length() == 0)
                 address = host;

diff -r 8146d69ec23a -r bb765b7a2f3a mail/src/main/java/com/sun/mail/imap/protocol/FetchResponse.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/FetchResponse.java Wed Oct 02 13:39:10 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/FetchResponse.java Wed Oct 02 15:12:32 2013 -0700
@@ -153,7 +153,7 @@
             throw new ParsingException(
                 "error in FETCH parsing, missing '(' at index " + index);
 
- Vector v = new Vector();
+ List<Item> v = new ArrayList<Item>();
         Item i = null;
         do {
             index++; // skip '(', or SPACE
@@ -164,15 +164,14 @@
 
             i = parseItem();
             if (i != null)
- v.addElement(i);
+ v.add(i);
             else if (!parseExtensionItem())
                 throw new ParsingException(
                 "error in FETCH parsing, unrecognized item at index " + index);
         } while (buffer[index] != ')');
 
         index++; // skip ')'
- items = new Item[v.size()];
- v.copyInto(items);
+ items = v.toArray(new Item[v.size()]);
     }
 
     /**

diff -r 8146d69ec23a -r bb765b7a2f3a mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java Wed Oct 02 13:39:10 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java Wed Oct 02 15:12:32 2013 -0700
@@ -403,7 +403,7 @@
      */
     public synchronized void authlogin(String u, String p)
                                 throws ProtocolException {
- Vector v = new Vector();
+ List<Response> v = new ArrayList<Response>();
         String tag = null;
         Response r = null;
         boolean done = false;
@@ -471,7 +471,7 @@
                 else if (r.isBYE()) // outta here
                     done = true;
                 else // hmm .. unsolicited response here ?!
- v.addElement(r);
+ v.add(r);
             } catch (Exception ioex) {
                 // convert this into a BYE response
                 r = Response.byeResponse(ioex);
@@ -489,8 +489,7 @@
          * connection has been authenticated. So, for now, the below
          * code really ends up being just a no-op.
          */
- Response[] responses = new Response[v.size()];
- v.copyInto(responses);
+ Response[] responses = v.toArray(new Response[v.size()]);
         notifyResponseHandlers(responses);
 
         // Handle the final OK, NO, BAD or BYE response
@@ -518,7 +517,7 @@
      */
     public synchronized void authplain(String authzid, String u, String p)
                                 throws ProtocolException {
- Vector v = new Vector();
+ List<Response> v = new ArrayList<Response>();
         String tag = null;
         Response r = null;
         boolean done = false;
@@ -582,7 +581,7 @@
                 else if (r.isBYE()) // outta here
                     done = true;
                 else // hmm .. unsolicited response here ?!
- v.addElement(r);
+ v.add(r);
             } catch (Exception ioex) {
                 // convert this into a BYE response
                 r = Response.byeResponse(ioex);
@@ -600,8 +599,7 @@
          * connection has been authenticated. So, for now, the below
          * code really ends up being just a no-op.
          */
- Response[] responses = new Response[v.size()];
- v.copyInto(responses);
+ Response[] responses = v.toArray(new Response[v.size()]);
         notifyResponseHandlers(responses);
 
         // Handle the final OK, NO, BAD or BYE response
@@ -628,7 +626,7 @@
      */
     public synchronized void authntlm(String authzid, String u, String p)
                                 throws ProtocolException {
- Vector v = new Vector();
+ List<Response> v = new ArrayList<Response>();
         String tag = null;
         Response r = null;
         boolean done = false;
@@ -680,7 +678,7 @@
                 else if (r.isBYE()) // outta here
                     done = true;
                 else // hmm .. unsolicited response here ?!
- v.addElement(r);
+ v.add(r);
             } catch (Exception ioex) {
                 // convert this into a BYE response
                 r = Response.byeResponse(ioex);
@@ -699,8 +697,7 @@
          * connection has been authenticated. So, for now, the below
          * code really ends up being just a no-op.
          */
- Response[] responses = new Response[v.size()];
- v.copyInto(responses);
+ Response[] responses = v.toArray(new Response[v.size()]);
         notifyResponseHandlers(responses);
 
         // Handle the final OK, NO, BAD or BYE response
@@ -1203,20 +1200,19 @@
         Response response = r[r.length-1];
 
         if (response.isOK()) { // command succesful
- Vector v = new Vector(1);
+ List<ListInfo> v = new ArrayList<ListInfo>(1);
             for (int i = 0, len = r.length; i < len; i++) {
                 if (!(r[i] instanceof IMAPResponse))
                     continue;
 
                 IMAPResponse ir = (IMAPResponse)r[i];
                 if (ir.keyEquals(cmd)) {
- v.addElement(new ListInfo(ir));
+ v.add(new ListInfo(ir));
                     r[i] = null;
                 }
             }
             if (v.size() > 0) {
- linfo = new ListInfo[v.size()];
- v.copyInto(linfo);
+ linfo = v.toArray(new ListInfo[v.size()]);
             }
         }
         
@@ -1612,22 +1608,20 @@
                              "UID", true);
 
         UID u;
- Vector v = new Vector();
+ List<UID> v = new ArrayList<UID>();
         for (int i = 0, len = r.length; i < len; i++) {
             if (r[i] == null || !(r[i] instanceof FetchResponse))
                 continue;
             
             FetchResponse fr = (FetchResponse)r[i];
             if ((u = fr.getItem(UID.class)) != null)
- v.addElement(u);
+ v.add(u);
         }
                 
         notifyResponseHandlers(r);
         handleResult(r[r.length-1]);
 
- UID[] ua = new UID[v.size()];
- v.copyInto(ua);
- return ua;
+ return v.toArray(new UID[v.size()]);
     }
 
     /**
@@ -1646,22 +1640,20 @@
         Response[] r = fetch(sb.toString(), "UID", true);
 
         UID u;
- Vector v = new Vector();
+ List<UID> v = new ArrayList<UID>();
         for (int i = 0, len = r.length; i < len; i++) {
             if (r[i] == null || !(r[i] instanceof FetchResponse))
                 continue;
             
             FetchResponse fr = (FetchResponse)r[i];
             if ((u = fr.getItem(UID.class)) != null)
- v.addElement(u);
+ v.add(u);
         }
                 
         notifyResponseHandlers(r);
         handleResult(r[r.length-1]);
 
- UID[] ua = new UID[v.size()];
- v.copyInto(ua);
- return ua;
+ return v.toArray(new UID[v.size()]);
     }
 
     /**
@@ -1988,7 +1980,7 @@
 
         // Grab all SEARCH responses
         if (response.isOK()) { // command succesful
- Vector v = new Vector();
+ List<Integer> v = new ArrayList<Integer>();
             int num;
             for (int i = 0, len = r.length; i < len; i++) {
                 if (!(r[i] instanceof IMAPResponse))
@@ -1998,7 +1990,7 @@
                 // There *will* be one SEARCH response.
                 if (ir.keyEquals("SEARCH")) {
                     while ((num = ir.readNumber()) != -1)
- v.addElement(Integer.valueOf(num));
+ v.add(Integer.valueOf(num));
                     r[i] = null;
                 }
             }
@@ -2007,7 +1999,7 @@
             int vsize = v.size();
             matches = new int[vsize];
             for (int i = 0; i < vsize; i++)
- matches[i] = ((Integer)v.elementAt(i)).intValue();
+ matches[i] = v.get(i).intValue();
         }
 
         // dispatch remaining untagged responses
@@ -2077,7 +2069,7 @@
 
         // Grab all SORT responses
         if (response.isOK()) { // command succesful
- Vector v = new Vector();
+ List<Integer> v = new ArrayList<Integer>();
             int num;
             for (int i = 0, len = r.length; i < len; i++) {
                 if (!(r[i] instanceof IMAPResponse))
@@ -2086,7 +2078,7 @@
                 IMAPResponse ir = (IMAPResponse)r[i];
                 if (ir.keyEquals("SORT")) {
                     while ((num = ir.readNumber()) != -1)
- v.addElement(Integer.valueOf(num));
+ v.add(Integer.valueOf(num));
                     r[i] = null;
                 }
             }
@@ -2095,7 +2087,7 @@
             int vsize = v.size();
             matches = new int[vsize];
             for (int i = 0; i < vsize; i++)
- matches[i] = ((Integer)v.elementAt(i)).intValue();
+ matches[i] = v.get(i).intValue();
         }
 
         // dispatch remaining untagged responses
@@ -2231,7 +2223,7 @@
         Response[] r = command("GETQUOTA", args);
 
         Quota quota = null;
- Vector v = new Vector();
+ List<Quota> v = new ArrayList<Quota>();
         Response response = r[r.length-1];
 
         // Grab all QUOTA responses
@@ -2243,7 +2235,7 @@
                 IMAPResponse ir = (IMAPResponse)r[i];
                 if (ir.keyEquals("QUOTA")) {
                     quota = parseQuota(ir);
- v.addElement(quota);
+ v.add(quota);
                     r[i] = null;
                 }
             }
@@ -2252,9 +2244,7 @@
         // dispatch remaining untagged responses
         notifyResponseHandlers(r);
         handleResult(response);
- Quota[] qa = new Quota[v.size()];
- v.copyInto(qa);
- return qa;
+ return v.toArray(new Quota[v.size()]);
     }
 
     /**
@@ -2288,7 +2278,7 @@
 
         /*
         Quota quota = null;
- Vector v = new Vector();
+ List<Quota> v = new ArrayList<Quota>();
 
         // Grab all QUOTA responses
         if (response.isOK()) { // command succesful
@@ -2299,7 +2289,7 @@
                 IMAPResponse ir = (IMAPResponse)r[i];
                 if (ir.keyEquals("QUOTA")) {
                     quota = parseQuota(ir);
- v.addElement(quota);
+ v.add(quota);
                     r[i] = null;
                 }
             }
@@ -2310,9 +2300,7 @@
         notifyResponseHandlers(r);
         handleResult(response);
         /*
- Quota[] qa = new Quota[v.size()];
- v.copyInto(qa);
- return qa;
+ return v.toArray(new Quota[v.size()]);
         */
     }
 
@@ -2328,7 +2316,7 @@
         if (r.readByte() != '(')
             throw new ParsingException("parse error in QUOTA");
 
- Vector v = new Vector();
+ List<Quota.Resource> v = new ArrayList<Quota.Resource>();
         while (r.peekByte() != ')') {
             // quota_resource ::= atom SP number SP number
             String name = r.readAtom();
@@ -2336,12 +2324,11 @@
                 long usage = r.readLong();
                 long limit = r.readLong();
                 Quota.Resource res = new Quota.Resource(name, usage, limit);
- v.addElement(res);
+ v.add(res);
             }
         }
         r.readByte();
- q.resources = new Quota.Resource[v.size()];
- v.copyInto(q.resources);
+ q.resources = v.toArray(new Quota.Resource[v.size()]);
         return q;
     }
 
@@ -2418,7 +2405,7 @@
         Response response = r[r.length-1];
 
         // Grab all ACL responses
- Vector v = new Vector();
+ List<ACL> v = new ArrayList<ACL>();
         if (response.isOK()) { // command succesful
             for (int i = 0, len = r.length; i < len; i++) {
                 if (!(r[i] instanceof IMAPResponse))
@@ -2436,7 +2423,7 @@
                         if (rights == null)
                             break;
                         ACL acl = new ACL(name, new Rights(rights));
- v.addElement(acl);
+ v.add(acl);
                     }
                     r[i] = null;
                 }
@@ -2446,9 +2433,7 @@
         // dispatch remaining untagged responses
         notifyResponseHandlers(r);
         handleResult(response);
- ACL[] aa = new ACL[v.size()];
- v.copyInto(aa);
- return aa;
+ return v.toArray(new ACL[v.size()]);
     }
 
     /**
@@ -2472,7 +2457,7 @@
         Response response = r[r.length-1];
 
         // Grab LISTRIGHTS response
- Vector v = new Vector();
+ List<Rights> v = new ArrayList<Rights>();
         if (response.isOK()) { // command succesful
             for (int i = 0, len = r.length; i < len; i++) {
                 if (!(r[i] instanceof IMAPResponse))
@@ -2488,7 +2473,7 @@
                     ir.readAtomString();
                     String rights;
                     while ((rights = ir.readAtomString()) != null)
- v.addElement(new Rights(rights));
+ v.add(new Rights(rights));
                     r[i] = null;
                 }
             }
@@ -2497,9 +2482,7 @@
         // dispatch remaining untagged responses
         notifyResponseHandlers(r);
         handleResult(response);
- Rights[] ra = new Rights[v.size()];
- v.copyInto(ra);
- return ra;
+ return v.toArray(new Rights[v.size()]);
     }
 
     /**
@@ -2573,7 +2556,7 @@
         if (!hasCapability("IDLE"))
             throw new BadCommandException("IDLE not supported");
 
- Vector v = new Vector();
+ List<Response> v = new ArrayList<Response>();
         boolean done = false;
         Response r = null;
 
@@ -2581,11 +2564,11 @@
         try {
             idleTag = writeCommand("IDLE", null);
         } catch (LiteralException lex) {
- v.addElement(lex.getResponse());
+ v.add(lex.getResponse());
             done = true;
         } catch (Exception ex) {
             // Convert this into a BYE response
- v.addElement(Response.byeResponse(ex));
+ v.add(Response.byeResponse(ex));
             done = true;
         }
 
@@ -2599,14 +2582,13 @@
                 continue; // skip this response
             }
 
- v.addElement(r);
+ v.add(r);
 
             if (r.isContinuation() || r.isBYE())
                 done = true;
         }
 
- Response[] responses = new Response[v.size()];
- v.copyInto(responses);
+ Response[] responses = v.toArray(new Response[v.size()]);
         r = responses[responses.length-1];
 
         // dispatch remaining untagged responses

diff -r 8146d69ec23a -r bb765b7a2f3a mail/src/main/java/com/sun/mail/imap/protocol/IMAPResponse.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/IMAPResponse.java Wed Oct 02 13:39:10 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/IMAPResponse.java Wed Oct 02 15:12:32 2013 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2013 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
@@ -104,24 +104,22 @@
             return null;
         index++; // skip '('
 
- Vector v = new Vector();
+ List<String> v = new ArrayList<String>();
         int start;
         for (start = index; buffer[index] != ')'; index++) {
             if (buffer[index] == ' ') { // got one item
- v.addElement(ASCIIUtility.toString(buffer, start, index));
+ v.add(ASCIIUtility.toString(buffer, start, index));
                 start = index+1; // index gets incremented at the top
             }
         }
         if (index > start) // get the last item
- v.addElement(ASCIIUtility.toString(buffer, start, index));
+ v.add(ASCIIUtility.toString(buffer, start, index));
         index++; // skip ')'
         
         int size = v.size();
- if (size > 0) {
- String[] s = new String[size];
- v.copyInto(s);
- return s;
- } else // empty list
+ if (size > 0)
+ return v.toArray(new String[size]);
+ else // empty list
             return null;
     }
 

diff -r 8146d69ec23a -r bb765b7a2f3a mail/src/main/java/com/sun/mail/imap/protocol/IMAPSaslAuthenticator.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/IMAPSaslAuthenticator.java Wed Oct 02 13:39:10 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/IMAPSaslAuthenticator.java Wed Oct 02 15:12:32 2013 -0700
@@ -78,7 +78,7 @@
                                 final String p) throws ProtocolException {
 
         synchronized (pr) { // authenticate method should be synchronized
- Vector v = new Vector();
+ List<Response> v = new ArrayList<Response>();
         String tag = null;
         Response r = null;
         boolean done = false;
@@ -213,7 +213,7 @@
                 else if (r.isBYE()) // outta here
                     done = true;
                 else // hmm .. unsolicited response here ?!
- v.addElement(r);
+ v.add(r);
             } catch (Exception ioex) {
                 logger.log(Level.FINE, "SASL Exception", ioex);
                 // convert this into a BYE response
@@ -240,8 +240,7 @@
          * connection has been authenticated. So, for now, the below
          * code really ends up being just a no-op.
          */
- Response[] responses = new Response[v.size()];
- v.copyInto(responses);
+ Response[] responses = v.toArray(new Response[v.size()]);
         pr.notifyResponseHandlers(responses);
 
         // Handle the final OK, NO, BAD or BYE response

diff -r 8146d69ec23a -r bb765b7a2f3a mail/src/main/java/com/sun/mail/imap/protocol/ListInfo.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/ListInfo.java Wed Oct 02 13:39:10 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/ListInfo.java Wed Oct 02 15:12:32 2013 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2013 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
@@ -40,7 +40,8 @@
 
 package com.sun.mail.imap.protocol;
 
-import java.util.Vector;
+import java.util.List;
+import java.util.ArrayList;
 
 import com.sun.mail.iap.*;
 
@@ -66,7 +67,7 @@
     public ListInfo(IMAPResponse r) throws ParsingException {
         String[] s = r.readSimpleList();
 
- Vector v = new Vector(); // accumulate attributes
+ List<String> v = new ArrayList<String>(); // accumulate attributes
         if (s != null) {
             // non-empty attribute list
             for (int i = 0; i < s.length; i++) {
@@ -78,11 +79,10 @@
                     canOpen = false;
                 else if (s[i].equalsIgnoreCase("\\Noinferiors"))
                     hasInferiors = false;
- v.addElement(s[i]);
+ v.add(s[i]);
             }
         }
- attrs = new String[v.size()];
- v.copyInto(attrs);
+ attrs = v.toArray(new String[v.size()]);
 
         r.skipSpaces();
         if (r.readByte() == '"') {

diff -r 8146d69ec23a -r bb765b7a2f3a mail/src/main/java/com/sun/mail/imap/protocol/MessageSet.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/MessageSet.java Wed Oct 02 13:39:10 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/MessageSet.java Wed Oct 02 15:12:32 2013 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2013 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
@@ -40,7 +40,8 @@
 
 package com.sun.mail.imap.protocol;
 
-import java.util.Vector;
+import java.util.List;
+import java.util.ArrayList;
 
 /**
  * This class holds the 'start' and 'end' for a range of messages
@@ -68,7 +69,7 @@
      * Convert an array of integers into an array of MessageSets
      */
     public static MessageSet[] createMessageSets(int[] msgs) {
- Vector v = new Vector();
+ List<MessageSet> v = new ArrayList<MessageSet>();
         int i,j;
 
         for (i=0; i < msgs.length; i++) {
@@ -81,12 +82,10 @@
                     break;
             }
             ms.end = msgs[j-1];
- v.addElement(ms);
+ v.add(ms);
             i = j-1; // i gets incremented @ top of the loop
         }
- MessageSet[] msgsets = new MessageSet[v.size()];
- v.copyInto(msgsets);
- return msgsets;
+ return v.toArray(new MessageSet[v.size()]);
     }
 
     /**

diff -r 8146d69ec23a -r bb765b7a2f3a mail/src/main/java/com/sun/mail/imap/protocol/Namespaces.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/Namespaces.java Wed Oct 02 13:39:10 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/Namespaces.java Wed Oct 02 15:12:32 2013 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2013 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
@@ -146,16 +146,14 @@
         r.skipSpaces();
         // Namespace = nil / "(" 1*( Namespace_Element) ")"
         if (r.peekByte() == '(') {
- Vector v = new Vector();
+ List<Namespace> v = new ArrayList<Namespace>();
             r.readByte();
             do {
                 Namespace ns = new Namespace(r);
- v.addElement(ns);
+ v.add(ns);
             } while (r.peekByte() != ')');
             r.readByte();
- Namespace[] nsa = new Namespace[v.size()];
- v.copyInto(nsa);
- return nsa;
+ return v.toArray(new Namespace[v.size()]);
         } else {
             String s = r.readAtom();
             if (s == null)


diff -r bb765b7a2f3a -r d1b1f39a605d mail/src/test/java/com/sun/mail/imap/protocol/EnvelopeTest.java
--- a/mail/src/test/java/com/sun/mail/imap/protocol/EnvelopeTest.java Wed Oct 02 15:12:32 2013 -0700
+++ b/mail/src/test/java/com/sun/mail/imap/protocol/EnvelopeTest.java Wed Oct 02 15:21:53 2013 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012-2013 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,8 +55,7 @@
      */
     @Test
     public void testYahooUndisclosedRecipientsBug() throws Exception {
- IMAPResponse response =
- new IMAPResponse(
+ IMAPResponse response = new IMAPResponse(
     "* 2 FETCH (INTERNALDATE \"24-Apr-2012 20:28:58 +0000\" " +
     "RFC822.SIZE 155937 " +
     "ENVELOPE (\"Wed, 28 Sep 2011 11:16:17 +0100\" \"test\" " +
@@ -71,4 +70,21 @@
         FetchResponse fr = new FetchResponse(response);
         // no exception means it worked
     }
+
+ /**
+ * Test workaround for Yahoo IMAP bug that returns an empty list
+ * instad of NIL for some addresses in ENVELOPE response.
+ */
+ @Test
+ public void testYahooEnvelopeAddressListBug() throws Exception {
+ IMAPResponse response = new IMAPResponse(
+ "* 2 FETCH (RFC822.SIZE 2567 INTERNALDATE \"29-Apr-2011 13:49:01 +0000\" " +
+ "ENVELOPE (\"Fri, 29 Apr 2011 19:19:01 +0530\" \"test\" " +
+ "((\"xxx\" NIL \"xxx\" \"milium.com.br\")) " +
+ "((\"xxx\" NIL \"xxx\" \"milium.com.br\")) " +
+ "((NIL NIL \"xxx\" \"live.hk\")) () NIL NIL NIL " +
+ "\"<20110429134718.70333732030A_at_mail2.milium.com.br>\"))");
+ FetchResponse fr = new FetchResponse(response);
+ // no exception means it worked
+ }
 }


diff -r d1b1f39a605d -r 64bc7c736dc9 mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java
--- a/mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java Wed Oct 02 15:21:53 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java Fri Oct 04 16:21:20 2013 -0700
@@ -609,24 +609,26 @@
      */
     protected synchronized boolean protocolConnect(String host, int port,
                         String user, String passwd) throws MessagingException {
- // setting mail.smtp.ehlo to false disables attempts to use EHLO
- boolean useEhlo = PropUtil.getBooleanSessionProperty(session,
- "mail." + name + ".ehlo", true);
         // setting mail.smtp.auth to true enables attempts to use AUTH
         boolean useAuth = PropUtil.getBooleanSessionProperty(session,
                                         "mail." + name + ".auth", false);
 
- if (logger.isLoggable(Level.FINE))
- logger.fine("useEhlo " + useEhlo + ", useAuth " + useAuth);
-
         /*
          * If mail.smtp.auth is set, make sure we have a valid username
          * and password, even if we might not end up using it (e.g.,
          * because the server doesn't support ESMTP or doesn't support
          * the AUTH extension).
          */
- if (useAuth && (user == null || passwd == null))
+ if (useAuth && (user == null || passwd == null)) {
+ logger.fine("need username and password for authentication");
             return false;
+ }
+
+ // setting mail.smtp.ehlo to false disables attempts to use EHLO
+ boolean useEhlo = PropUtil.getBooleanSessionProperty(session,
+ "mail." + name + ".ehlo", true);
+ if (logger.isLoggable(Level.FINE))
+ logger.fine("useEhlo " + useEhlo + ", useAuth " + useAuth);
 
         /*
          * If port is not specified, set it to value of mail.smtp.port
@@ -790,6 +792,7 @@
          */
         boolean authenticate(String host, String authzid,
                         String user, String passwd) throws MessagingException {
+ Throwable thrown = null;
             try {
                 // use "initial response" capability, if supported
                 String ir = getInitialResponse(host, authzid, user, passwd);
@@ -818,6 +821,9 @@
                     doAuth(host, authzid, user, passwd);
             } catch (IOException ex) { // should never happen, ignore
                 logger.log(Level.FINE, "AUTH " + mech + " failed", ex);
+ } catch (Throwable t) { // crypto can't be initialized?
+ logger.log(Level.FINE, "AUTH " + mech + " failed", t);
+ thrown = t;
             } finally {
                 if (noauthdebug && isTracing())
                     logger.fine("AUTH " + mech + " " +
@@ -825,6 +831,15 @@
                 resumeTracing();
                 if (resp != 235) {
                     closeConnection();
+ if (thrown != null) {
+ if (thrown instanceof Error)
+ throw (Error)thrown;
+ if (thrown instanceof Exception)
+ throw new AuthenticationFailedException(
+ getLastServerResponse(),
+ (Exception)thrown);
+ assert false : "unknown Throwable"; // can't happen
+ }
                     throw new AuthenticationFailedException(
                                             getLastServerResponse());
                 }