Bug 1178166 - Handle gbk encoded login.ini from 360 secure browser. r=mak draft
authorHector Zhao <bzhao@mozilla.com>
Thu, 25 Jun 2015 15:18:44 +0800
changeset 276043 8fc881e9a3b06a8ae2c41c1c09af1971ed71c3ae
parent 275891 e7e69cc8c07bfe4a069920f883ee970c73a9dfac
child 507295 c438ca59fbb336052db747134b4b922ef10d2d2e
push id3250
push userbzhao@mozilla.com
push dateTue, 07 Jul 2015 12:54:37 +0000
reviewersmak
bugs1178166
milestone42.0a1
Bug 1178166 - Handle gbk encoded login.ini from 360 secure browser. r=mak
browser/components/migration/360seProfileMigrator.js
--- a/browser/components/migration/360seProfileMigrator.js
+++ b/browser/components/migration/360seProfileMigrator.js
@@ -3,25 +3,68 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource:///modules/MigrationUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Sqlite",
                                   "resource://gre/modules/Sqlite.jsm");
 
+function copyToTempUTF8File(file, charset) {
+  let inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
+                      .createInstance(Ci.nsIFileInputStream);
+  inputStream.init(file, -1, -1, 0);
+  let inputStr = NetUtil.readInputStreamToString(
+    inputStream, inputStream.available(), { charset });
+
+  /*
+   * Adding a random element to reduce the likelihood of hitting a name
+   * collision in createUnique.
+   */
+  let rand = Math.floor(Math.random() * Math.pow(2, 15));
+  let leafName = "mozilla-temp-" + rand;
+  let tempUTF8File = FileUtils.getFile(
+    "TmpD", ["mozilla-temp-files", leafName], true);
+  tempUTF8File.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
+
+  let out = FileUtils.openAtomicFileOutputStream(tempUTF8File);
+  try {
+    let bufferedOut = Cc["@mozilla.org/network/buffered-output-stream;1"]
+                        .createInstance(Ci.nsIBufferedOutputStream);
+    bufferedOut.init(out, 4096);
+    try {
+      let converterOut = Cc["@mozilla.org/intl/converter-output-stream;1"]
+                           .createInstance(Ci.nsIConverterOutputStream);
+      converterOut.init(bufferedOut, "utf-8", 0, 0x0000);
+      try {
+        converterOut.writeString(inputStr || "");
+        bufferedOut.QueryInterface(Ci.nsISafeOutputStream).finish();
+      } finally {
+        converterOut.close();
+      }
+    } finally {
+      bufferedOut.close();
+    }
+  } finally {
+    out.close();
+  }
+
+  return tempUTF8File;
+}
+
 function parseINIStrings(file) {
   let factory = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].
                 getService(Ci.nsIINIParserFactory);
   let parser = factory.createINIParser(file);
   let obj = {};
   let sections = parser.getSections();
   while (sections.hasMore()) {
     let section = sections.getNext();
@@ -180,17 +223,23 @@ Object.defineProperty(Qihoo360seProfileM
       let loginIni = this._usersDir.clone();
       loginIni.append("login.ini");
       if (!loginIni.exists()) {
         throw new Error("360 Secure Browser's 'login.ini' does not exist.");
       }
       if (!loginIni.isReadable()) {
         throw new Error("360 Secure Browser's 'login.ini' file could not be read.");
       }
-      let loginIniObj = parseINIStrings(loginIni);
+
+      let loginIniInUtf8 = copyToTempUTF8File(loginIni, "gbk");
+      let loginIniObj = parseINIStrings(loginIniInUtf8);
+      try {
+        loginIniInUtf8.remove(false);
+      } catch(ex) {}
+
       let nowLoginEmail = loginIniObj.NowLogin && loginIniObj.NowLogin.email;
 
       /*
        * NowLogin section may:
        * 1. be missing or without email, before any user logs in.
        * 2. represents the current logged in user
        * 3. represents the most recent logged in user
        *