diff options
Diffstat (limited to 'uriloader/exthandler/tests/unit/test_filename_sanitize.js')
-rw-r--r-- | uriloader/exthandler/tests/unit/test_filename_sanitize.js | 398 |
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" + ); +}); |