Bug 359809: properly escape keyword searches when alternative character sets are specified, r=gavin
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2280,19 +2280,25 @@ function getShortcutOrURI(aURL, aPostDat
// Try to get the saved character-set.
try {
// makeURI throws if URI is invalid.
// Will return an empty string if character-set is not found.
charset = PlacesUtils.history.getCharsetForURI(makeURI(shortcutURL));
} catch (e) {}
}
+ // encodeURIComponent produces UTF-8, and cannot be used for other charsets.
+ // escape() works in those cases, but it doesn't uri-encode +, @, and /.
+ // Therefore we need to manually replace these ASCII characters by their
+ // encodeURIComponent result, to match the behavior of nsEscape() with
+ // url_XPAlphas
var encodedParam = "";
- if (charset)
- encodedParam = escape(convertFromUnicode(charset, param));
+ if (charset && charset != "UTF-8")
+ encodedParam = escape(convertFromUnicode(charset, param)).
+ replace(/[+@\/]+/g, encodeURIComponent);
else // Default charset is UTF-8
encodedParam = encodeURIComponent(param);
shortcutURL = shortcutURL.replace(/%s/g, encodedParam).replace(/%S/g, param);
if (/%s/i.test(postData)) // POST keyword
aPostDataRef.value = getPostDataStream(postData, param, encodedParam,
"application/x-www-form-urlencoded");
--- a/browser/base/content/test/browser_getshortcutoruri.js
+++ b/browser/base/content/test/browser_getshortcutoruri.js
@@ -69,16 +69,24 @@ var testData = [
// Test escaping (%s = escaped, %S = raw)
// UTF-8 default
[new bmKeywordData("bmget-escaping", "http://bmget/?esc=%s&raw=%S", null, "foé"),
new keywordResult("http://bmget/?esc=fo%C3%A9&raw=foé", null)],
// Explicitly-defined ISO-8859-1
[new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "foé"),
new keywordResult("http://bmget/?esc=fo%E9&raw=foé", null)],
+
+ // Bug 359809: Test escaping +, /, and @
+ // UTF-8 default
+ [new bmKeywordData("bmget-escaping", "http://bmget/?esc=%s&raw=%S", null, "+/@"),
+ new keywordResult("http://bmget/?esc=%2B%2F%40&raw=+/@", null)],
+ // Explicitly-defined ISO-8859-1
+ [new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "+/@"),
+ new keywordResult("http://bmget/?esc=%2B%2F%40&raw=+/@", null)],
];
function test() {
setupKeywords();
for each (var item in testData) {
var [data, result] = item;