Prevent errors thrown from terminal (#443)

At least from getFilepath function
This commit is contained in:
Snarling 2023-03-23 12:01:58 -04:00 committed by GitHub
parent 07b18edb5c
commit 6290ce562a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 44 additions and 77 deletions

@ -392,22 +392,17 @@ export class Terminal {
return null; return null;
} }
getFilepath(filename: string): string { getFilepath(filename: string): string | null {
const path = evaluateFilePath(filename, this.cwd()); const path = evaluateFilePath(filename, this.cwd());
if (path == null) { if (path === null || !isInRootDirectory(path)) return path;
throw new Error(`Invalid file path specified: ${filename}`);
}
if (isInRootDirectory(path)) {
return removeLeadingSlash(path); return removeLeadingSlash(path);
} }
return path;
}
getScript(filename: string): Script | null { getScript(filename: string): Script | null {
const s = Player.getCurrentServer(); const s = Player.getCurrentServer();
const filepath = this.getFilepath(filename); const filepath = this.getFilepath(filename);
if (!filepath) return null;
for (const script of s.scripts) { for (const script of s.scripts) {
if (filepath === script.filename) { if (filepath === script.filename) {
return script; return script;
@ -420,6 +415,7 @@ export class Terminal {
getTextFile(filename: string): TextFile | null { getTextFile(filename: string): TextFile | null {
const s = Player.getCurrentServer(); const s = Player.getCurrentServer();
const filepath = this.getFilepath(filename); const filepath = this.getFilepath(filename);
if (!filepath) return null;
for (const txt of s.textFiles) { for (const txt of s.textFiles) {
if (filepath === txt.fn) { if (filepath === txt.fn) {
return txt; return txt;
@ -432,6 +428,7 @@ export class Terminal {
getLitFile(filename: string): string | null { getLitFile(filename: string): string | null {
const s = Player.getCurrentServer(); const s = Player.getCurrentServer();
const filepath = this.getFilepath(filename); const filepath = this.getFilepath(filename);
if (!filepath) return null;
for (const lit of s.messages) { for (const lit of s.messages) {
if (typeof lit === "string" && filepath === lit) { if (typeof lit === "string" && filepath === lit) {
return lit; return lit;

@ -12,6 +12,7 @@ export function cat(args: (string | number | boolean)[], server: BaseServer): vo
} }
const relative_filename = args[0] + ""; const relative_filename = args[0] + "";
const filename = Terminal.getFilepath(relative_filename); const filename = Terminal.getFilepath(relative_filename);
if (!filename) return Terminal.error(`Invalid filename: ${relative_filename}`);
if ( if (
!filename.endsWith(".msg") && !filename.endsWith(".msg") &&
!filename.endsWith(".lit") && !filename.endsWith(".lit") &&

@ -8,6 +8,8 @@ export function check(args: (string | number | boolean)[], server: BaseServer):
Terminal.error(`Incorrect number of arguments. Usage: check [script] [arg1] [arg2]...`); Terminal.error(`Incorrect number of arguments. Usage: check [script] [arg1] [arg2]...`);
} else { } else {
const scriptName = Terminal.getFilepath(args[0] + ""); const scriptName = Terminal.getFilepath(args[0] + "");
if (!scriptName) return Terminal.error(`Invalid filename: ${args[0]}`);
// Can only tail script files // Can only tail script files
if (!isScriptFilename(scriptName)) { if (!isScriptFilename(scriptName)) {
Terminal.error( Terminal.error(

@ -109,6 +109,7 @@ export function commonEditor(
if (isScriptFilename(filename)) { if (isScriptFilename(filename)) {
const filepath = Terminal.getFilepath(filename); const filepath = Terminal.getFilepath(filename);
if (!filepath) throw `Invalid filename: ${filename}`;
const script = Terminal.getScript(filename); const script = Terminal.getScript(filename);
const fileIsNs2 = isNs2(filename); const fileIsNs2 = isNs2(filename);
const code = script !== null ? script.code : fileIsNs2 ? newNs2Template : ""; const code = script !== null ? script.code : fileIsNs2 ? newNs2Template : "";
@ -125,6 +126,7 @@ export function commonEditor(
if (filename.endsWith(".txt")) { if (filename.endsWith(".txt")) {
const filepath = Terminal.getFilepath(filename); const filepath = Terminal.getFilepath(filename);
if (!filepath) throw `Invalid filename: ${filename}`;
const txt = Terminal.getTextFile(filename); const txt = Terminal.getTextFile(filename);
return [filepath, txt === null ? "" : txt.text]; return [filepath, txt === null ? "" : txt.text];
} }

@ -5,39 +5,26 @@ import { getDestinationFilepath, areFilesEqual } from "../DirectoryHelpers";
export function cp(args: (string | number | boolean)[], server: BaseServer): void { export function cp(args: (string | number | boolean)[], server: BaseServer): void {
try { try {
if (args.length !== 2) { if (args.length !== 2) return Terminal.error("Incorrect usage of cp command. Usage: cp [src] [dst]");
Terminal.error("Incorrect usage of cp command. Usage: cp [src] [dst]");
return;
}
// Convert a relative path source file to the absolute path. // Convert a relative path source file to the absolute path.
const src = Terminal.getFilepath(args[0] + ""); const src = Terminal.getFilepath(args[0] + "");
if (src === null) { if (src === null) return Terminal.error(`Invalid source filename ${args[0]}`);
Terminal.error("src cannot be a directory");
return;
}
// Get the destination based on the source file and the current directory // Get the destination based on the source file and the current directory
const t_dst = getDestinationFilepath(args[1] + "", src, Terminal.cwd()); const t_dst = getDestinationFilepath(args[1] + "", src, Terminal.cwd());
if (t_dst === null) { if (t_dst === null) return Terminal.error("error parsing dst file");
Terminal.error("error parsing dst file");
return;
}
// Convert a relative path destination file to the absolute path. // Convert a relative path destination file to the absolute path.
const dst = Terminal.getFilepath(t_dst); const dst = Terminal.getFilepath(t_dst);
if (areFilesEqual(src, dst)) { if (!dst) return Terminal.error(`Invalid destination filename ${t_dst}`);
Terminal.error("src and dst cannot be the same"); if (areFilesEqual(src, dst)) return Terminal.error("src and dst cannot be the same");
return;
}
const srcExt = src.slice(src.lastIndexOf(".")); const srcExt = src.slice(src.lastIndexOf("."));
const dstExt = dst.slice(dst.lastIndexOf(".")); const dstExt = dst.slice(dst.lastIndexOf("."));
if (srcExt !== dstExt) { if (srcExt !== dstExt) return Terminal.error("src and dst must have the same extension.");
Terminal.error("src and dst must have the same extension.");
return;
}
if (!isScriptFilename(src) && !src.endsWith(".txt")) { if (!isScriptFilename(src) && !src.endsWith(".txt")) {
Terminal.error("cp only works for scripts and .txt files"); return Terminal.error("cp only works for scripts and .txt files");
return;
} }
// Scp for txt files // Scp for txt files

@ -26,6 +26,7 @@ export function kill(args: (string | number | boolean)[], server: BaseServer): v
} }
const scriptName = Terminal.getFilepath(args[0]); const scriptName = Terminal.getFilepath(args[0]);
if (!scriptName) return Terminal.error(`Invalid filename: ${args[0]}`);
const runningScript = server.getRunningScript(scriptName, args.slice(1)); const runningScript = server.getRunningScript(scriptName, args.slice(1));
if (runningScript == null) { if (runningScript == null) {
Terminal.error("No such script is running. Nothing to kill"); Terminal.error("No such script is running. Nothing to kill");

@ -155,6 +155,9 @@ export function ls(args: (string | number | boolean)[], server: BaseServer): voi
const filepath = Terminal.getFilepath(`${prefix}${filename}`); const filepath = Terminal.getFilepath(`${prefix}${filename}`);
// Terminal.getScript also calls Terminal.getFilepath and therefore also // Terminal.getScript also calls Terminal.getFilepath and therefore also
// needs the given parameter // needs the given parameter
if (!filepath) {
return Terminal.error(`Invalid filename (${prefix}${filename}) when clicking script link. This is a bug.`);
}
const code = toString(Terminal.getScript(`${prefix}${filename}`)?.code); const code = toString(Terminal.getScript(`${prefix}${filename}`)?.code);
Router.toScriptEditor({ [filepath]: code }); Router.toScriptEditor({ [filepath]: code });
} }
@ -199,6 +202,9 @@ export function ls(args: (string | number | boolean)[], server: BaseServer): voi
} }
if (filename.startsWith("/")) filename = filename.slice(1); if (filename.startsWith("/")) filename = filename.slice(1);
const filepath = Terminal.getFilepath(`${prefix}${filename}`); const filepath = Terminal.getFilepath(`${prefix}${filename}`);
if (!filepath) {
return Terminal.error(`Invalid filename ${prefix}${filename} when clicking message link. This is a bug.`);
}
if (filepath.endsWith(".lit")) { if (filepath.endsWith(".lit")) {
showLiterature(filepath); showLiterature(filepath);

@ -21,40 +21,28 @@ export function mv(args: (string | number | boolean)[], server: BaseServer): voi
} }
const srcFile = Terminal.getFile(source); const srcFile = Terminal.getFile(source);
if (srcFile == null) { if (srcFile == null) return Terminal.error(`Source file ${source} does not exist`);
Terminal.error(`Source file ${source} does not exist`);
return;
}
const sourcePath = Terminal.getFilepath(source); const sourcePath = Terminal.getFilepath(source);
if (!sourcePath) return Terminal.error(`Invalid source filename: ${source}`);
// Get the destination based on the source file and the current directory // Get the destination based on the source file and the current directory
const dest = getDestinationFilepath(t_dest, source, Terminal.cwd()); const dest = getDestinationFilepath(t_dest, source, Terminal.cwd());
if (dest === null) { if (dest === null) return Terminal.error("error parsing dst file");
Terminal.error("error parsing dst file");
return;
}
const destFile = Terminal.getFile(dest); const destFile = Terminal.getFile(dest);
const destPath = Terminal.getFilepath(dest); const destPath = Terminal.getFilepath(dest);
if (areFilesEqual(sourcePath, destPath)) { if (!destPath) return Terminal.error(`Invalid destination filename: ${destPath}`);
Terminal.error(`Source and destination files are the same file`); if (areFilesEqual(sourcePath, destPath)) return Terminal.error(`Source and destination files are the same file`);
return;
}
// 'mv' command only works on scripts and txt files. // 'mv' command only works on scripts and txt files.
// Also, you can't convert between different file types // Also, you can't convert between different file types
if (isScriptFilename(source)) { if (isScriptFilename(source)) {
const script = srcFile as Script; const script = srcFile as Script;
if (!isScriptFilename(destPath)) { if (!isScriptFilename(destPath)) return Terminal.error(`Source and destination files must have the same type`);
Terminal.error(`Source and destination files must have the same type`);
return;
}
// Command doesn't work if script is running // Command doesn't work if script is running
if (server.isRunning(sourcePath)) { if (server.isRunning(sourcePath)) return Terminal.error(`Cannot use 'mv' on a script that is running`);
Terminal.error(`Cannot use 'mv' on a script that is running`);
return;
}
if (destFile != null) { if (destFile != null) {
// Already exists, will be overwritten, so we'll delete it // Already exists, will be overwritten, so we'll delete it

@ -1,30 +1,10 @@
import { Terminal } from "../../Terminal"; import { Terminal } from "../../Terminal";
import { BaseServer } from "../../Server/BaseServer"; import { BaseServer } from "../../Server/BaseServer";
import { IReturnStatus } from "../../types";
export function rm(args: (string | number | boolean)[], server: BaseServer): void { export function rm(args: (string | number | boolean)[], server: BaseServer): void {
if (args.length !== 1) { if (args.length !== 1) return Terminal.error("Incorrect number of arguments. Usage: rm [program/script]");
Terminal.error("Incorrect number of arguments. Usage: rm [program/script]"); const delTarget = Terminal.getFilepath(args[0] + "");
return; if (!delTarget) return Terminal.error(`Invalid filename: ${args[0]}`);
} const status = server.removeFile(delTarget);
if (!status.res && status.msg) Terminal.error(status.msg);
// Check programs
let delTarget;
let status: IReturnStatus = {
res: true,
msg: "",
};
try {
delTarget = Terminal.getFilepath(args[0] + "");
status = server.removeFile(delTarget);
} catch (err) {
status = {
res: false,
msg: "No such file exists",
};
}
if (!status.res && status.msg) {
Terminal.error(status.msg);
}
} }

@ -18,6 +18,7 @@ export function runScript(commandArgs: (string | number | boolean)[], server: Ba
} }
const scriptName = Terminal.getFilepath(commandArgs[0] + ""); const scriptName = Terminal.getFilepath(commandArgs[0] + "");
if (!scriptName) return Terminal.error(`Invalid filename: ${commandArgs[0]}`);
const runArgs = { "--tail": Boolean, "-t": Number }; const runArgs = { "--tail": Boolean, "-t": Number };
const flags = libarg(runArgs, { const flags = libarg(runArgs, {

@ -10,6 +10,7 @@ export function scp(args: (string | number | boolean)[], server: BaseServer): vo
return; return;
} }
const scriptname = Terminal.getFilepath(args[0] + ""); const scriptname = Terminal.getFilepath(args[0] + "");
if (!scriptname) return Terminal.error(`Invalid filename: ${args[0]}`);
if (!scriptname.endsWith(".lit") && !isScriptFilename(scriptname) && !scriptname.endsWith(".txt")) { if (!scriptname.endsWith(".lit") && !isScriptFilename(scriptname) && !scriptname.endsWith(".txt")) {
Terminal.error("scp only works for scripts, text files (.txt), and literature files (.lit)"); Terminal.error("scp only works for scripts, text files (.txt), and literature files (.lit)");
return; return;

@ -11,6 +11,7 @@ export function tail(commandArray: (string | number | boolean)[], server: BaseSe
Terminal.error("Incorrect number of arguments. Usage: tail [script] [arg1] [arg2]..."); Terminal.error("Incorrect number of arguments. Usage: tail [script] [arg1] [arg2]...");
} else if (typeof commandArray[0] === "string") { } else if (typeof commandArray[0] === "string") {
const scriptName = Terminal.getFilepath(commandArray[0]); const scriptName = Terminal.getFilepath(commandArray[0]);
if (!scriptName) return Terminal.error(`Invalid filename: ${commandArray[0]}`);
if (!isScriptFilename(scriptName)) { if (!isScriptFilename(scriptName)) {
Terminal.error(`tail can only be called on ${validScriptExtensions.join(", ")} files, or by PID`); Terminal.error(`tail can only be called on ${validScriptExtensions.join(", ")} files, or by PID`);
return; return;

@ -12,7 +12,7 @@ export function wget(args: (string | number | boolean)[], server: BaseServer): v
const url = args[0] + ""; const url = args[0] + "";
const target = Terminal.getFilepath(args[1] + ""); const target = Terminal.getFilepath(args[1] + "");
if (!isScriptFilename(target) && !target.endsWith(".txt")) { if (!target || (!isScriptFilename(target) && !target.endsWith(".txt"))) {
return Terminal.error(`wget failed: Invalid target file. Target file must be script or text file`); return Terminal.error(`wget failed: Invalid target file. Target file must be script or text file`);
} }
$.get( $.get(