From 2158e7e5725fb136c6fee17e4809400194294d62 Mon Sep 17 00:00:00 2001 From: Justin Dolske Date: Mon, 25 Aug 2008 15:32:59 -0700 Subject: [PATCH] Bug 451155 ? Password manager does not work correctly on IDN site whose name contains any character over U+0100. r=gavin --- .../components/passwordmgr/src/storage-Legacy.js | 26 +++++++++----- .../passwordmgr/src/storage-mozStorage.js | 22 +++++++----- .../passwordmgr/test/unit/test_storage_legacy_3.js | 41 +++++++++++++++++++++- .../test/unit/test_storage_mozStorage_3.js | 40 +++++++++++++++++++++ 4 files changed, 110 insertions(+), 19 deletions(-) diff --git a/toolkit/components/passwordmgr/src/storage-Legacy.js b/toolkit/components/passwordmgr/src/storage-Legacy.js index fea883126..f6e0c262c 100644 --- a/toolkit/components/passwordmgr/src/storage-Legacy.js +++ b/toolkit/components/passwordmgr/src/storage-Legacy.js @@ -74,6 +74,16 @@ LoginManagerStorage_legacy.prototype = { return this.__decoderRing; }, + __utfConverter : null, // UCS2 <--> UTF8 string conversion + get _utfConverter() { + if (!this.__utfConverter) { + this.__utfConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. + createInstance(Ci.nsIScriptableUnicodeConverter); + this.__utfConverter.charset = "UTF-8"; + } + return this.__utfConverter; + }, + __profileDir: null, // nsIFile for the user's profile dir get _profileDir() { if (!this.__profileDir) { @@ -852,6 +862,7 @@ LoginManagerStorage_legacy.prototype = { do { var hasMore = lineStream.readLine(line); + line.value = this._utfConverter.ConvertToUnicode(line.value); switch (parseState) { // Check file header @@ -1021,7 +1032,10 @@ LoginManagerStorage_legacy.prototype = { * master password if prompted). */ _writeFile : function () { + var converter = this._utfConverter; function writeLine(data) { + data = converter.ConvertFromUnicode(data); + data += converter.Finish(); data += "\r\n"; outputStream.write(data, data.length); } @@ -1243,11 +1257,8 @@ LoginManagerStorage_legacy.prototype = { var cipherText = null, userCanceled = false; try { - var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. - createInstance(Ci.nsIScriptableUnicodeConverter); - converter.charset = "UTF-8"; - var plainOctet = converter.ConvertFromUnicode(plainText); - plainOctet += converter.Finish(); + var plainOctet = this._utfConverter.ConvertFromUnicode(plainText); + plainOctet += this._utfConverter.Finish(); cipherText = this._decoderRing.encryptString(plainOctet); } catch (e) { this.log("Failed to encrypt string. (" + e.name + ")"); @@ -1288,10 +1299,7 @@ LoginManagerStorage_legacy.prototype = { } else { plainOctet = this._decoderRing.decryptString(cipherText); } - var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. - createInstance(Ci.nsIScriptableUnicodeConverter); - converter.charset = "UTF-8"; - plainText = converter.ConvertToUnicode(plainOctet); + plainText = this._utfConverter.ConvertToUnicode(plainOctet); } catch (e) { this.log("Failed to decrypt string: " + cipherText + " (" + e.name + ")"); diff --git a/toolkit/components/passwordmgr/src/storage-mozStorage.js b/toolkit/components/passwordmgr/src/storage-mozStorage.js index ad5e3b6d5..2a1514e0e 100644 --- a/toolkit/components/passwordmgr/src/storage-mozStorage.js +++ b/toolkit/components/passwordmgr/src/storage-mozStorage.js @@ -70,6 +70,16 @@ LoginManagerStorage_mozStorage.prototype = { return this.__decoderRing; }, + __utfConverter : null, // UCS2 <--> UTF8 string conversion + get _utfConverter() { + if (!this.__utfConverter) { + this.__utfConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. + createInstance(Ci.nsIScriptableUnicodeConverter); + this.__utfConverter.charset = "UTF-8"; + } + return this.__utfConverter; + }, + __profileDir: null, // nsIFile for the user's profile dir get _profileDir() { if (!this.__profileDir) @@ -850,11 +860,8 @@ LoginManagerStorage_mozStorage.prototype = { let cipherText = null, userCanceled = false; try { - let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. - createInstance(Ci.nsIScriptableUnicodeConverter); - converter.charset = "UTF-8"; - let plainOctet = converter.ConvertFromUnicode(plainText); - plainOctet += converter.Finish(); + let plainOctet = this._utfConverter.ConvertFromUnicode(plainText); + plainOctet += this._utfConverter.Finish(); cipherText = this._decoderRing.encryptString(plainOctet); } catch (e) { this.log("Failed to encrypt string. (" + e.name + ")"); @@ -887,10 +894,7 @@ LoginManagerStorage_mozStorage.prototype = { try { let plainOctet = this._decoderRing.decryptString(cipherText); - let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] - .createInstance(Ci.nsIScriptableUnicodeConverter); - converter.charset = "UTF-8"; - plainText = converter.ConvertToUnicode(plainOctet); + plainText = this._utfConverter.ConvertToUnicode(plainOctet); } catch (e) { this.log("Failed to decrypt string: " + cipherText + " (" + e.name + ")"); diff --git a/toolkit/components/passwordmgr/test/unit/test_storage_legacy_3.js b/toolkit/components/passwordmgr/test/unit/test_storage_legacy_3.js index 8bba470e1..01860439b 100644 --- a/toolkit/components/passwordmgr/test/unit/test_storage_legacy_3.js +++ b/toolkit/components/passwordmgr/test/unit/test_storage_legacy_3.js @@ -519,7 +519,7 @@ testnum++; testdesc = "ensure internal login objects not shared with callers." storage = LoginTest.initStorage(INDIR, "signons-empty.txt", - OUTDIR, "output-394610-5.txt"); + OUTDIR, "output-449701.txt"); LoginTest.checkStorageData(storage, [], []); // dummyuser1 == dummyuser2 @@ -547,6 +547,45 @@ var obtainedLogin2 = logins[0]; do_check_neq(obtainedLogin1.usernameField, obtainedLogin2.usernameField); +/* + * ---------------------- Bug 451155 ---------------------- + * Ensure that we don't mangle strings when then contain + * UCS2 characters above U+00FF. + */ + +/* ========== 15 ========== */ +testnum++; +testdesc = "ensure UCS2 strings don't get mangled." + +storage = LoginTest.initStorage(INDIR, "signons-empty.txt", + OUTDIR, "output-451155.txt"); +LoginTest.checkStorageData(storage, [], []); + +var testString = String.fromCharCode(355, 277, 349, 357, 533, 537, 101, 345, 185); + +var utfHost = "http://" + testString + ".org"; +var utfUser1 = Cc["@mozilla.org/login-manager/loginInfo;1"]. + createInstance(Ci.nsILoginInfo); +var utfUser2 = Cc["@mozilla.org/login-manager/loginInfo;1"]. + createInstance(Ci.nsILoginInfo); + +utfUser1.init("http://" + testString + ".org", + "http://" + testString + ".org", null, + testString, testString, testString, testString); +utfUser2.init("http://realm.check.net", null, "realm " + testString + " test", + "user", "pass", "", ""); + +storage.addLogin(utfUser1); +storage.addLogin(utfUser2); +storage.setLoginSavingEnabled(utfHost, false); + +LoginTest.checkStorageData(storage, [utfHost], [utfUser1, utfUser2]); + +testdesc = "[flush and reload for verification]" +storage = LoginTest.reloadStorage(OUTDIR, "output-451155.txt"); +LoginTest.checkStorageData(storage, [utfHost], [utfUser1, utfUser2]); + + /* ========== end ========== */ } catch (e) { throw ("FAILED in test #" + testnum + " -- " + testdesc + ": " + e); diff --git a/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage_3.js b/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage_3.js index 3a74dcdf3..9828af8db 100644 --- a/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage_3.js +++ b/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage_3.js @@ -522,6 +522,46 @@ nullUser.password = "password"; LoginTest.deleteFile(OUTDIR, "output-394610-4.sqlite"); +/* + * ---------------------- Bug 451155 ---------------------- + * Ensure that we don't mangle strings when then contain + * UCS2 characters above U+00FF. + */ + +/* ========== 14 ========== */ +testnum++; +testdesc = "ensure UCS2 strings don't get mangled." + +storage = LoginTest.initStorage(INDIR, "signons-empty.txt", + OUTDIR, "output-451155.sqlite"); +LoginTest.checkStorageData(storage, [], []); + +var testString = String.fromCharCode(355, 277, 349, 357, 533, 537, 101, 345, 185); + +var utfHost = "http://" + testString + ".org"; +var utfUser1 = Cc["@mozilla.org/login-manager/loginInfo;1"]. + createInstance(Ci.nsILoginInfo); +var utfUser2 = Cc["@mozilla.org/login-manager/loginInfo;1"]. + createInstance(Ci.nsILoginInfo); + +utfUser1.init("http://" + testString + ".org", + "http://" + testString + ".org", null, + testString, testString, testString, testString); +utfUser2.init("http://realm.check.net", null, "realm " + testString + " test", + "user", "pass", "", ""); + +storage.addLogin(utfUser1); +storage.addLogin(utfUser2); +storage.setLoginSavingEnabled(utfHost, false); + +LoginTest.checkStorageData(storage, [utfHost], [utfUser1, utfUser2]); + +testdesc = "[flush and reload for verification]" +storage = LoginTest.reloadStorage(OUTDIR, "output-451155.sqlite"); +LoginTest.checkStorageData(storage, [utfHost], [utfUser1, utfUser2]); + + + /* ========== end ========== */ } catch (e) { throw ("FAILED in test #" + testnum + " -- " + testdesc + ": " + e); -- 2.11.4.GIT