зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1746052, use validateFileNameForSaving in DownloadPaths.sanitize with flags to emulate something similar to the existing behaviour, r=mak
Differential Revision: https://phabricator.services.mozilla.com/D138738
This commit is contained in:
Родитель
2be09b9192
Коммит
660ff47e74
|
@ -100,7 +100,7 @@ function test() {
|
|||
aCallback();
|
||||
};
|
||||
|
||||
launcherDialog.promptForSaveToFileAsync(launcher, aWin, null, null, null);
|
||||
launcherDialog.promptForSaveToFileAsync(launcher, aWin, "", "", false);
|
||||
}
|
||||
|
||||
testOnWindow(false, function(win, downloadDir) {
|
||||
|
|
|
@ -10,83 +10,22 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["DownloadPaths"];
|
||||
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"AppConstants",
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
|
||||
/**
|
||||
* Platform-dependent regular expression used by the "sanitize" method.
|
||||
*/
|
||||
XPCOMUtils.defineLazyGetter(this, "gConvertToSpaceRegExp", () => {
|
||||
// Note: we remove colons everywhere to avoid issues in subresource URL
|
||||
// parsing, as well as filename restrictions on some OSes (see bug 1562176).
|
||||
/* eslint-disable no-control-regex */
|
||||
switch (AppConstants.platform) {
|
||||
// On mobile devices, the file system may be very limited in what it
|
||||
// considers valid characters. To avoid errors, sanitize conservatively.
|
||||
case "android":
|
||||
return /[\x00-\x1f\x7f-\x9f:*?|"<>;,+=\[\]]+/g;
|
||||
case "win":
|
||||
return /[\x00-\x1f\x7f-\x9f:*?|]+/g;
|
||||
default:
|
||||
return /[\x00-\x1f\x7f-\x9f:]+/g;
|
||||
}
|
||||
/* eslint-enable no-control-regex */
|
||||
});
|
||||
|
||||
var DownloadPaths = {
|
||||
/**
|
||||
* Sanitizes an arbitrary string for use as the local file name of a download.
|
||||
* The input is often a document title or a manually edited name. The output
|
||||
* can be an empty string if the input does not include any valid character.
|
||||
*
|
||||
* The length of the resulting string is not limited, because restrictions
|
||||
* apply to the full path name after the target folder has been added.
|
||||
*
|
||||
* Splitting the base name and extension to add a counter or to identify the
|
||||
* file type should only be done after the sanitization process, because it
|
||||
* can alter the final part of the string or remove leading dots.
|
||||
*
|
||||
* Runs of slashes and backslashes are replaced with an underscore.
|
||||
*
|
||||
* On Windows, the angular brackets `<` and `>` are replaced with parentheses,
|
||||
* and double quotes are replaced with single quotes.
|
||||
*
|
||||
* Runs of control characters are replaced with a space. On Mac, colons are
|
||||
* also included in this group. On Windows, stars, question marks, and pipes
|
||||
* are additionally included. On Android, semicolons, commas, plus signs,
|
||||
* equal signs, and brackets are additionally included.
|
||||
*
|
||||
* Leading and trailing dots and whitespace are removed on all platforms. This
|
||||
* avoids the accidental creation of hidden files on Unix and invalid or
|
||||
* inaccessible file names on Windows. These characters are not removed when
|
||||
* located at the end of the base name or at the beginning of the extension.
|
||||
* Sanitizes an arbitrary string via mimeSvc.validateFileNameForSaving.
|
||||
*
|
||||
* @param {string} leafName The full leaf name to sanitize
|
||||
* @param {boolean} [compressWhitespaces] Whether consecutive whitespaces
|
||||
* should be compressed.
|
||||
*/
|
||||
sanitize(leafName, { compressWhitespaces = true } = {}) {
|
||||
if (AppConstants.platform == "win") {
|
||||
leafName = leafName
|
||||
.replace(/</g, "(")
|
||||
.replace(/>/g, ")")
|
||||
.replace(/"/g, "'");
|
||||
const mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
|
||||
let flags = mimeSvc.VALIDATE_SANITIZE_ONLY | mimeSvc.VALIDATE_DONT_TRUNCATE;
|
||||
if (!compressWhitespaces) {
|
||||
flags |= mimeSvc.VALIDATE_DONT_COLLAPSE_WHITESPACE;
|
||||
}
|
||||
leafName = leafName
|
||||
.replace(/[\\/]+/g, "_")
|
||||
.replace(/[\u200e\u200f\u202a-\u202e]/g, "")
|
||||
.replace(gConvertToSpaceRegExp, " ");
|
||||
if (compressWhitespaces) {
|
||||
leafName = leafName.replace(/\s{2,}/g, " ");
|
||||
}
|
||||
return leafName.replace(/^[\s\u180e.]+|[\s\u180e.]+$/g, "");
|
||||
return mimeSvc.validateFileNameForSaving(leafName, "", flags);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,27 +40,27 @@ add_task(async function test_sanitize() {
|
|||
testSanitize("Website | Page!", "Website Page!");
|
||||
testSanitize("Directory Listing: /a/b/", "Directory Listing _a_b_");
|
||||
} else if (AppConstants.platform == "win") {
|
||||
testSanitize(kSpecialChars, "A ''(());,+=[]B][=+,;))(('' C");
|
||||
testSanitize(kSpecialChars, "A ;,+=[]B][=+,; C");
|
||||
testSanitize(" :: Website :: ", "Website");
|
||||
testSanitize("* Website!", "Website!");
|
||||
testSanitize("Website | Page!", "Website Page!");
|
||||
testSanitize("Directory Listing: /a/b/", "Directory Listing _a_b_");
|
||||
} else if (AppConstants.platform == "macosx") {
|
||||
testSanitize(kSpecialChars, 'A *?|""<<>>;,+=[]B][=+,;>><<""|?* C');
|
||||
testSanitize(kSpecialChars, "A ;,+=[]B][=+,; C");
|
||||
testSanitize(" :: Website :: ", "Website");
|
||||
testSanitize("* Website!", "* Website!");
|
||||
testSanitize("Website | Page!", "Website | Page!");
|
||||
testSanitize("* Website!", "Website!");
|
||||
testSanitize("Website | Page!", "Website Page!");
|
||||
testSanitize("Directory Listing: /a/b/", "Directory Listing _a_b_");
|
||||
} else {
|
||||
testSanitize(kSpecialChars, kSpecialChars.replace(/[:]/g, " "));
|
||||
testSanitize(kSpecialChars, "A ;,+=[]B][=+,; C");
|
||||
testSanitize(" :: Website :: ", "Website");
|
||||
testSanitize("* Website!", "* Website!");
|
||||
testSanitize("Website | Page!", "Website | Page!");
|
||||
testSanitize("* Website!", "Website!");
|
||||
testSanitize("Website | Page!", "Website Page!");
|
||||
testSanitize("Directory Listing: /a/b/", "Directory Listing _a_b_");
|
||||
}
|
||||
|
||||
// Conversion of consecutive runs of slashes and backslashes to underscores.
|
||||
testSanitize("\\ \\\\Website\\/Page// /", "_ _Website_Page_ _");
|
||||
testSanitize("\\ \\\\Website\\/Page// /", "_ __Website__Page__ _");
|
||||
|
||||
// Removal of leading and trailing whitespace and dots after conversion.
|
||||
testSanitize(" Website ", "Website");
|
||||
|
@ -77,8 +77,8 @@ add_task(async function test_sanitize() {
|
|||
testSanitize(" . ", "");
|
||||
|
||||
// Stripping of BIDI formatting characters.
|
||||
testSanitize("\u200e \u202b\u202c\u202d\u202etest\x7f\u200f", "test");
|
||||
testSanitize("AB\x7f\u202a\x7f\u202a\x7fCD", "AB CD");
|
||||
testSanitize("\u200e \u202b\u202c\u202d\u202etest\x7f\u200f", "_ ____test _");
|
||||
testSanitize("AB\x7f\u202a\x7f\u202a\x7fCD", "AB _ _ CD");
|
||||
|
||||
// Stripping of colons:
|
||||
testSanitize("foo:bar", "foo bar");
|
||||
|
|
|
@ -294,11 +294,13 @@ nsUnknownContentTypeDialog.prototype = {
|
|||
let defaultFolder = new FileUtils.File(preferredDir);
|
||||
|
||||
try {
|
||||
result = this.validateLeafName(
|
||||
defaultFolder,
|
||||
aDefaultFileName,
|
||||
aSuggestedFileExtension
|
||||
);
|
||||
if (aDefaultFileName) {
|
||||
result = this.validateLeafName(
|
||||
defaultFolder,
|
||||
aDefaultFileName,
|
||||
aSuggestedFileExtension
|
||||
);
|
||||
}
|
||||
} catch (ex) {
|
||||
// When the default download directory is write-protected,
|
||||
// prompt the user for a different target file.
|
||||
|
|
Загрузка…
Ссылка в новой задаче