Bug 511521 - downloading file with RTL override (RLO) presents conflicting filenames; r=bzbarsky

This commit is contained in:
Ehsan Akhgari 2009-08-25 13:52:47 +04:30
Родитель f6fbe9828b
Коммит 8204627bef
4 изменённых файлов: 197 добавлений и 0 удалений

Просмотреть файл

@ -1119,6 +1119,19 @@ nsExternalAppHandler::nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo,
// replace platform specific path separator and illegal characters to avoid any confusion
mSuggestedFileName.ReplaceChar(FILE_PATH_SEPARATOR FILE_ILLEGAL_CHARACTERS, '_');
mTempFileExtension.ReplaceChar(FILE_PATH_SEPARATOR FILE_ILLEGAL_CHARACTERS, '_');
// Remove unsafe bidi characters which might have spoofing implications (bug 511521).
const PRUnichar unsafeBidiCharacters[] = {
PRUnichar(0x202a), // Left-to-Right Embedding
PRUnichar(0x202b), // Right-to-Left Embedding
PRUnichar(0x202c), // Pop Directional Formatting
PRUnichar(0x202d), // Left-to-Right Override
PRUnichar(0x202e) // Right-to-Left Override
};
for (int i = 0; i < NS_ARRAY_LENGTH(unsafeBidiCharacters); ++i) {
mSuggestedFileName.ReplaceChar(unsafeBidiCharacters[i], '_');
mTempFileExtension.ReplaceChar(unsafeBidiCharacters[i], '_');
}
// Make sure extension is correct.
EnsureSuggestedFileName();

Просмотреть файл

@ -46,8 +46,10 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
test_handlerApps.xhtml \
test_unsafeBidiChars.xhtml \
handlerApps.js \
handlerApp.xhtml \
unsafeBidiFileName.sjs \
$(NULL)
libs:: $(_TEST_FILES)

Просмотреть файл

@ -0,0 +1,135 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test for Handling of unsafe bidi chars</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<iframe id="test"></iframe>
<script type="text/javascript">
<![CDATA[
var unsafeBidiChars = {
LRE: "\xe2\x80\xaa",
RLE: "\xe2\x80\xab",
PDF: "\xe2\x80\xac",
LRO: "\xe2\x80\xad",
RLO: "\xe2\x80\xae"
};
var tests = [
"{1}.test",
"{1}File.test",
"Fi{1}le.test",
"File{1}.test",
"File.{1}test",
"File.te{1}st",
"File.test{1}",
"File.{1}",
];
function replace(name, x) {
return name.replace(/\{1\}/, x);
}
function sanitize(name) {
return replace(name, '_');
}
var gTests = [];
function make_test(param, expected) {
gTests.push({
param: param,
expected: expected,
});
}
var iframe = document.getElementById("test");
var gCallback = null;
function run_test(test, cb) {
iframe.src = "unsafeBidiFileName.sjs?name=" + encodeURIComponent(test.param);
gCallback = cb;
}
var gCounter = -1;
function run_next_test() {
if (++gCounter == gTests.length)
finish_test();
else
run_test(gTests[gCounter], run_next_test);
}
SimpleTest.waitForExplicitFinish();
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const HELPERAPP_DIALOG_CID = "@mozilla.org/helperapplauncherdialog;1";
const HELPERAPP_DIALOG_ID = Components.ID(Components.classes[HELPERAPP_DIALOG_CID].number);
const HELPERAPP_DIALOG_DESCRIPTION = "Helper App Dialog Test Service";
function HelperAppLauncherDialog() {}
HelperAppLauncherDialog.prototype = {
REASON_CANTHANDLE: 0,
REASON_SERVERREQUEST: 1,
REASON_TYPESNIFFED: 2,
show: function(aLauncher, aWindowContext, aReason) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var test = gTests[gCounter];
is(aLauncher.suggestedFileName, test.expected,
"The filename should be correctly sanitized");
gCallback();
},
promptForSaveToFile: function(aLauncher, aWindowContext, aDefaultFileName, aSuggestedFileExtension, aForcePrompt) {
return null;
},
QueryInterface: function(aIID) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIHelperAppLauncherDialog))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};
var factory = {
createInstance: function(aOuter, aIID) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
if (aOuter != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return new HelperAppLauncherDialog().QueryInterface(aIID);
}
};
Components.manager
.QueryInterface(Components.interfaces.nsIComponentRegistrar)
.registerFactory(HELPERAPP_DIALOG_ID,
HELPERAPP_DIALOG_DESCRIPTION,
HELPERAPP_DIALOG_CID,
factory);
function finish_test() {
Components.manager
.QueryInterface(Components.interfaces.nsIComponentRegistrar)
.unregisterFactory(HELPERAPP_DIALOG_ID,
factory);
SimpleTest.finish();
}
var i,j;
for (i = 0; i < tests.length; ++i) {
for (j in unsafeBidiChars) {
make_test(replace(tests[i], unsafeBidiChars[j]),
sanitize(tests[i]));
}
}
run_next_test();
]]>
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,47 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Handler Apps Tests.
*
* The Initial Developer of the Original Code is
* Ehsan Akhgari.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, 200, "OK");
if (!request.queryString.match(/^name=/))
return;
var name = decodeURIComponent(request.queryString.substring(5));
response.setHeader("Content-Type", "application/octet-stream; name=\"" + name + "\"");
response.setHeader("Content-Disposition", "inline; filename=\"" + name + "\"");
}