commits@javamail.java.net

[javamail~mercurial:486] Added tag JAVAMAIL-1_4_6 for changeset 3dba8c78634f

From: <shannon_at_kenai.com>
Date: Thu, 7 Feb 2013 23:16:00 +0000

Project: javamail
Repository: mercurial
Revision: 486
Author: shannon
Date: 2013-02-02 00:08:49 UTC
Link:

Log Message:
------------
Fix GmailMessage.getLabels to work with latest version of Gmail.
Got confirmation that XLIST is no longer needed, removed it.
handle multibyte characters in multi-segment parameters - bug 5816
Update version to 1.4.6.
Added tag JAVAMAIL-1_4_6 for changeset b9c00b0cf3cf
merge in a few last minute fixes.
Added tag JAVAMAIL-1_4_6 for changeset 3dba8c78634f


Revisions:
----------
480
481
482
483
484
485
486


Modified Paths:
---------------
gimap/src/main/java/com/sun/mail/gimap/package.html
gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java
mail/src/main/java/com/sun/mail/iap/Response.java
doc/release/CHANGES.txt
mail/src/main/java/javax/mail/internet/ParameterList.java
mail/src/test/java/javax/mail/internet/ParameterListDecode.java
mail/src/test/resources/javax/mail/internet/paramdata
client/pom.xml
demo/pom.xml
dsn/pom.xml
gimap/pom.xml
imap/pom.xml
javadoc/pom.xml
logging/pom.xml
mail/pom.xml
mailapi/pom.xml
mailapijar/pom.xml
mbox/dist/pom.xml
mbox/native/pom.xml
mbox/pom.xml
oldmail/pom.xml
outlook/pom.xml
parent-distrib/pom.xml
pom.xml
pop3/pom.xml
servlet/pom.xml
smtp/pom.xml
taglib/pom.xml
webapp/pom.xml
.hgtags


Diffs:
------
diff -r 1b4bafe49b74 -r 669676adcc85 gimap/src/main/java/com/sun/mail/gimap/package.html
--- a/gimap/src/main/java/com/sun/mail/gimap/package.html Tue Dec 04 14:56:31 2012 -0800
+++ b/gimap/src/main/java/com/sun/mail/gimap/package.html Wed Jan 30 12:26:10 2013 -0800
@@ -5,7 +5,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
@@ -76,6 +76,9 @@
 <PRE>
     GmailMessage gmsg = (GmailMessage)msg;
     System.out.println("Gmail message ID is " + gmsg.getMsgId());
+ String[] labels = gmsg.getLabels();
+ for (String s : labels)
+ System.out.println("Gmail message label: " + s);
 </PRE>
 <P>
 Gmail-specific data may be prefetched using the GmailFolder.FetchProfileItems

diff -r 1b4bafe49b74 -r 669676adcc85 gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java
--- a/gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java Tue Dec 04 14:56:31 2012 -0800
+++ b/gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java Wed Jan 30 12:26:10 2013 -0800
@@ -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
@@ -76,7 +76,7 @@
     public static final FetchItem LABELS_ITEM =
         new FetchItem("X-GM-LABELS", FetchProfileItem.LABELS) {
             public Object parseItem(FetchResponse r) {
- return r.readStringList();
+ return r.readAtomStringList();
             }
         };
 
@@ -143,6 +143,8 @@
 
     /**
      * LIST Command. Use XLIST for Gmail.
+ * Note that Gmail is deprecating XLIST in favor of RFC 6154
+ * so this won't be necessary in future releases.
      */
     public ListInfo[] list(String ref, String pattern)
                         throws ProtocolException {

diff -r 1b4bafe49b74 -r 669676adcc85 mail/src/main/java/com/sun/mail/iap/Response.java
--- a/mail/src/main/java/com/sun/mail/iap/Response.java Tue Dec 04 14:56:31 2012 -0800
+++ b/mail/src/main/java/com/sun/mail/iap/Response.java Wed Jan 30 12:26:10 2013 -0800
@@ -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
@@ -248,6 +248,14 @@
     }
 
     public String[] readStringList() {
+ return readStringList(false);
+ }
+
+ public String[] readAtomStringList() {
+ return readStringList(true);
+ }
+
+ private String[] readStringList(boolean atom) {
         skipSpaces();
 
         if (buffer[index] != '(') // not what we expected
@@ -256,7 +264,7 @@
 
         Vector v = new Vector();
         do {
- v.addElement(readString());
+ v.addElement(atom ? readAtomString() : readString());
         } while (buffer[index++] != ')');
 
         int size = v.size();


diff -r 669676adcc85 -r 64c4eb6bdb1b gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java
--- a/gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java Wed Jan 30 12:26:10 2013 -0800
+++ b/gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java Wed Jan 30 12:41:15 2013 -0800
@@ -87,7 +87,6 @@
     };
 
     private FetchItem[] fetchItems = null;
- private boolean supportsXlist;
 
     /**
      * Connect to Gmail.
@@ -110,7 +109,6 @@
         } else {
             logger.fine("connected to Gmail");
         }
- supportsXlist = hasCapability("XLIST");
     }
 
     /**
@@ -140,14 +138,4 @@
             searchSequence = new GmailSearchSequence();
         return searchSequence;
     }
-
- /**
- * LIST Command. Use XLIST for Gmail.
- * Note that Gmail is deprecating XLIST in favor of RFC 6154
- * so this won't be necessary in future releases.
- */
- public ListInfo[] list(String ref, String pattern)
- throws ProtocolException {
- return doList(supportsXlist ? "XLIST" : "LIST", ref, pattern);
- }
 }


diff -r 64c4eb6bdb1b -r 9a58018396fd doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Wed Jan 30 12:41:15 2013 -0800
+++ b/doc/release/CHANGES.txt Fri Feb 01 14:24:15 2013 -0800
@@ -22,6 +22,8 @@
 K 5086 STARTTLS when already using SSL may cause connection to fail
 K 5090 Yahoo: Error reading emails containing "undisclosed recipients"
 K 5233 Infinite loop if Quota information is not correctly reported by server
+K 5816 Issue in decoding filename with charset iso-2022-jp from Mime header
+ based on rfc 2231
 <no id> add mail.imap.ignorebodystructuresize to work around server bugs
 <no id> add "gimap" EXPERIMENTAL Gmail IMAP provider
 <no id> add isSSL() method to all protocol providers

diff -r 64c4eb6bdb1b -r 9a58018396fd mail/src/main/java/javax/mail/internet/ParameterList.java
--- a/mail/src/main/java/javax/mail/internet/ParameterList.java Wed Jan 30 12:41:15 2013 -0800
+++ b/mail/src/main/java/javax/mail/internet/ParameterList.java Fri Feb 01 14:24:15 2013 -0800
@@ -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
@@ -43,6 +43,7 @@
 import java.util.*;
 import java.io.*;
 import com.sun.mail.util.PropUtil;
+import com.sun.mail.util.ASCIIUtility;
 
 /**
  * This class holds MIME parameters (attribute-value pairs).
@@ -124,8 +125,10 @@
      * The Value object is not decoded during the initial parse
      * because the segments may appear in any order and until the
      * first segment appears we don't know what charset to use to
- * decode any encoded segments. The segments are decoded in
- * order in the combineMultisegmentNames method.
+ * decode the encoded segments. The segments are hex decoded
+ * in order, combined into a single byte array, and converted
+ * to a String using the specified charset in the
+ * combineMultisegmentNames method.
      */
     private Map slist;
 
@@ -320,7 +323,14 @@
         } else if (star == name.length() - 1) {
             // single parameter, encoded value
             name = name.substring(0, star);
- list.put(name, decodeValue(value));
+ Value v = extractCharset(value);
+ try {
+ v.value = decodeBytes(v.value, v.charset);
+ } catch (UnsupportedEncodingException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ }
+ list.put(name, v);
         } else {
             // multiple segments
             String rname = name.substring(0, star);
@@ -330,9 +340,13 @@
             Object v;
             if (name.endsWith("*")) {
                 // encoded value
- v = new Value();
- ((Value)v).encodedValue = value;
- ((Value)v).value = value; // default; decoded later
+ if (name.endsWith("*0*")) { // first segment
+ v = extractCharset(value);
+ } else {
+ v = new Value();
+ ((Value)v).encodedValue = value;
+ ((Value)v).value = value; // default; decoded later
+ }
                 name = name.substring(0, name.length() - 1);
             } else {
                 // unencoded value
@@ -363,6 +377,7 @@
                  * decode each segment as needed.
                  */
                 String charset = null;
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
                 int segment;
                 for (segment = 0; ; segment++) {
                     String sname = name + "*" + segment;
@@ -370,49 +385,44 @@
                     if (v == null) // out of segments
                         break;
                     mv.add(v);
- String value = null;
- if (v instanceof Value) {
- try {
+ try {
+ if (v instanceof Value) {
                             Value vv = (Value)v;
- String evalue = vv.encodedValue;
- value = evalue; // in case of exception
                             if (segment == 0) {
- // the first segment specified the charset
+ // the first segment specifies the charset
                                 // for all other encoded segments
- Value vnew = decodeValue(evalue);
- charset = vv.charset = vnew.charset;
- value = vv.value = vnew.value;
+ charset = vv.charset;
                             } else {
                                 if (charset == null) {
                                     // should never happen
                                     multisegmentNames.remove(name);
                                     break;
                                 }
- value = vv.value = decodeBytes(evalue, charset);
                             }
- } catch (NumberFormatException nex) {
- if (decodeParametersStrict)
- throw new ParseException(nex.toString());
- } catch (UnsupportedEncodingException uex) {
- if (decodeParametersStrict)
- throw new ParseException(uex.toString());
- } catch (StringIndexOutOfBoundsException ex) {
- if (decodeParametersStrict)
- throw new ParseException(ex.toString());
+ decodeBytes(vv.value, bos);
+ } else {
+ bos.write(ASCIIUtility.getBytes((String)v));
                         }
- // if anything went wrong decoding the value,
- // we just use the original value (set above)
- } else {
- value = (String)v;
+ } catch (IOException ex) {
+ // XXX - should never happen
                     }
- sb.append(value);
                     slist.remove(sname);
                 }
                 if (segment == 0) {
                     // didn't find any segments at all
                     list.remove(name);
                 } else {
- mv.value = sb.toString();
+ try {
+ if (charset != null)
+ mv.value = bos.toString(charset);
+ else
+ mv.value = bos.toString();
+ } catch (UnsupportedEncodingException uex) {
+ if (decodeParametersStrict)
+ throw new ParseException(uex.toString());
+ // convert as if ASCII
+ mv.value = bos.toString(0);
+ }
                     list.put(name, mv);
                 }
             }
@@ -433,9 +443,13 @@
                         Object v = sit.next();
                         if (v instanceof Value) {
                             Value vv = (Value)v;
- Value vnew = decodeValue(vv.encodedValue);
- vv.charset = vnew.charset;
- vv.value = vnew.value;
+ try {
+ vv.value =
+ decodeBytes(vv.value, vv.charset);
+ } catch (UnsupportedEncodingException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ }
                         }
                     }
                     list.putAll(slist);
@@ -698,12 +712,12 @@
     }
 
     /**
- * Decode a parameter value.
+ * Extract charset and encoded value.
+ * Value will be decoded later.
      */
- private static Value decodeValue(String value) throws ParseException {
+ private static Value extractCharset(String value) throws ParseException {
         Value v = new Value();
- v.encodedValue = value;
- v.value = value; // in case we fail to decode it
+ v.value = v.encodedValue = value;
         try {
             int i = value.indexOf('\'');
             if (i <= 0) {
@@ -721,15 +735,11 @@
                 return v; // not encoded correctly? return as is.
             }
             String lang = value.substring(i + 1, li);
- value = value.substring(li + 1);
+ v.value = value.substring(li + 1);
             v.charset = charset;
- v.value = decodeBytes(value, charset);
         } catch (NumberFormatException nex) {
             if (decodeParametersStrict)
                 throw new ParseException(nex.toString());
- } catch (UnsupportedEncodingException uex) {
- if (decodeParametersStrict)
- throw new ParseException(uex.toString());
         } catch (StringIndexOutOfBoundsException ex) {
             if (decodeParametersStrict)
                 throw new ParseException(ex.toString());
@@ -741,7 +751,7 @@
      * Decode the encoded bytes in value using the specified charset.
      */
     private static String decodeBytes(String value, String charset)
- throws UnsupportedEncodingException {
+ throws ParseException, UnsupportedEncodingException {
         /*
          * Decode the ASCII characters in value
          * into an array of bytes, and then convert
@@ -755,12 +765,52 @@
         for (i = 0, bi = 0; i < value.length(); i++) {
             char c = value.charAt(i);
             if (c == '%') {
- String hex = value.substring(i + 1, i + 3);
- c = (char)Integer.parseInt(hex, 16);
- i += 2;
+ try {
+ String hex = value.substring(i + 1, i + 3);
+ c = (char)Integer.parseInt(hex, 16);
+ i += 2;
+ } catch (NumberFormatException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ } catch (StringIndexOutOfBoundsException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ }
             }
             b[bi++] = (byte)c;
         }
- return new String(b, 0, bi, MimeUtility.javaCharset(charset));
+ charset = MimeUtility.javaCharset(charset);
+ if (charset == null)
+ charset = MimeUtility.getDefaultJavaCharset();
+ return new String(b, 0, bi, charset);
+ }
+
+ /**
+ * Decode the encoded bytes in value and write them to the OutputStream.
+ */
+ private static void decodeBytes(String value, OutputStream os)
+ throws ParseException, IOException {
+ /*
+ * Decode the ASCII characters in value
+ * and write them to the stream.
+ */
+ int i;
+ for (i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ if (c == '%') {
+ try {
+ String hex = value.substring(i + 1, i + 3);
+ c = (char)Integer.parseInt(hex, 16);
+ i += 2;
+ } catch (NumberFormatException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ } catch (StringIndexOutOfBoundsException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ }
+ }
+ os.write((byte)c);
+ }
     }
 }

diff -r 64c4eb6bdb1b -r 9a58018396fd mail/src/test/java/javax/mail/internet/ParameterListDecode.java
--- a/mail/src/test/java/javax/mail/internet/ParameterListDecode.java Wed Jan 30 12:41:15 2013 -0800
+++ b/mail/src/test/java/javax/mail/internet/ParameterListDecode.java Fri Feb 01 14:24:15 2013 -0800
@@ -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
@@ -198,7 +198,7 @@
                         int nexpect = Integer.parseInt(s.substring(8));
                         expect = new String[nexpect];
                         for (i = 0; i < nexpect; i++)
- expect[i] = trim(in.readLine());
+ expect[i] = decode(trim(in.readLine()));
                     } catch (NumberFormatException e) {
                         try {
                             if (s.substring(8, 17).equals("Exception")) {
@@ -243,6 +243,22 @@
     }
 
     /**
+ * Decode Unicode escapes.
+ */
+ public static String decode(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\\' && s.charAt(i + 1) == 'u') {
+ c = (char)Integer.parseInt(s.substring(i + 2, i + 6), 16);
+ i += 5;
+ }
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ /**
      * Test the header's value to see if we can parse it as expected.
      */
     public static void test(String header, String value, String expect[])

diff -r 64c4eb6bdb1b -r 9a58018396fd mail/src/test/resources/javax/mail/internet/paramdata
--- a/mail/src/test/resources/javax/mail/internet/paramdata Wed Jan 30 12:41:15 2013 -0800
+++ b/mail/src/test/resources/javax/mail/internet/paramdata Fri Feb 01 14:24:15 2013 -0800
@@ -2,7 +2,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
@@ -119,21 +119,39 @@
 Expect: 2
         title=This is even more ***fun***
         title*3=isn't it!
+Comment:
+ This is an error case with no right answer.
+ Should we assume earlier segments are missing and just decode
+ this segment? Or should we assume that the "*3" is part of
+ the parameter name and this is a single segment encoded parameter?
+ Currently we do the former.
 Content-Type: application/x-stuff; title*3*=us-ascii'en'isn't%20it!
 Expect: 1
- title*3=isn't it!
+ title*3=us-ascii'en'isn't it!
 Content-Type: application/x-stuff; title*3*=unknown'en'isn't%20it!
 Expect: 1
- title*3=unknown'en'isn't%20it!
+ title*3=unknown'en'isn't it!
 Content-Type: application/x-stuff;
         title*0*=us-ascii'en'This%20is%20even%20more%20;
         title*1*=%XX%2A%2Afun%2A%2A%2A%20;
         title*2="isn't it!"
 Expect: 1
- title=This is even more %XX%2A%2Afun%2A%2A%2A%20isn't it!
+ title=This is even more %XX**fun*** isn't it!
 Content-Type: application/x-stuff;
         title*0*=us-ascii'en'This%20is%20even%20more%20;
         title*1="***fun***";
         title*2*=%20isn't%20it!
 Expect: 1
         title=This is even more ***fun*** isn't it!
+Content-Type: image/png;
+ name*0*=ISO-2022-JP''%1B%24B%24%22%24%24%24%26%24%28%24*%24%22%24%24%24%26;
+ name*1*=%24%28%24*%24%22%24%24%24%26%24%28%24*%24%22%24%24%24%26%24%28;
+ name*2*=%24*%1B%28B.png
+Expect: 1
+ name=\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a.png
+Content-Type: image/png;
+ filename*0*=ISO-2022-JP''%1B%24B%24%22%24%24%24%26%24%28%24*%24%22%24%24;
+ filename*1*=%24%26%24%28%24*%24%22%24%24%24%26%24%28%24*%24%22%24%24%24;
+ filename*2*=%26%24%28%24*%1B%28B.png
+Expect: 1
+ filename=\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a.png


diff -r 1b4bafe49b74 -r b9c00b0cf3cf client/pom.xml
--- a/client/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/client/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf demo/pom.xml
--- a/demo/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/demo/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf dsn/pom.xml
--- a/dsn/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/dsn/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf gimap/pom.xml
--- a/gimap/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/gimap/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf imap/pom.xml
--- a/imap/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/imap/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>parent-distrib</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
         <relativePath>../parent-distrib/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf javadoc/pom.xml
--- a/javadoc/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/javadoc/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,13 +48,13 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>
     <artifactId>javadoc</artifactId>
     <packaging>pom</packaging>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     <name>JavaMail API javadocs</name>
     <description>${project.name}</description>
 

diff -r 1b4bafe49b74 -r b9c00b0cf3cf logging/pom.xml
--- a/logging/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/logging/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf mail/pom.xml
--- a/mail/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/mail/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf mailapi/pom.xml
--- a/mailapi/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/mailapi/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -56,7 +56,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf mailapijar/pom.xml
--- a/mailapijar/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/mailapijar/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -55,7 +55,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>javax.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf mbox/dist/pom.xml
--- a/mbox/dist/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/mbox/dist/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf mbox/native/pom.xml
--- a/mbox/native/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/mbox/native/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf mbox/pom.xml
--- a/mbox/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/mbox/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf oldmail/pom.xml
--- a/oldmail/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/oldmail/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -53,7 +53,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>javax.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf outlook/pom.xml
--- a/outlook/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/outlook/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf parent-distrib/pom.xml
--- a/parent-distrib/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/parent-distrib/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf pom.xml
--- a/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -54,7 +54,7 @@
     <groupId>com.sun.mail</groupId>
     <artifactId>all</artifactId>
     <packaging>pom</packaging>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     <name>JavaMail API distribution</name>
     <description>${project.name}</description>
     <url>http://kenai.com/projects/javamail</url>
@@ -91,9 +91,9 @@
     </organization>
 
     <properties>
- <mail.version>1.4.6-rc1</mail.version>
+ <mail.version>1.4.6</mail.version>
         <!-- like mail.version, but with underscores instead of dots -->
- <mail.zipversion>1_4_6-rc1</mail.zipversion>
+ <mail.zipversion>1_4_6</mail.zipversion>
         <mail.spec.version>1.4</mail.spec.version>
         <activation-api.version>1.1</activation-api.version>
         <!-- defaults that are overridden in mail module -->

diff -r 1b4bafe49b74 -r b9c00b0cf3cf pop3/pom.xml
--- a/pop3/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/pop3/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>parent-distrib</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
         <relativePath>../parent-distrib/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf servlet/pom.xml
--- a/servlet/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/servlet/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf smtp/pom.xml
--- a/smtp/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/smtp/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>parent-distrib</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
         <relativePath>../parent-distrib/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf taglib/pom.xml
--- a/taglib/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/taglib/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r 1b4bafe49b74 -r b9c00b0cf3cf webapp/pom.xml
--- a/webapp/pom.xml Tue Dec 04 14:56:31 2012 -0800
+++ b/webapp/pom.xml Wed Dec 19 12:44:17 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-rc1</version>
+ <version>1.4.6</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>


diff -r b9c00b0cf3cf -r e67e851f70a0 .hgtags
--- a/.hgtags Wed Dec 19 12:44:17 2012 -0800
+++ b/.hgtags Wed Dec 19 12:44:41 2012 -0800
@@ -10,3 +10,4 @@
 ce00d5900757397cbc7943b686035e8b27aa9449 JAVAMAIL-1_4_5-RC1
 e0ece38db9a0a6b46fe03575bffba6605603761d JAVAMAIL-1_4_5
 da6e25608ec175cf0556c6b7b7d1fee40cbe09c5 JAVAMAIL-1_4_6-RC1
+b9c00b0cf3cf560077cd3c393c597e4ed9f1bf14 JAVAMAIL-1_4_6


diff -r e67e851f70a0 -r 3dba8c78634f doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Wed Dec 19 12:44:41 2012 -0800
+++ b/doc/release/CHANGES.txt Fri Feb 01 16:08:22 2013 -0800
@@ -22,6 +22,8 @@
 K 5086 STARTTLS when already using SSL may cause connection to fail
 K 5090 Yahoo: Error reading emails containing "undisclosed recipients"
 K 5233 Infinite loop if Quota information is not correctly reported by server
+K 5816 Issue in decoding filename with charset iso-2022-jp from Mime header
+ based on rfc 2231
 <no id> add mail.imap.ignorebodystructuresize to work around server bugs
 <no id> add "gimap" EXPERIMENTAL Gmail IMAP provider
 <no id> add isSSL() method to all protocol providers

diff -r e67e851f70a0 -r 3dba8c78634f gimap/src/main/java/com/sun/mail/gimap/package.html
--- a/gimap/src/main/java/com/sun/mail/gimap/package.html Wed Dec 19 12:44:41 2012 -0800
+++ b/gimap/src/main/java/com/sun/mail/gimap/package.html Fri Feb 01 16:08:22 2013 -0800
@@ -5,7 +5,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
@@ -76,6 +76,9 @@
 <PRE>
     GmailMessage gmsg = (GmailMessage)msg;
     System.out.println("Gmail message ID is " + gmsg.getMsgId());
+ String[] labels = gmsg.getLabels();
+ for (String s : labels)
+ System.out.println("Gmail message label: " + s);
 </PRE>
 <P>
 Gmail-specific data may be prefetched using the GmailFolder.FetchProfileItems

diff -r e67e851f70a0 -r 3dba8c78634f gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java
--- a/gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java Wed Dec 19 12:44:41 2012 -0800
+++ b/gimap/src/main/java/com/sun/mail/gimap/protocol/GmailProtocol.java Fri Feb 01 16:08:22 2013 -0800
@@ -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
@@ -76,7 +76,7 @@
     public static final FetchItem LABELS_ITEM =
         new FetchItem("X-GM-LABELS", FetchProfileItem.LABELS) {
             public Object parseItem(FetchResponse r) {
- return r.readStringList();
+ return r.readAtomStringList();
             }
         };
 
@@ -87,7 +87,6 @@
     };
 
     private FetchItem[] fetchItems = null;
- private boolean supportsXlist;
 
     /**
      * Connect to Gmail.
@@ -110,7 +109,6 @@
         } else {
             logger.fine("connected to Gmail");
         }
- supportsXlist = hasCapability("XLIST");
     }
 
     /**
@@ -140,12 +138,4 @@
             searchSequence = new GmailSearchSequence();
         return searchSequence;
     }
-
- /**
- * LIST Command. Use XLIST for Gmail.
- */
- public ListInfo[] list(String ref, String pattern)
- throws ProtocolException {
- return doList(supportsXlist ? "XLIST" : "LIST", ref, pattern);
- }
 }

diff -r e67e851f70a0 -r 3dba8c78634f mail/src/main/java/com/sun/mail/iap/Response.java
--- a/mail/src/main/java/com/sun/mail/iap/Response.java Wed Dec 19 12:44:41 2012 -0800
+++ b/mail/src/main/java/com/sun/mail/iap/Response.java Fri Feb 01 16:08:22 2013 -0800
@@ -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
@@ -248,6 +248,14 @@
     }
 
     public String[] readStringList() {
+ return readStringList(false);
+ }
+
+ public String[] readAtomStringList() {
+ return readStringList(true);
+ }
+
+ private String[] readStringList(boolean atom) {
         skipSpaces();
 
         if (buffer[index] != '(') // not what we expected
@@ -256,7 +264,7 @@
 
         Vector v = new Vector();
         do {
- v.addElement(readString());
+ v.addElement(atom ? readAtomString() : readString());
         } while (buffer[index++] != ')');
 
         int size = v.size();

diff -r e67e851f70a0 -r 3dba8c78634f mail/src/main/java/javax/mail/internet/ParameterList.java
--- a/mail/src/main/java/javax/mail/internet/ParameterList.java Wed Dec 19 12:44:41 2012 -0800
+++ b/mail/src/main/java/javax/mail/internet/ParameterList.java Fri Feb 01 16:08:22 2013 -0800
@@ -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
@@ -43,6 +43,7 @@
 import java.util.*;
 import java.io.*;
 import com.sun.mail.util.PropUtil;
+import com.sun.mail.util.ASCIIUtility;
 
 /**
  * This class holds MIME parameters (attribute-value pairs).
@@ -124,8 +125,10 @@
      * The Value object is not decoded during the initial parse
      * because the segments may appear in any order and until the
      * first segment appears we don't know what charset to use to
- * decode any encoded segments. The segments are decoded in
- * order in the combineMultisegmentNames method.
+ * decode the encoded segments. The segments are hex decoded
+ * in order, combined into a single byte array, and converted
+ * to a String using the specified charset in the
+ * combineMultisegmentNames method.
      */
     private Map slist;
 
@@ -320,7 +323,14 @@
         } else if (star == name.length() - 1) {
             // single parameter, encoded value
             name = name.substring(0, star);
- list.put(name, decodeValue(value));
+ Value v = extractCharset(value);
+ try {
+ v.value = decodeBytes(v.value, v.charset);
+ } catch (UnsupportedEncodingException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ }
+ list.put(name, v);
         } else {
             // multiple segments
             String rname = name.substring(0, star);
@@ -330,9 +340,13 @@
             Object v;
             if (name.endsWith("*")) {
                 // encoded value
- v = new Value();
- ((Value)v).encodedValue = value;
- ((Value)v).value = value; // default; decoded later
+ if (name.endsWith("*0*")) { // first segment
+ v = extractCharset(value);
+ } else {
+ v = new Value();
+ ((Value)v).encodedValue = value;
+ ((Value)v).value = value; // default; decoded later
+ }
                 name = name.substring(0, name.length() - 1);
             } else {
                 // unencoded value
@@ -363,6 +377,7 @@
                  * decode each segment as needed.
                  */
                 String charset = null;
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
                 int segment;
                 for (segment = 0; ; segment++) {
                     String sname = name + "*" + segment;
@@ -370,49 +385,44 @@
                     if (v == null) // out of segments
                         break;
                     mv.add(v);
- String value = null;
- if (v instanceof Value) {
- try {
+ try {
+ if (v instanceof Value) {
                             Value vv = (Value)v;
- String evalue = vv.encodedValue;
- value = evalue; // in case of exception
                             if (segment == 0) {
- // the first segment specified the charset
+ // the first segment specifies the charset
                                 // for all other encoded segments
- Value vnew = decodeValue(evalue);
- charset = vv.charset = vnew.charset;
- value = vv.value = vnew.value;
+ charset = vv.charset;
                             } else {
                                 if (charset == null) {
                                     // should never happen
                                     multisegmentNames.remove(name);
                                     break;
                                 }
- value = vv.value = decodeBytes(evalue, charset);
                             }
- } catch (NumberFormatException nex) {
- if (decodeParametersStrict)
- throw new ParseException(nex.toString());
- } catch (UnsupportedEncodingException uex) {
- if (decodeParametersStrict)
- throw new ParseException(uex.toString());
- } catch (StringIndexOutOfBoundsException ex) {
- if (decodeParametersStrict)
- throw new ParseException(ex.toString());
+ decodeBytes(vv.value, bos);
+ } else {
+ bos.write(ASCIIUtility.getBytes((String)v));
                         }
- // if anything went wrong decoding the value,
- // we just use the original value (set above)
- } else {
- value = (String)v;
+ } catch (IOException ex) {
+ // XXX - should never happen
                     }
- sb.append(value);
                     slist.remove(sname);
                 }
                 if (segment == 0) {
                     // didn't find any segments at all
                     list.remove(name);
                 } else {
- mv.value = sb.toString();
+ try {
+ if (charset != null)
+ mv.value = bos.toString(charset);
+ else
+ mv.value = bos.toString();
+ } catch (UnsupportedEncodingException uex) {
+ if (decodeParametersStrict)
+ throw new ParseException(uex.toString());
+ // convert as if ASCII
+ mv.value = bos.toString(0);
+ }
                     list.put(name, mv);
                 }
             }
@@ -433,9 +443,13 @@
                         Object v = sit.next();
                         if (v instanceof Value) {
                             Value vv = (Value)v;
- Value vnew = decodeValue(vv.encodedValue);
- vv.charset = vnew.charset;
- vv.value = vnew.value;
+ try {
+ vv.value =
+ decodeBytes(vv.value, vv.charset);
+ } catch (UnsupportedEncodingException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ }
                         }
                     }
                     list.putAll(slist);
@@ -698,12 +712,12 @@
     }
 
     /**
- * Decode a parameter value.
+ * Extract charset and encoded value.
+ * Value will be decoded later.
      */
- private static Value decodeValue(String value) throws ParseException {
+ private static Value extractCharset(String value) throws ParseException {
         Value v = new Value();
- v.encodedValue = value;
- v.value = value; // in case we fail to decode it
+ v.value = v.encodedValue = value;
         try {
             int i = value.indexOf('\'');
             if (i <= 0) {
@@ -721,15 +735,11 @@
                 return v; // not encoded correctly? return as is.
             }
             String lang = value.substring(i + 1, li);
- value = value.substring(li + 1);
+ v.value = value.substring(li + 1);
             v.charset = charset;
- v.value = decodeBytes(value, charset);
         } catch (NumberFormatException nex) {
             if (decodeParametersStrict)
                 throw new ParseException(nex.toString());
- } catch (UnsupportedEncodingException uex) {
- if (decodeParametersStrict)
- throw new ParseException(uex.toString());
         } catch (StringIndexOutOfBoundsException ex) {
             if (decodeParametersStrict)
                 throw new ParseException(ex.toString());
@@ -741,7 +751,7 @@
      * Decode the encoded bytes in value using the specified charset.
      */
     private static String decodeBytes(String value, String charset)
- throws UnsupportedEncodingException {
+ throws ParseException, UnsupportedEncodingException {
         /*
          * Decode the ASCII characters in value
          * into an array of bytes, and then convert
@@ -755,12 +765,52 @@
         for (i = 0, bi = 0; i < value.length(); i++) {
             char c = value.charAt(i);
             if (c == '%') {
- String hex = value.substring(i + 1, i + 3);
- c = (char)Integer.parseInt(hex, 16);
- i += 2;
+ try {
+ String hex = value.substring(i + 1, i + 3);
+ c = (char)Integer.parseInt(hex, 16);
+ i += 2;
+ } catch (NumberFormatException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ } catch (StringIndexOutOfBoundsException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ }
             }
             b[bi++] = (byte)c;
         }
- return new String(b, 0, bi, MimeUtility.javaCharset(charset));
+ charset = MimeUtility.javaCharset(charset);
+ if (charset == null)
+ charset = MimeUtility.getDefaultJavaCharset();
+ return new String(b, 0, bi, charset);
+ }
+
+ /**
+ * Decode the encoded bytes in value and write them to the OutputStream.
+ */
+ private static void decodeBytes(String value, OutputStream os)
+ throws ParseException, IOException {
+ /*
+ * Decode the ASCII characters in value
+ * and write them to the stream.
+ */
+ int i;
+ for (i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ if (c == '%') {
+ try {
+ String hex = value.substring(i + 1, i + 3);
+ c = (char)Integer.parseInt(hex, 16);
+ i += 2;
+ } catch (NumberFormatException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ } catch (StringIndexOutOfBoundsException ex) {
+ if (decodeParametersStrict)
+ throw new ParseException(ex.toString());
+ }
+ }
+ os.write((byte)c);
+ }
     }
 }

diff -r e67e851f70a0 -r 3dba8c78634f mail/src/test/java/javax/mail/internet/ParameterListDecode.java
--- a/mail/src/test/java/javax/mail/internet/ParameterListDecode.java Wed Dec 19 12:44:41 2012 -0800
+++ b/mail/src/test/java/javax/mail/internet/ParameterListDecode.java Fri Feb 01 16:08:22 2013 -0800
@@ -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
@@ -198,7 +198,7 @@
                         int nexpect = Integer.parseInt(s.substring(8));
                         expect = new String[nexpect];
                         for (i = 0; i < nexpect; i++)
- expect[i] = trim(in.readLine());
+ expect[i] = decode(trim(in.readLine()));
                     } catch (NumberFormatException e) {
                         try {
                             if (s.substring(8, 17).equals("Exception")) {
@@ -243,6 +243,22 @@
     }
 
     /**
+ * Decode Unicode escapes.
+ */
+ public static String decode(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\\' && s.charAt(i + 1) == 'u') {
+ c = (char)Integer.parseInt(s.substring(i + 2, i + 6), 16);
+ i += 5;
+ }
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ /**
      * Test the header's value to see if we can parse it as expected.
      */
     public static void test(String header, String value, String expect[])

diff -r e67e851f70a0 -r 3dba8c78634f mail/src/test/resources/javax/mail/internet/paramdata
--- a/mail/src/test/resources/javax/mail/internet/paramdata Wed Dec 19 12:44:41 2012 -0800
+++ b/mail/src/test/resources/javax/mail/internet/paramdata Fri Feb 01 16:08:22 2013 -0800
@@ -2,7 +2,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
@@ -119,21 +119,39 @@
 Expect: 2
         title=This is even more ***fun***
         title*3=isn't it!
+Comment:
+ This is an error case with no right answer.
+ Should we assume earlier segments are missing and just decode
+ this segment? Or should we assume that the "*3" is part of
+ the parameter name and this is a single segment encoded parameter?
+ Currently we do the former.
 Content-Type: application/x-stuff; title*3*=us-ascii'en'isn't%20it!
 Expect: 1
- title*3=isn't it!
+ title*3=us-ascii'en'isn't it!
 Content-Type: application/x-stuff; title*3*=unknown'en'isn't%20it!
 Expect: 1
- title*3=unknown'en'isn't%20it!
+ title*3=unknown'en'isn't it!
 Content-Type: application/x-stuff;
         title*0*=us-ascii'en'This%20is%20even%20more%20;
         title*1*=%XX%2A%2Afun%2A%2A%2A%20;
         title*2="isn't it!"
 Expect: 1
- title=This is even more %XX%2A%2Afun%2A%2A%2A%20isn't it!
+ title=This is even more %XX**fun*** isn't it!
 Content-Type: application/x-stuff;
         title*0*=us-ascii'en'This%20is%20even%20more%20;
         title*1="***fun***";
         title*2*=%20isn't%20it!
 Expect: 1
         title=This is even more ***fun*** isn't it!
+Content-Type: image/png;
+ name*0*=ISO-2022-JP''%1B%24B%24%22%24%24%24%26%24%28%24*%24%22%24%24%24%26;
+ name*1*=%24%28%24*%24%22%24%24%24%26%24%28%24*%24%22%24%24%24%26%24%28;
+ name*2*=%24*%1B%28B.png
+Expect: 1
+ name=\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a.png
+Content-Type: image/png;
+ filename*0*=ISO-2022-JP''%1B%24B%24%22%24%24%24%26%24%28%24*%24%22%24%24;
+ filename*1*=%24%26%24%28%24*%24%22%24%24%24%26%24%28%24*%24%22%24%24%24;
+ filename*2*=%26%24%28%24*%1B%28B.png
+Expect: 1
+ filename=\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a\u3042\u3044\u3046\u3048\u304a.png


diff -r 3dba8c78634f -r 5489ad682aa3 .hgtags
--- a/.hgtags Fri Feb 01 16:08:22 2013 -0800
+++ b/.hgtags Fri Feb 01 16:08:49 2013 -0800
@@ -11,3 +11,5 @@
 e0ece38db9a0a6b46fe03575bffba6605603761d JAVAMAIL-1_4_5
 da6e25608ec175cf0556c6b7b7d1fee40cbe09c5 JAVAMAIL-1_4_6-RC1
 b9c00b0cf3cf560077cd3c393c597e4ed9f1bf14 JAVAMAIL-1_4_6
+b9c00b0cf3cf560077cd3c393c597e4ed9f1bf14 JAVAMAIL-1_4_6
+3dba8c78634fcb1ffd9a32e840bcfab91a83a551 JAVAMAIL-1_4_6