summaryrefslogtreecommitdiffstats
path: root/uriloader/exthandler/tests/unit/test_filename_sanitize.js
diff options
context:
space:
mode:
Diffstat (limited to 'uriloader/exthandler/tests/unit/test_filename_sanitize.js')
-rw-r--r--uriloader/exthandler/tests/unit/test_filename_sanitize.js398
1 files changed, 398 insertions, 0 deletions
diff --git a/uriloader/exthandler/tests/unit/test_filename_sanitize.js b/uriloader/exthandler/tests/unit/test_filename_sanitize.js
new file mode 100644
index 0000000000..d8ab12c266
--- /dev/null
+++ b/uriloader/exthandler/tests/unit/test_filename_sanitize.js
@@ -0,0 +1,398 @@
+/* Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// This test verifies that
+// nsIMIMEService.validateFileNameForSaving sanitizes filenames
+// properly with different flags.
+
+"use strict";
+
+add_task(async function validate_filename_method() {
+ let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
+
+ function checkFilename(filename, flags, mime = "image/png") {
+ return mimeService.validateFileNameForSaving(filename, mime, flags);
+ }
+
+ Assert.equal(checkFilename("basicfile.png", 0), "basicfile.png");
+ Assert.equal(checkFilename(" whitespace.png ", 0), "whitespace.png");
+ Assert.equal(
+ checkFilename(" .whitespaceanddots.png...", 0),
+ "whitespaceanddots.png"
+ );
+ Assert.equal(
+ checkFilename(" \u00a0 \u00a0 extrawhitespace.png \u00a0 \u00a0 ", 0),
+ "extrawhitespace.png"
+ );
+ Assert.equal(
+ checkFilename(" filename with whitespace.png ", 0),
+ "filename with whitespace.png"
+ );
+ Assert.equal(checkFilename("\\path.png", 0), "_path.png");
+ Assert.equal(
+ checkFilename("\\path*and/$?~file.png", 0),
+ "_path and_$ ~file.png"
+ );
+ Assert.equal(
+ checkFilename(" \u180e whit\u180ee.png \u180e", 0),
+ "whit\u180ee.png"
+ );
+ Assert.equal(checkFilename("簡単簡単簡単", 0), "簡単簡単簡単.png");
+ Assert.equal(checkFilename(" happy\u061c\u2069.png", 0), "happy__.png");
+ Assert.equal(
+ checkFilename("12345678".repeat(31) + "abcdefgh.png", 0),
+ "12345678".repeat(31) + "ab.png"
+ );
+ Assert.equal(
+ checkFilename("簡単".repeat(41) + ".png", 0),
+ "簡単".repeat(41) + ".png"
+ );
+ Assert.equal(
+ checkFilename("a" + "簡単".repeat(42) + ".png", 0),
+ "a" + "簡単".repeat(40) + "簡.png"
+ );
+ Assert.equal(
+ checkFilename("a" + "簡単".repeat(56) + ".png", 0),
+ "a" + "簡単".repeat(40) + ".png"
+ );
+ Assert.equal(checkFilename("café.png", 0), "café.png");
+ Assert.equal(
+ checkFilename("café".repeat(50) + ".png", 0),
+ "café".repeat(50) + ".png"
+ );
+ Assert.equal(
+ checkFilename("café".repeat(51) + ".png", 0),
+ "café".repeat(49) + "caf.png"
+ );
+
+ Assert.equal(
+ checkFilename("\u{100001}\u{100002}.png", 0),
+ "\u{100001}\u{100002}.png"
+ );
+ Assert.equal(
+ checkFilename("\u{100001}\u{100002}".repeat(31) + ".png", 0),
+ "\u{100001}\u{100002}".repeat(31) + ".png"
+ );
+ Assert.equal(
+ checkFilename("\u{100001}\u{100002}".repeat(32) + ".png", 0),
+ "\u{100001}\u{100002}".repeat(30) + "\u{100001}.png"
+ );
+
+ Assert.equal(
+ checkFilename("noextensionfile".repeat(16), 0),
+ "noextensionfile".repeat(16) + ".png"
+ );
+ Assert.equal(
+ checkFilename("noextensionfile".repeat(17), 0),
+ "noextensionfile".repeat(16) + "noextensio.png"
+ );
+ Assert.equal(
+ checkFilename("noextensionfile".repeat(16) + "noextensionfil.", 0),
+ "noextensionfile".repeat(16) + "noextensio.png"
+ );
+
+ Assert.equal(checkFilename(" first .png ", 0), "first .png");
+ Assert.equal(
+ checkFilename(
+ " second .png ",
+ mimeService.VALIDATE_DONT_COLLAPSE_WHITESPACE
+ ),
+ "second .png"
+ );
+
+ // 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("f*\\ourth file.jpg", mimeService.VALIDATE_SANITIZE_ONLY),
+ "f _ourth file.jpg"
+ );
+ Assert.equal(
+ checkFilename(
+ "f*\\ift h.jpe*\\g",
+ mimeService.VALIDATE_SANITIZE_ONLY |
+ mimeService.VALIDATE_DONT_COLLAPSE_WHITESPACE
+ ),
+ "f _ift h.jpe _g"
+ );
+ Assert.equal(checkFilename("sixth.j pe/*g", 0), "sixth.png");
+
+ let repeatStr = "12345678".repeat(31);
+ Assert.equal(
+ checkFilename(
+ repeatStr + "seventh.png",
+ mimeService.VALIDATE_DONT_TRUNCATE
+ ),
+ repeatStr + "seventh.png"
+ );
+ Assert.equal(
+ checkFilename(repeatStr + "seventh.png", 0),
+ repeatStr + "se.png"
+ );
+
+ // no filename, so index is used by default.
+ Assert.equal(checkFilename(".png", 0), "png.png");
+
+ // sanitization only, so Untitled is not added, but initial period is stripped.
+ Assert.equal(
+ checkFilename(".png", mimeService.VALIDATE_SANITIZE_ONLY),
+ "png"
+ );
+
+ // correct .png extension is applied.
+ Assert.equal(checkFilename(".butterpecan.icecream", 0), "butterpecan.png");
+
+ // sanitization only, so extension is not modified, but initial period is stripped.
+ Assert.equal(
+ checkFilename(".butterpecan.icecream", mimeService.VALIDATE_SANITIZE_ONLY),
+ "butterpecan.icecream"
+ );
+
+ let ext = ".fairlyLongExtension";
+ Assert.equal(
+ checkFilename(repeatStr + ext, mimeService.VALIDATE_SANITIZE_ONLY),
+ repeatStr.substring(0, 254 - ext.length) + ext
+ );
+
+ ext = "lo%?n/ginvalid? ch\\ars";
+ Assert.equal(
+ checkFilename(repeatStr + ext, mimeService.VALIDATE_SANITIZE_ONLY),
+ repeatStr + "lo% n_"
+ );
+
+ ext = ".long/invalid%? ch\\ars";
+ Assert.equal(
+ checkFilename(repeatStr + ext, mimeService.VALIDATE_SANITIZE_ONLY),
+ repeatStr.substring(0, 233) + ".long_invalid% ch_ars"
+ );
+
+ Assert.equal(
+ checkFilename("test_テスト_T\x83E\\S\x83T.png", 0),
+ "test_テスト_T E_S T.png"
+ );
+ Assert.equal(
+ checkFilename("test_テスト_T\x83E\\S\x83T.pテ\x83ng", 0),
+ "test_テスト_T E_S T.png"
+ );
+
+ // Check we don't invalidate surrogate pairs when trimming.
+ Assert.equal(checkFilename("test😀", 0, ""), "test😀");
+ Assert.equal(checkFilename("test😀😀", 0, ""), "test😀😀");
+
+ // Now check some media types
+ Assert.equal(
+ mimeService.validateFileNameForSaving("video.ogg", "video/ogg", 0),
+ "video.ogg",
+ "video.ogg"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("video.ogv", "video/ogg", 0),
+ "video.ogv",
+ "video.ogv"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("video.ogt", "video/ogg", 0),
+ "video.ogv",
+ "video.ogt"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving("audio.mp3", "audio/mpeg", 0),
+ "audio.mp3",
+ "audio.mp3"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("audio.mpega", "audio/mpeg", 0),
+ "audio.mpega",
+ "audio.mpega"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("audio.mp2", "audio/mpeg", 0),
+ "audio.mp2",
+ "audio.mp2"
+ );
+
+ let expected = "audio.mp3";
+ if (AppConstants.platform == "linux") {
+ expected = "audio.mpga";
+ } else if (AppConstants.platform == "android") {
+ expected = "audio.mp4";
+ }
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving("audio.mp4", "audio/mpeg", 0),
+ expected,
+ "audio.mp4"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving("sound.m4a", "audio/mp4", 0),
+ "sound.m4a",
+ "sound.m4a"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("sound.m4b", "audio/mp4", 0),
+ AppConstants.platform == "android" ? "sound.m4a" : "sound.m4b",
+ "sound.m4b"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("sound.m4c", "audio/mp4", 0),
+ AppConstants.platform == "macosx" ? "sound.mp4" : "sound.m4a",
+ "sound.mpc"
+ );
+
+ // This has a long filename with a 13 character extension. The end of the filename should be
+ // cropped to fit into 255 bytes.
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "라이브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박스 더 (뚱랑이 굿즈 .등 유산균 컬처렐 특가!",
+ "very long filename with extension"
+ );
+
+ // This filename has a very long extension, almost the entire filename.
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "라이브9.9만 시청컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장컬처렐 다이제스티브 3박스 - 3박스 더 (뚱랑이 굿즈 증정) - 선물용 쇼핑백 2장24%102 000원 브랜드데이 앵콜 🎁 1등 유산균 컬처렐 특가!",
+ "text/unknown",
+ mimeService.VALIDATE_SANITIZE_ONLY
+ ),
+ "라이브9",
+ "another very long filename with long extension"
+ );
+
+ // This filename is cropped at 254 bytes.
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ ".라이브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원 브랜드데",
+ "very filename with extension only"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving("filename.LNK", "text/unknown", 0),
+ "filename.LNK.download",
+ "filename.LNK"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("filename.local", "text/unknown", 0),
+ "filename.local.download",
+ "filename.local"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("filename.url", "text/unknown", 0),
+ "filename.url.download",
+ "filename.url"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("filename.URl", "text/unknown", 0),
+ "filename.URl.download",
+ "filename.URl"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("filename.scf", "text/unknown", 0),
+ "filename.scf.download",
+ "filename.scf"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving("filename.sCF", "text/unknown", 0),
+ "filename.sCF.download",
+ "filename.sCF"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving("filename.lnk\n", "text/unknown", 0),
+ "filename.lnk.download",
+ "filename.lnk with newline"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "filename.lnk\n ",
+ "text/unknown",
+ 0
+ ),
+ "filename.lnk.download",
+ "filename.lnk with newline"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "filename.\n\t lnk",
+ "text/unknown",
+ 0
+ ),
+ "filename. lnk",
+ "filename.lnk with space and newline"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "filename.local\u180e\u180e\u180e",
+ "text/unknown",
+ 0
+ ),
+ "filename.local.download",
+ "filename.lnk with vowel separators"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "filename.LNK",
+ "text/unknown",
+ mimeService.VALIDATE_SANITIZE_ONLY
+ ),
+ "filename.LNK.download",
+ "filename.LNK sanitize only"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "filename.LNK\n",
+ "text/unknown",
+ mimeService.VALIDATE_ALLOW_INVALID_FILENAMES
+ ),
+ "filename.LNK",
+ "filename.LNK allow invalid"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "filename.URL\n",
+ "text/unknown",
+ mimeService.VALIDATE_SANITIZE_ONLY |
+ mimeService.VALIDATE_ALLOW_INVALID_FILENAMES
+ ),
+ "filename.URL",
+ "filename.URL allow invalid, sanitize only"
+ );
+
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "filename.desktop",
+ "text/unknown",
+ mimeService.VALIDATE_SANITIZE_ONLY
+ ),
+ "filename.desktop.download",
+ "filename.desktop sanitize only"
+ );
+ Assert.equal(
+ mimeService.validateFileNameForSaving(
+ "filename.DESKTOP\n",
+ "text/unknown",
+ mimeService.VALIDATE_SANITIZE_ONLY |
+ mimeService.VALIDATE_ALLOW_INVALID_FILENAMES
+ ),
+ "filename.DESKTOP",
+ "filename.DESKTOP allow invalid, sanitize only"
+ );
+});