Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix to disallow invalid characters in filenames #142

Merged
merged 9 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

All notable changes to the z/OS FTP Plug-in for Zowe CLI will be documented in this file.

## Recent Changes
- BugFix: Provide new utility function that checks file names for valid characters [143](https://github.com/zowe/zowe-cli-ftp-plugin/issues/143).

## `2.1.3`

- Update example of `upload file-to-data-set` command.
Expand Down
36 changes: 36 additions & 0 deletions src/cli/Utilities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*
*/

export class Utilities{
/**
* Check to ensure filename only contains valid characters
* @param {fileName} string - filename to be evaluated
* @returns {Promise<boolean>} - promise that resolves to true if filename contains valid characters
* @memberof Utilities
*/
public static async isValidFileName(fileName: string): Promise<boolean> {
ATorrise marked this conversation as resolved.
Show resolved Hide resolved
// Define valid character ranges for ISO/IEC 8859-1 https://en.wikipedia.org/wiki/ISO/IEC_8859-1
const validRanges = [
{ start: 32, end: 127 }, // First chunk of valid characters
{ start: 160, end: 255 } // Second chunk of valid characters
];

// Check if each character in the filename is within a valid range
for (const char of fileName) {
const charCode = char.charCodeAt(0);
if (!validRanges.some(range => charCode >= range.start && charCode <= range.end)) {
return false;
}
}

return true;
}
}
53 changes: 34 additions & 19 deletions src/cli/download/data-set/DataSet.Handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,48 @@ 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";
import { Utilities } from "../../Utilities";

export default class DownloadDataSetHandler extends FTPBaseHandler {
public async processFTP(params: IFTPHandlerParams): Promise<void> {

const file = params.arguments.file == null ?
ZosFilesUtils.getDirsFromDataSet(params.arguments.dataSet) :
params.arguments.file;
try {
// Validate the destination file name before proceeding
if (!(await Utilities.isValidFileName(file))) {
ATorrise marked this conversation as resolved.
Show resolved Hide resolved
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);
}
let transferType = params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII;
if (params.arguments.rdw) {
transferType = params.arguments.binary ? TRANSFER_TYPE_BINARY_RDW : TRANSFER_TYPE_ASCII_RDW;
}
const options = {
localFile: file,
response: params.response,
transferType,
progress,
encoding: params.arguments.encoding
};
await DataSetUtils.downloadDataSet(params.connection, params.arguments.dataSet, options);

let progress;
if (params.response && params.response.progress) {
progress = new FTPProgressHandler(params.response.progress, true);
const successMsg = params.response.console.log(ZosFilesMessages.datasetDownloadedSuccessfully.message, file);
this.log.info(successMsg);
params.response.data.setMessage(successMsg);
}
let transferType = params.arguments.binary ? TRANSFER_TYPE_BINARY : TRANSFER_TYPE_ASCII;
if (params.arguments.rdw) {
transferType = params.arguments.binary ? TRANSFER_TYPE_BINARY_RDW : TRANSFER_TYPE_ASCII_RDW;
catch (e) {
if (e instanceof ImperativeError){
throw e;
}
throw new ImperativeError({
msg: `An error was encountered while trying to download your dataset '${file}'.\nError details: ${e.message}`
});
}
const options = {
localFile: file,
response: params.response,
transferType,
progress,
encoding: params.arguments.encoding
};
await DataSetUtils.downloadDataSet(params.connection, params.arguments.dataSet, options);

const successMsg = params.response.console.log(ZosFilesMessages.datasetDownloadedSuccessfully.message, file);
this.log.info(successMsg);
params.response.data.setMessage(successMsg);
}
}
Loading