mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 07:04:53 +09:00
Bad Windows names also apply with any extension
A file name con.zip is also treated in the same way as the special CON redirection and may not be used as a normal filesystem path in Windows. This includes any extension, even with multiple dots. Fix checkFilename and cleaneFilename not handling these cases.
This commit is contained in:
1 parent
14934a0d3a
commit
9a1c7b2ecd
2 files changed
+35
-27
No files matched your search
+25
-25
@@ -108,6 +108,18 @@ async function safeOutputFile(file, data, options={}) {
|
||||
await fs.rename(temporary, file);
|
||||
}
|
||||
|
||||
|
||||
// Reserved names by allmost all filesystems
|
||||
const badNames = [".", ".."];
|
||||
|
||||
// Reserved namespaces in Windows
|
||||
const oneToNine = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
const badWinNamespaces = [
|
||||
"CON", "PRN", "AUX", "NUL",
|
||||
...oneToNine.map(n => `COM${n}`),
|
||||
...oneToNine.map(n => `LPT${n}`),
|
||||
];
|
||||
|
||||
/**
|
||||
* Check if a string is a valid file name
|
||||
*
|
||||
@@ -120,17 +132,6 @@ function checkFilename(name) {
|
||||
const badChars = /[<>:"\/\\|?*\x00-\x1f]/g;
|
||||
const badEnd = /[. ]$/;
|
||||
|
||||
const oneToNine = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
const badNames = [
|
||||
// Relative path components
|
||||
".", "..",
|
||||
|
||||
// Reserved filenames in Windows
|
||||
"CON", "PRN", "AUX", "NUL",
|
||||
...oneToNine.map(n => `COM${n}`),
|
||||
...oneToNine.map(n => `LPT${n}`),
|
||||
];
|
||||
|
||||
if (typeof name !== "string") {
|
||||
throw new Error("must be a string");
|
||||
}
|
||||
@@ -143,9 +144,15 @@ function checkFilename(name) {
|
||||
throw new Error('cannot contain <>:"\\/|=* or control characters');
|
||||
}
|
||||
|
||||
if (badNames.includes(name.toUpperCase())) {
|
||||
if (badNames.includes(name)) {
|
||||
throw new Error(
|
||||
"cannot be named any of . .. CON PRN AUX NUL COM1-9 and LPT1-9"
|
||||
`cannot be named ${name}`
|
||||
);
|
||||
}
|
||||
|
||||
if (badWinNamespaces.includes(name.toUpperCase().split(".")[0])) {
|
||||
throw new Error(
|
||||
"cannot be named any of CON PRN AUX NUL COM1-9 and LPT1-9"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -161,21 +168,10 @@ function checkFilename(name) {
|
||||
* @returns {string} Filename suitable to use in the filesystem
|
||||
*/
|
||||
function cleanFilename(name) {
|
||||
// copied from checkFilename
|
||||
// copied from checkFilename due to RegExp with global flag containing state.
|
||||
const badChars = /[<>:"\/\\|?*\x00-\x1f]/g;
|
||||
const badEnd = /[. ]$/;
|
||||
|
||||
const oneToNine = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
const badNames = [
|
||||
// Relative path components
|
||||
".", "..",
|
||||
|
||||
// Reserved filenames in Windows
|
||||
"CON", "PRN", "AUX", "NUL",
|
||||
...oneToNine.map(n => `COM${n}`),
|
||||
...oneToNine.map(n => `LPT${n}`),
|
||||
];
|
||||
|
||||
if (typeof name !== "string") {
|
||||
throw new Error("name must be a string");
|
||||
}
|
||||
@@ -184,6 +180,10 @@ function cleanFilename(name) {
|
||||
name += "_";
|
||||
}
|
||||
|
||||
if (badWinNamespaces.includes(name.toUpperCase().split(".")[0])) {
|
||||
name = [`${name.split(".")[0]}_`, ...name.split(".").slice(1)].join(".");
|
||||
}
|
||||
|
||||
name = name.replace(badChars, "_");
|
||||
name = name.replace(badEnd, "_");
|
||||
|
||||
|
||||
+10
-2
@@ -115,13 +115,17 @@ describe("lib/file_ops", function() {
|
||||
|
||||
it("should throw on CON, PRN, AUX, NUL, COM1, LPT1", function() {
|
||||
for (let bad of ["CON", "PRN", "AUX", "NUL", "COM1", "LPT1"]) {
|
||||
check(bad, "cannot be named any of . .. CON PRN AUX NUL COM1-9 and LPT1-9");
|
||||
check(bad, "cannot be named any of CON PRN AUX NUL COM1-9 and LPT1-9");
|
||||
check(`${bad}.zip`, "cannot be named any of CON PRN AUX NUL COM1-9 and LPT1-9");
|
||||
check(`${bad}.anything.txt`, "cannot be named any of CON PRN AUX NUL COM1-9 and LPT1-9");
|
||||
check(`${bad}....a`, "cannot be named any of CON PRN AUX NUL COM1-9 and LPT1-9");
|
||||
check(`${bad}.`, "cannot be named any of CON PRN AUX NUL COM1-9 and LPT1-9");
|
||||
}
|
||||
});
|
||||
|
||||
it("should throw on . and ..", function() {
|
||||
for (let bad of [".", ".."]) {
|
||||
check(bad, "cannot be named any of . .. CON PRN AUX NUL COM1-9 and LPT1-9");
|
||||
check(bad, `cannot be named ${bad}`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -166,6 +170,10 @@ describe("lib/file_ops", function() {
|
||||
it("should clean CON, PRN, AUX, NUL, COM1, LPT1", function() {
|
||||
for (let bad of ["CON", "PRN", "AUX", "NUL", "COM1", "LPT1"]) {
|
||||
clean(bad, `${bad}_`);
|
||||
clean(`${bad}.zip`, `${bad}_.zip`);
|
||||
clean(`${bad}.anything.txt`, `${bad}_.anything.txt`);
|
||||
clean(`${bad}....a`, `${bad}_....a`);
|
||||
clean(`${bad}.`, `${bad}__`);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user