Bug 1338758 - Handle success codes from nsIUnicodeDecoder in nsTextToSubURI::UnEscapeNonAsciiURI. r=m_kato a=jcristau
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Sat, 11 Feb 2017 20:40:58 +0900
changeset 378434 64915a68d19056e45c4c1ad1bd75593fdbb8b4c7
parent 378433 4f8cf5f4df94aa9c9b83c11a8985f70f01a17fed
child 378435 8e53e1a9964baa87965e59d53d2882deff62d3ff
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato, jcristau
bugs1338758
milestone53.0a2
Bug 1338758 - Handle success codes from nsIUnicodeDecoder in nsTextToSubURI::UnEscapeNonAsciiURI. r=m_kato a=jcristau MozReview-Commit-ID: 43jAOFPYMeT
intl/uconv/nsTextToSubURI.cpp
intl/uconv/tests/unit/test_bug699673.js
intl/uconv/tests/unit/test_unEscapeNonAsciiURI.js
intl/uconv/tests/unit/xpcshell.ini
--- a/intl/uconv/nsTextToSubURI.cpp
+++ b/intl/uconv/nsTextToSubURI.cpp
@@ -257,32 +257,37 @@ NS_IMETHODIMP  nsTextToSubURI::UnEscapeU
   }
   const nsPromiseFlatString& unescapedResult = PromiseFlatString(_retval);
   nsString reescapedSpec;
   _retval = NS_EscapeURL(unescapedResult, mUnsafeChars, reescapedSpec);
 
   return NS_OK;
 }
 
-NS_IMETHODIMP  nsTextToSubURI::UnEscapeNonAsciiURI(const nsACString & aCharset, 
-                                                   const nsACString & aURIFragment, 
-                                                   nsAString &_retval)
+NS_IMETHODIMP
+nsTextToSubURI::UnEscapeNonAsciiURI(const nsACString& aCharset,
+                                    const nsACString& aURIFragment,
+                                    nsAString& _retval)
 {
   nsAutoCString unescapedSpec;
   NS_UnescapeURL(PromiseFlatCString(aURIFragment),
                  esc_AlwaysCopy | esc_OnlyNonASCII, unescapedSpec);
   // leave the URI as it is if it's not UTF-8 and aCharset is not a ASCII
-  // superset since converting "http:" with such an encoding is always a bad 
+  // superset since converting "http:" with such an encoding is always a bad
   // idea.
   if (!IsUTF8(unescapedSpec) && 
       (aCharset.LowerCaseEqualsLiteral("utf-16") ||
        aCharset.LowerCaseEqualsLiteral("utf-16be") ||
        aCharset.LowerCaseEqualsLiteral("utf-16le") ||
        aCharset.LowerCaseEqualsLiteral("utf-7") ||
        aCharset.LowerCaseEqualsLiteral("x-imap4-modified-utf7"))){
     CopyASCIItoUTF16(aURIFragment, _retval);
     return NS_OK;
   }
 
-  return convertURItoUnicode(PromiseFlatCString(aCharset), unescapedSpec, _retval);
+  nsresult rv = convertURItoUnicode(PromiseFlatCString(aCharset),
+                                    unescapedSpec, _retval);
+  // NS_OK_UDEC_MOREINPUT is a success code, so caller can't catch the error
+  // if the string ends with a valid (but incomplete) sequence.
+  return rv == NS_OK_UDEC_MOREINPUT ? NS_ERROR_UDEC_ILLEGALINPUT : rv;
 }
 
 //----------------------------------------------------------------------
rename from intl/uconv/tests/unit/test_bug699673.js
rename to intl/uconv/tests/unit/test_unEscapeNonAsciiURI.js
--- a/intl/uconv/tests/unit/test_bug699673.js
+++ b/intl/uconv/tests/unit/test_unEscapeNonAsciiURI.js
@@ -1,7 +1,46 @@
-// Tests whether nsTextToSubURI does UTF-16 unescaping (it shouldn't)
- function run_test()
-{
-  var testURI = "data:text/html,%FE%FF";
-  var textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"].getService(Components.interfaces.nsITextToSubURI);
+// Tests for nsITextToSubURI.unEscapeNonAsciiURI
+function run_test() {
+  const textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"].getService(Components.interfaces.nsITextToSubURI);
+
+  // Tests whether nsTextToSubURI does UTF-16 unescaping (it shouldn't)
+  const testURI = "data:text/html,%FE%FF";
   do_check_eq(textToSubURI.unEscapeNonAsciiURI("UTF-16", testURI), testURI);
+
+  // Tests whether incomplete multibyte sequences throw.
+  const tests = [{
+    input: "http://example.com/?p=%E9",
+    throws: Components.results.NS_ERROR_ILLEGAL_INPUT,
+  }, {
+    input: "http://example.com/?p=%E9%80",
+    throws: Components.results.NS_ERROR_ILLEGAL_INPUT,
+  }, {
+    input: "http://example.com/?p=%E9%80%80",
+    expected: "http://example.com/?p=\u9000",
+  }, {
+    input: "http://example.com/?p=%E9e",
+    throws: Components.results.NS_ERROR_ILLEGAL_INPUT,
+  }, {
+    input: "http://example.com/?p=%E9%E9",
+    throws: Components.results.NS_ERROR_ILLEGAL_INPUT,
+  }, {
+    input: "http://example.com/?name=M%FCller/",
+    throws: Components.results.NS_ERROR_ILLEGAL_INPUT,
+  }, {
+    input: "http://example.com/?name=M%C3%BCller/",
+    expected: "http://example.com/?name=Müller/",
+  }];
+
+  for (const t of tests) {
+    if (t.throws !== undefined) {
+      let thrown = undefined;
+      try {
+        textToSubURI.unEscapeNonAsciiURI("UTF-8", t.input);
+      } catch (e) {
+        thrown = e.result;
+      }
+      do_check_eq(thrown, t.throws);
+    } else {
+      do_check_eq(textToSubURI.unEscapeNonAsciiURI("UTF-8", t.input), t.expected);
+    }
+  }
 }
--- a/intl/uconv/tests/unit/xpcshell.ini
+++ b/intl/uconv/tests/unit/xpcshell.ini
@@ -20,20 +20,20 @@ support-files =
 [test_bug381412.js]
 [test_bug396637.js]
 [test_bug399257.js]
 [test_bug457886.js]
 [test_bug522931.js]
 [test_bug563283.js]
 [test_bug563618.js]
 [test_bug601429.js]
-[test_bug699673.js]
 [test_bug715319.euc_jp.js]
 [test_bug715319.gb2312.js]
 [test_bug715319.dbcs.js]
+[test_bug1008832.js]
 [test_charset_conversion.js]
 [test_decode_8859-1.js]
 [test_decode_8859-10.js]
 [test_decode_8859-11.js]
 [test_decode_8859-13.js]
 [test_decode_8859-14.js]
 [test_decode_8859-15.js]
 [test_decode_8859-2.js]
@@ -110,12 +110,12 @@ support-files =
 [test_encode_x_mac_greek.js]
 [test_encode_x_mac_gujarati.js]
 [test_encode_x_mac_gurmukhi.js]
 [test_encode_x_mac_hebrew.js]
 [test_encode_x_mac_icelandic.js]
 [test_encode_macintosh.js]
 [test_encode_x_mac_romanian.js]
 [test_encode_x_mac_turkish.js]
+[test_input_stream.js]
+[test_unEscapeNonAsciiURI.js]
+[test_unmapped.js]
 [test_utf8_illegals.js]
-[test_input_stream.js]
-[test_bug1008832.js]
-[test_unmapped.js]