forked from mirrors/gecko-dev
Bug 1891234, additional filename filter checks, r=Gijs,extension-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D208659
This commit is contained in:
parent
75385837ce
commit
e17b53a054
6 changed files with 70 additions and 61 deletions
|
|
@ -34,29 +34,29 @@ add_task(async function test_sanitize() {
|
|||
// Platform-dependent conversion of special characters to spaces.
|
||||
const kSpecialChars = 'A:*?|""<<>>;,+=[]B][=+,;>><<""|?*:C';
|
||||
if (AppConstants.platform == "android") {
|
||||
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_");
|
||||
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 == "win") {
|
||||
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_");
|
||||
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(" :: Website :: ", "Website");
|
||||
testSanitize("* Website!", "Website!");
|
||||
testSanitize("Website | Page!", "Website Page!");
|
||||
testSanitize("Directory Listing: /a/b/", "Directory Listing _a_b_");
|
||||
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 {
|
||||
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_");
|
||||
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_");
|
||||
}
|
||||
|
||||
// Conversion of consecutive runs of slashes and backslashes to underscores.
|
||||
|
|
@ -66,7 +66,7 @@ add_task(async function test_sanitize() {
|
|||
testSanitize(" Website ", "Website");
|
||||
testSanitize(". . Website . Page . .", "Website .Page");
|
||||
testSanitize(" File . txt ", "File .txt");
|
||||
testSanitize("\f\n\r\t\v\x00\x1f\x7f\x80\x9f\xa0 . txt", "txt");
|
||||
testSanitize("\f\n\r\t\v\x00\x1f\x7f\x80\x9f\xa0 . txt", "_________ .txt");
|
||||
testSanitize("\u1680\u180e\u2000\u2008\u200a . txt", "txt");
|
||||
testSanitize("\u2028\u2029\u202f\u205f\u3000\ufeff . txt", "txt");
|
||||
|
||||
|
|
@ -77,25 +77,25 @@ 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");
|
||||
testSanitize("foo:bar", "foo_bar");
|
||||
|
||||
// not compressing whitespaces.
|
||||
testSanitize("foo : bar", "foo bar", { compressWhitespaces: false });
|
||||
testSanitize("foo : bar", "foo _ bar", { compressWhitespaces: false });
|
||||
|
||||
testSanitize("thing.lnk", "thing.lnk.download");
|
||||
testSanitize("thing.lnk\n", "thing.lnk.download");
|
||||
testSanitize("thing.lnk\n", "thing.lnk_");
|
||||
testSanitize("thing.lnk", "thing.lnk", {
|
||||
allowInvalidFilenames: true,
|
||||
});
|
||||
testSanitize("thing.lnk\n", "thing.lnk", {
|
||||
testSanitize("thing.lnk\n", "thing.lnk_", {
|
||||
allowInvalidFilenames: true,
|
||||
});
|
||||
testSanitize("thing.URl", "thing.URl.download");
|
||||
testSanitize("thing.URl \n", "thing.URl", {
|
||||
testSanitize("thing.URl \n", "thing.URl_", {
|
||||
allowInvalidFilenames: true,
|
||||
});
|
||||
|
||||
|
|
@ -107,12 +107,12 @@ add_task(async function test_sanitize() {
|
|||
allowInvalidFilenames: true,
|
||||
});
|
||||
|
||||
testSanitize("thing.local|", "thing.local.download");
|
||||
testSanitize("thing.lo|cal", "thing.lo cal");
|
||||
testSanitize('thing.local/*"', "thing.local_");
|
||||
testSanitize("thing.local|", "thing.local_");
|
||||
testSanitize("thing.lo|cal", "thing.lo_cal");
|
||||
testSanitize('thing.local/*"', "thing.local___");
|
||||
|
||||
testSanitize("thing.desktoP", "thing.desktoP.download");
|
||||
testSanitize("thing.desktoP \n", "thing.desktoP", {
|
||||
testSanitize("thing.desktoP \n", "thing.desktoP_", {
|
||||
allowInvalidFilenames: true,
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ add_task(async function test_decoded_filename_download() {
|
|||
const FILE_NAME_DECODED_2 = "file\u{0001F6B2}encoded.txt";
|
||||
const FILE_NAME_ENCODED_URL_2 = BASE + "/" + FILE_NAME_ENCODED_2;
|
||||
const FILE_NAME_ENCODED_3 = "file%X%20encode.txt";
|
||||
const FILE_NAME_DECODED_3 = "file%X encode.txt";
|
||||
const FILE_NAME_DECODED_3 = "file_X encode.txt";
|
||||
const FILE_NAME_ENCODED_URL_3 = BASE + "/" + FILE_NAME_ENCODED_3;
|
||||
const FILE_NAME_ENCODED_4 = "file%E3%80%82encode.txt";
|
||||
const FILE_NAME_DECODED_4 = "file\u3002encode.txt";
|
||||
|
|
|
|||
|
|
@ -3485,8 +3485,8 @@ void nsExternalHelperAppService::SanitizeFileName(nsAString& aFileName,
|
|||
nsAutoString fileName(aFileName);
|
||||
|
||||
// Replace known invalid characters.
|
||||
fileName.ReplaceChar(u"" KNOWN_PATH_SEPARATORS, u'_');
|
||||
fileName.ReplaceChar(u"" FILE_ILLEGAL_CHARACTERS, u' ');
|
||||
fileName.ReplaceChar(u"" KNOWN_PATH_SEPARATORS FILE_ILLEGAL_CHARACTERS "%",
|
||||
u'_');
|
||||
fileName.StripChar(char16_t(0));
|
||||
|
||||
const char16_t *startStr, *endStr;
|
||||
|
|
@ -3668,6 +3668,14 @@ void nsExternalHelperAppService::SanitizeFileName(nsAString& aFileName,
|
|||
outFileName.Truncate(lastNonTrimmable);
|
||||
}
|
||||
|
||||
nsAutoString extension;
|
||||
int32_t dotidx = outFileName.RFind(u".");
|
||||
if (dotidx != -1) {
|
||||
extension = Substring(outFileName, dotidx + 1);
|
||||
extension.StripWhitespace();
|
||||
outFileName = Substring(outFileName, 0, dotidx + 1) + extension;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (nsLocalFile::CheckForReservedFileName(outFileName)) {
|
||||
outFileName.Truncate();
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<img id="i1" src="http://localhost:8000/save_filename.sjs?type=png&filename=simple.png" data-filename="simple.png">
|
||||
|
||||
<!-- invalid characters in the filename -->
|
||||
<img id="i2" src="http://localhost:8000/save_filename.sjs?type=png&filename=invalidfilename/a:b*c%63d.png" data-filename="invalidfilename_a b ccd.png">
|
||||
<img id="i2" src="http://localhost:8000/save_filename.sjs?type=png&filename=invalidfilename/a:b*c%63d.png" data-filename="invalidfilename_a_b_ccd.png">
|
||||
|
||||
<!-- invalid extension for a png image -->
|
||||
<img id="i3" src="http://localhost:8000/save_filename.sjs?type=png&filename=invalidextension.pang" data-filename="invalidextension.png">
|
||||
|
|
@ -329,11 +329,11 @@
|
|||
|
||||
<!-- filename which is changed to an invalid filename within the file picker -->
|
||||
<a id="mod1" href="http://localhost:8000/save_filename.sjs?type=png&filename=orange.png"
|
||||
data-pickedfilename='"peach".png' data-filename='peach .png'>
|
||||
data-pickedfilename='"peach".png' data-filename='_peach_.png'>
|
||||
|
||||
<!-- an invalid filename which is changed to another invalid filename within the file picker -->
|
||||
<a id="mod2" href="http://localhost:8000/save_filename.sjs?type=png&filename=%maroon%34.png"
|
||||
data-pickedfilename='"violet".png' data-filename="violet .png">
|
||||
data-pickedfilename='"violet".png' data-filename="_violet_.png">
|
||||
|
||||
</span>
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
var tests = [
|
||||
["test.png:large", "test.png"],
|
||||
["test.png/large", "test.png"],
|
||||
[":test.png::large:", "test.png"],
|
||||
[":test.png::large:", "_test.png"],
|
||||
];
|
||||
|
||||
add_task(async function() {
|
||||
|
|
|
|||
|
|
@ -31,8 +31,9 @@ add_task(async function validate_filename_method() {
|
|||
Assert.equal(checkFilename("\\path.png", 0), "_path.png");
|
||||
Assert.equal(
|
||||
checkFilename("\\path*and/$?~file.png", 0),
|
||||
"_path and_$ ~file.png"
|
||||
"_path_and_$_~file.png"
|
||||
);
|
||||
|
||||
Assert.equal(
|
||||
checkFilename(" \u180e whit\u180ee.png \u180e", 0),
|
||||
"whit\u180ee.png"
|
||||
|
|
@ -103,12 +104,12 @@ add_task(async function validate_filename_method() {
|
|||
// For whatever reason, the Android mime handler accepts the .jpeg
|
||||
// extension for image/png, so skip this test there.
|
||||
if (AppConstants.platform != "android") {
|
||||
Assert.equal(checkFilename("thi/*rd.jpeg", 0), "thi_ rd.png");
|
||||
Assert.equal(checkFilename("thi/*rd.jpeg", 0), "thi__rd.png");
|
||||
}
|
||||
|
||||
Assert.equal(
|
||||
checkFilename("f*\\ourth file.jpg", mimeService.VALIDATE_SANITIZE_ONLY),
|
||||
"f _ourth file.jpg"
|
||||
"f__ourth file.jpg"
|
||||
);
|
||||
Assert.equal(
|
||||
checkFilename(
|
||||
|
|
@ -116,7 +117,7 @@ add_task(async function validate_filename_method() {
|
|||
mimeService.VALIDATE_SANITIZE_ONLY |
|
||||
mimeService.VALIDATE_DONT_COLLAPSE_WHITESPACE
|
||||
),
|
||||
"f _ift h.jpe _g"
|
||||
"f__ift h.jpe__g"
|
||||
);
|
||||
Assert.equal(checkFilename("sixth.j pe/*g", 0), "sixth.png");
|
||||
|
||||
|
|
@ -157,25 +158,25 @@ add_task(async function validate_filename_method() {
|
|||
repeatStr.substring(0, 254 - ext.length) + ext
|
||||
);
|
||||
|
||||
ext = "lo%?n/ginvalid? ch\\ars";
|
||||
ext = "lo#?n/ginvalid? ch\\ars";
|
||||
Assert.equal(
|
||||
checkFilename(repeatStr + ext, mimeService.VALIDATE_SANITIZE_ONLY),
|
||||
repeatStr + "lo% n_"
|
||||
repeatStr + "lo#_n_"
|
||||
);
|
||||
|
||||
ext = ".long/invalid%? ch\\ars";
|
||||
ext = ".long/invalid#? ch\\ars";
|
||||
Assert.equal(
|
||||
checkFilename(repeatStr + ext, mimeService.VALIDATE_SANITIZE_ONLY),
|
||||
repeatStr.substring(0, 233) + ".long_invalid% ch_ars"
|
||||
repeatStr.substring(0, 232) + ".long_invalid#_ch_ars"
|
||||
);
|
||||
|
||||
Assert.equal(
|
||||
checkFilename("test_テスト_T\x83E\\S\x83T.png", 0),
|
||||
"test_テスト_T E_S T.png"
|
||||
"test_テスト_T_E_S_T.png"
|
||||
);
|
||||
Assert.equal(
|
||||
checkFilename("test_テスト_T\x83E\\S\x83T.pテ\x83ng", 0),
|
||||
"test_テスト_T E_S T.png"
|
||||
"test_テスト_T_E_S_T.png"
|
||||
);
|
||||
|
||||
// Check we don't invalidate surrogate pairs when trimming.
|
||||
|
|
@ -248,11 +249,11 @@ add_task(async function validate_filename_method() {
|
|||
// cropped to fit into 255 bytes.
|
||||
Assert.equal(
|
||||
mimeService.validateFileNameForSaving(
|
||||
"라이브9.9만 시청컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장24%102 000원 브랜드데이 앵콜 🎁 1.등 유산균 컬처렐 특가!",
|
||||
"라이브9.9만 시청컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장24%102 000원 브랜드데이 앵콜 🎁 1.등-유산균-컬처렐-특가!",
|
||||
"text/unknown",
|
||||
mimeService.VALIDATE_SANITIZE_ONLY
|
||||
),
|
||||
"라이브9.9만 시청컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 .등 유산균 컬처렐 특가!",
|
||||
"라이브9.9만 시청컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 .등-유산균-컬처렐-특가!",
|
||||
"very long filename with extension"
|
||||
);
|
||||
|
||||
|
|
@ -270,11 +271,11 @@ add_task(async function validate_filename_method() {
|
|||
// This filename is cropped at 254 bytes.
|
||||
Assert.equal(
|
||||
mimeService.validateFileNameForSaving(
|
||||
".라이브99만 시청컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장24%102 000원 브랜드데이 앵콜 🎁 1등 유산균 컬처렐 특가!",
|
||||
".라이브99만 시청컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장24_102 000원 브랜드데이 앵콜 🎁 1등 유산균 컬처렐 특가!",
|
||||
"text/unknown",
|
||||
mimeService.VALIDATE_SANITIZE_ONLY
|
||||
),
|
||||
"라이브99만 시청컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장24%102 000원 브랜드데",
|
||||
"라이브99만 시청컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장24_102 000원 브랜드데",
|
||||
"very filename with extension only"
|
||||
);
|
||||
|
||||
|
|
@ -311,7 +312,7 @@ add_task(async function validate_filename_method() {
|
|||
|
||||
Assert.equal(
|
||||
mimeService.validateFileNameForSaving("filename.lnk\n", "text/unknown", 0),
|
||||
"filename.lnk.download",
|
||||
"filename.lnk_",
|
||||
"filename.lnk with newline"
|
||||
);
|
||||
|
||||
|
|
@ -321,7 +322,7 @@ add_task(async function validate_filename_method() {
|
|||
"text/unknown",
|
||||
0
|
||||
),
|
||||
"filename.lnk.download",
|
||||
"filename.lnk_",
|
||||
"filename.lnk with newline"
|
||||
);
|
||||
|
||||
|
|
@ -331,7 +332,7 @@ add_task(async function validate_filename_method() {
|
|||
"text/unknown",
|
||||
0
|
||||
),
|
||||
"filename. lnk",
|
||||
"filename.__lnk",
|
||||
"filename.lnk with space and newline"
|
||||
);
|
||||
|
||||
|
|
@ -361,7 +362,7 @@ add_task(async function validate_filename_method() {
|
|||
"text/unknown",
|
||||
mimeService.VALIDATE_ALLOW_INVALID_FILENAMES
|
||||
),
|
||||
"filename.LNK",
|
||||
"filename.LNK_",
|
||||
"filename.LNK allow invalid"
|
||||
);
|
||||
|
||||
|
|
@ -372,7 +373,7 @@ add_task(async function validate_filename_method() {
|
|||
mimeService.VALIDATE_SANITIZE_ONLY |
|
||||
mimeService.VALIDATE_ALLOW_INVALID_FILENAMES
|
||||
),
|
||||
"filename.URL",
|
||||
"filename.URL_",
|
||||
"filename.URL allow invalid, sanitize only"
|
||||
);
|
||||
|
||||
|
|
@ -392,7 +393,7 @@ add_task(async function validate_filename_method() {
|
|||
mimeService.VALIDATE_SANITIZE_ONLY |
|
||||
mimeService.VALIDATE_ALLOW_INVALID_FILENAMES
|
||||
),
|
||||
"filename.DESKTOP",
|
||||
"filename.DESKTOP_",
|
||||
"filename.DESKTOP allow invalid, sanitize only"
|
||||
);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue