Bug 1511950 - Add GetCharsetAlias() call to JS Mime. r=mkmelin
authorJorg K <jorgk@jorgk.com>
Wed, 05 Dec 2018 23:05:58 +0100
changeset 33856 060cb49e2b681b2b741672049be79543c5034088
parent 33855 f51f341a4d9cb315ba830d242e246442458bfb1c
child 33857 f4b9e739d180fcd1f813978893b7d9907737193b
push id388
push userclokep@gmail.com
push dateMon, 28 Jan 2019 20:54:56 +0000
reviewersmkmelin
bugs1511950
Bug 1511950 - Add GetCharsetAlias() call to JS Mime. r=mkmelin
mailnews/intl/test/unit/CharsetConversionTests.js
mailnews/intl/test/unit/test_decode_utf-7_internal.js
mailnews/mime/src/jsmime.jsm
mailnews/mime/test/unit/test_jsmime_charset.js
--- a/mailnews/intl/test/unit/CharsetConversionTests.js
+++ b/mailnews/intl/test/unit/CharsetConversionTests.js
@@ -58,22 +58,22 @@ function testEncodeAliases()
   var converter = CreateScriptableConverter();
   for (var i = 0; i < aliases.length; ++i) {
     checkEncode(converter, aliases[i], inString, expectedString);
   }
 }
 
 function testDecodeAliasesInternal()
 {
-  var converter = CreateScriptableConverter();
+  let manager = Cc['@mozilla.org/charset-converter-manager;1']
+                  .getService(Ci.nsICharsetConverterManager);
+  let converter = CreateScriptableConverter();
   converter.isInternal = true;
-  for (var i = 0; i < aliases.length; ++i) {
-    if (aliases[i].toLowerCase() == "utf-7") {
-      let manager = Cc['@mozilla.org/charset-converter-manager;1']
-                      .getService(Ci.nsICharsetConverterManager);
+  for (let i = 0; i < aliases.length; ++i) {
+    if (manager.getCharsetAlias(aliases[i]).toLowerCase() == "utf-7") {
       Assert.equal(manager.utf7ToUnicode(inString), expectedString);
     } else {
       checkDecode(converter, aliases[i], inString, expectedString);
     }
   }
 }
 
 function testEncodeAliasesInternal()
--- a/mailnews/intl/test/unit/test_decode_utf-7_internal.js
+++ b/mailnews/intl/test/unit/test_decode_utf-7_internal.js
@@ -1,13 +1,13 @@
 // Tests conversion from UTF-7 to Unicode.
 
 load('CharsetConversionTests.js');
 
 var inString = "+LGI--+ITIipSIp- +AocCeQ-oddns +Ad0CjQ- s+ATECZQKH- p+AlAB3QJ5- u+AlACVA- no+Ao4- +Al8-I";
 
 var expectedString = "\u2C62-\u2132\u22A5\u2229 \u0287\u0279oddns \u01DD\u028D s\u0131\u0265\u0287 p\u0250\u01DD\u0279 u\u0250\u0254 no\u028E \u025FI";
 
-var aliases = [ "UTF-7", "utf-7" ];
-
+var aliases = [ "UTF-7", "utf-7", "x-unicode-2-0-utf-7", "unicode-2-0-utf-7",
+                "unicode-1-1-utf-7", "csunicode11utf7" ];
 function run_test() {
   testDecodeAliasesInternal();
 }
--- a/mailnews/mime/src/jsmime.jsm
+++ b/mailnews/mime/src/jsmime.jsm
@@ -19,23 +19,18 @@ var EXPORTED_SYMBOLS = ["jsmime"];
 function bytesToString(buffer) {
   var string = '';
   for (var i = 0; i < buffer.length; i++)
     string += String.fromCharCode(buffer[i]);
   return string;
 }
 
 // Our UTF-7 decoder.
-function UTF7TextDecoder(label, options = {}) {
-  this.manager = Cc["@mozilla.org/charset-converter-manager;1"]
-                   .createInstance(Ci.nsICharsetConverterManager);
-  // The following will throw if the charset is unknown.
-  let charset = this.manager.getCharsetAlias(label);
-  if (charset.toLowerCase() != "utf-7")
-    throw new Error("UTF7TextDecoder: This code should never be reached for " + label);
+function UTF7TextDecoder(options = {}, manager) {
+  this.manager = manager;
   this.collectInput = "";
 }
 UTF7TextDecoder.prototype = {
   // Since the constructor checked, this will only be called for UTF-7.
   decode: function (input, options = {}) {
     let more = 'stream' in options ? options.stream : false;
     // There are cases where this is called without input.
     if (!input)
@@ -43,22 +38,23 @@ UTF7TextDecoder.prototype = {
     this.collectInput += bytesToString(input);
     if (more)
       return "";
     return this.manager.utf7ToUnicode(this.collectInput);
   },
 };
 
 function MimeTextDecoder(charset, options) {
-  try {
-    return new TextDecoder(charset, options);
-  } catch (e) {
-    // If TextDecoder fails, it must be UTF-7 or an invalid charset.
-    return new UTF7TextDecoder(charset, options);
-  }
+  let manager = Cc["@mozilla.org/charset-converter-manager;1"]
+                  .createInstance(Ci.nsICharsetConverterManager);
+  // The following will throw if the charset is unknown.
+  let newCharset = manager.getCharsetAlias(charset);
+  if (newCharset.toLowerCase() == "utf-7")
+    return new UTF7TextDecoder(options, manager);
+  return new TextDecoder(newCharset, options);
 }
 
 
 // The following code loads custom MIME encoders.
 var CATEGORY_NAME = "custom-mime-encoder";
 Services.obs.addObserver(function (subject, topic, data) {
   subject = subject.QueryInterface(Ci.nsISupportsCString)
                    .data;
--- a/mailnews/mime/test/unit/test_jsmime_charset.js
+++ b/mailnews/mime/test/unit/test_jsmime_charset.js
@@ -10,16 +10,21 @@ ChromeUtils.import("resource:///modules/
 var tests = [
   ["=?UTF-7?Q?+AKM-1?=", "\u00A31"],
   ["=?UTF-7?Q?+AK?= =?UTF-7?Q?M-1?=", "\u00A31"],
   ["=?UTF-8?Q?=C2?=", "\uFFFD"], // Replacement character for invalid input.
   ["=?NotARealCharset?Q?text?=", "=?NotARealCharset?Q?text?="],
   ["\xC2\xA31", "\u00A31", "ISO-8859-2"],
   ["\xA31", "\u01411", "ISO-8859-2"],
   ["\xC21", "\u00C21", "ISO-8859-1"],
+  // "Here comes the text." in Japanese encoded in Shift_JIS, also using Thunderbird's alias cp932.
+  ["=?shift_jis?Q?=82=b1=82=b1=82=c9=96=7b=95=b6=82=aa=82=ab=82=dc=82=b7=81=42?=", "ここに本文がきます。"],
+  ["=?shift_jis?B?grGCsYLJlnuVtoKqgquC3IK3gUI=?=", "ここに本文がきます。"],
+  ["=?cp932?Q?=82=b1=82=b1=82=c9=96=7b=95=b6=82=aa=82=ab=82=dc=82=b7=81=42?=", "ここに本文がきます。"],
+  ["=?cp932?B?grGCsYLJlnuVtoKqgquC3IK3gUI=?=", "ここに本文がきます。"],
 ];
 
 function run_test() {
   for (let test of tests) {
     dump("Testing message " + test[0]);
     let value = test[0];
     if (test.length > 2)
       value = jsmime.headerparser.convert8BitHeader(value, test[2])