From 8aacd85ba2a5b1ae0148a7c904e573023a2579cb Mon Sep 17 00:00:00 2001 From: Amber Torrise Date: Thu, 19 Oct 2023 14:56:49 -0400 Subject: [PATCH] fix to disallow invalid characters in filenames Signed-off-by: Amber Torrise --- src/cli/download/data-set/DataSet.Handler.ts | 32 ++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/cli/download/data-set/DataSet.Handler.ts b/src/cli/download/data-set/DataSet.Handler.ts index a7e9f01f..ac53a7a4 100644 --- a/src/cli/download/data-set/DataSet.Handler.ts +++ b/src/cli/download/data-set/DataSet.Handler.ts @@ -14,7 +14,34 @@ import { FTPBaseHandler } from "../../../FTPBase.Handler"; import { IFTPHandlerParams } from "../../../IFTPHandlerParams"; import { FTPProgressHandler } from "../../../FTPProgressHandler"; import { DataSetUtils, TRANSFER_TYPE_ASCII, TRANSFER_TYPE_ASCII_RDW, TRANSFER_TYPE_BINARY, TRANSFER_TYPE_BINARY_RDW } from "../../../api"; +import { ImperativeError } from "@zowe/imperative"; +function isValidFileName(fileName: string) { + //to prevent magic number eslint errors + const iso8859_1_start_first = 32; // first valid code point for first chunk of valid characters in the ISO/IEC 8859-1 table + const iso8859_1_end_first = 127; + const iso8859_1_start_second = 160; //second chunk of valid characters + const iso8859_1_end_second = 255; + const binary = 2; + const hexadecimal = 16; + + const unicodeString = fileName.split('').map(char => `U+${char.charCodeAt(0).toString(hexadecimal).toUpperCase()}`).join(' '); + const codePoints = unicodeString.split(' '); + + for (const codePoint of codePoints) { + // Extract the decimal representation from the code point (e.g., ☻ = U+263B => 9787) + const decimalRepresentation = parseInt(codePoint.substring(binary), hexadecimal); + + // Check if the code point is in the range of valid characters (valid numbers deduced from https://en.wikipedia.org/wiki/ISO/IEC_8859-1) + if ((decimalRepresentation >= iso8859_1_start_first && decimalRepresentation <= iso8859_1_end_first) || + (decimalRepresentation >= iso8859_1_start_second && decimalRepresentation <= iso8859_1_end_second)) + { + // If any invalid code point is found, return false + return false; + } + } + return true; +} export default class DownloadDataSetHandler extends FTPBaseHandler { public async processFTP(params: IFTPHandlerParams): Promise { @@ -22,6 +49,11 @@ export default class DownloadDataSetHandler extends FTPBaseHandler { ZosFilesUtils.getDirsFromDataSet(params.arguments.dataSet) : params.arguments.file; + // Validate the file name before proceeding + if (!isValidFileName(file)) { + throw new ImperativeError({msg: "Invalid file name. Please check the file name for typos."}); + } + let progress; if (params.response && params.response.progress) { progress = new FTPProgressHandler(params.response.progress, true);