зеркало из https://github.com/mozilla/gecko-dev.git
Bug 511521 - downloading file with RTL override (RLO) presents conflicting filenames; r=bzbarsky
This commit is contained in:
Родитель
f6fbe9828b
Коммит
8204627bef
|
@ -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 + "\"");
|
||||
}
|
Загрузка…
Ссылка в новой задаче