Skip to content

Commit

Permalink
Merge pull request #3728 from zowe/v2.x/bugfix/Dollar
Browse files Browse the repository at this point in the history
Treat special chars and more
  • Loading branch information
MarkAckert authored Feb 20, 2024
2 parents 2d8b04d + 274a307 commit f4f61a7
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 18 deletions.
3 changes: 2 additions & 1 deletion bin/libs/configmgr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import * as os from 'cm_os';
import * as xplatform from 'xplatform';
import { ConfigManager } from 'Configuration';
import * as fs from './fs';
import * as stringlib from './string';

import * as objUtils from '../utils/ObjUtils';

Expand Down Expand Up @@ -415,7 +416,7 @@ function getMemberNameFromConfigPath(configPath: string): string|undefined {
function stripMemberName(configPath: string, memberName: string): string {
//Turn PARMLIB(my.zowe(yaml)):PARMLIB(my.other.zowe(yaml))
//Into PARMLIB(my.zowe):FILE(/some/path.yaml):PARMLIB(my.other.zowe)
const replacer = new RegExp('\\('+memberName+'\\)\\)', 'gi');
const replacer = new RegExp('\\('+stringlib.escapeDollar(memberName)+'\\)\\)', 'gi');
return configPath.replace(replacer, ")");
}

Expand Down
13 changes: 13 additions & 0 deletions bin/libs/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,3 +344,16 @@ export function itemInList(stringList: string, stringToFind?: string, separator:
}
return stringList.split(separator).includes(stringToFind);
}

export function escapeDollar(str: string): string | undefined {
if (str === null || str === undefined)
return undefined;
return str.replace(/[$]/g, '\\$&');
}

export function escapeRegExp(str: string): string | undefined {
if (str === null || str === undefined)
return undefined;
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

27 changes: 13 additions & 14 deletions bin/libs/zos-dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import * as shell from './shell';
import * as zoslib from './zos';

export function isDatasetExists(datasetName: string): boolean {
const result = shell.execSync('sh', '-c', `cat "//'${datasetName}'" 1>/dev/null 2>&1`);
const result = shell.execSync('sh', '-c', `cat "//'${stringlib.escapeDollar(datasetName)}'" 1>/dev/null 2>&1`);
return result.rc === 0;
}

Expand All @@ -27,7 +27,7 @@ export function isDatasetExists(datasetName: string): boolean {
// 1: data set is not in catalog
// 2: data set member doesn't exist
export function tsoIsDatasetExists(datasetName: string): number {
const result = zoslib.tsoCommand(`listds '${datasetName}' label`);
const result = zoslib.tsoCommand(`listds '${stringlib.escapeDollar(datasetName)}' label`);
if (result.rc != 0) {
if (result.out.includes('NOT IN CATALOG')) {
return 1;
Expand All @@ -44,7 +44,7 @@ export function tsoIsDatasetExists(datasetName: string): number {
}

export function createDataSet(dsName: string, dsOptions: string): number {
const result=zoslib.tsoCommand(`ALLOCATE NEW DA('${dsName}') ${dsOptions}`);
const result=zoslib.tsoCommand(`ALLOCATE NEW DA('${stringlib.escapeDollar(dsName)}') ${dsOptions}`);
return result.rc;
}

Expand All @@ -55,7 +55,7 @@ export function copyToDataset(filePath: string, dsName: string, cpOptions: strin
}
}

const cpCommand=`cp ${cpOptions} -v "${filePath}" "//'${dsName}'"`;
const cpCommand=`cp ${cpOptions} -v "${filePath}" "//'${stringlib.escapeDollar(dsName)}'"`;
common.printDebug('- '+cpCommand);
const result=shell.execOutSync('sh', '-c', `${cpCommand} 2>&1`);
if (result.rc == 0) {
Expand All @@ -79,7 +79,7 @@ export function datasetCopyToDataset(prefix: string, datasetFrom: string, datase
}
}

const cmd=`exec '${prefix}.${std.getenv('ZWE_PRIVATE_DS_SZWEEXEC')}(ZWEMCOPY)' '${datasetFrom} ${datasetTo}'`;
const cmd = `exec '${stringlib.escapeDollar(prefix)}.${std.getenv('ZWE_PRIVATE_DS_SZWEEXEC')}(ZWEMCOPY)' '${stringlib.escapeDollar(datasetFrom)} ${stringlib.escapeDollar(datasetTo)}'`;
const result = zoslib.tsoCommand(cmd);
return result.rc;
}
Expand All @@ -91,7 +91,7 @@ export function datasetCopyToDataset(prefix: string, datasetFrom: string, datase
// 1: there are some users
// @output output of operator command "d grs"
export function listDatasetUser(datasetName: string): number {
const cmd=`D GRS,RES=(*,${datasetName})`;
const cmd = `D GRS,RES=(*,'${stringlib.escapeDollar(datasetName)}')`;
const result=zoslib.operatorCommand(cmd);
return result.out.includes('NO REQUESTORS FOR RESOURCE') ? 0 : 1;
// example outputs:
Expand Down Expand Up @@ -128,7 +128,7 @@ export function listDatasetUser(datasetName: string): number {
// 3: data set is in use
// @output tso listds label output
export function deleteDataset(dataset: string): number {
const cmd=`delete '${dataset}'`;
const cmd=`delete '${stringlib.escapeDollar(dataset)}'`;
const result=zoslib.tsoCommand(cmd);
if (result.rc != 0) {
if (result.out.includes('NOT IN CATALOG')) {
Expand Down Expand Up @@ -170,7 +170,7 @@ export function isDatasetSmsManaged(dataset: string): { rc: number, smsManaged?:
// SMS flag is in `FORMAT 1 DSCB` section second line, after 780037

common.printTrace(`- Check if ${dataset} is SMS managed`);
const labelResult = zoslib.tsoCommand(`listds '${dataset}' label`);
const labelResult = zoslib.tsoCommand(`listds '${stringlib.escapeDollar(dataset)}' label`);
const datasetLabel=labelResult.out;
if (labelResult.rc == 0) {
let formatIndex = datasetLabel.indexOf('--FORMAT 1 DSCB--');
Expand Down Expand Up @@ -212,14 +212,13 @@ export function isDatasetSmsManaged(dataset: string): { rc: number, smsManaged?:

export function getDatasetVolume(dataset: string): { rc: number, volume?: string } {
common.printTrace(`- Find volume of data set ${dataset}`);
const result = zoslib.tsoCommand(`listds '${dataset}'`);
const result = zoslib.tsoCommand(`listds '${stringlib.escapeDollar(dataset)}'`);
if (result.rc == 0) {
let volumesIndex = result.out.indexOf('--VOLUMES--');
let volume: string;
if (volumesIndex != -1) {
let startIndex = volumesIndex + '--VOLUMES--'.length;
let endIndex = result.out.indexOf('--',startIndex);
volume = result.out.substring(startIndex, endIndex).trim();
volume = result.out.substring(startIndex).trim();
}
if (!volume) {
common.printError(" * Failed to find volume information of the data set.");
Expand All @@ -235,7 +234,7 @@ export function getDatasetVolume(dataset: string): { rc: number, volume?: string
export function apfAuthorizeDataset(dataset: string): number {
const result = isDatasetSmsManaged(dataset);
if (result.rc) {
common.printError("Error ZWEL0134E: Failed to find SMS status of data set ${dataset}.");
common.printError(`Error ZWEL0134E: Failed to find SMS status of data set ${dataset}.`);
return 134;
}

Expand All @@ -256,7 +255,7 @@ export function apfAuthorizeDataset(dataset: string): number {
}
}

const apfCmd="SETPROG APF,ADD,DSNAME=${dataset},${apfVolumeParam}"
const apfCmd=`SETPROG APF,ADD,DSNAME=${dataset},${apfVolumeParam}`;
if (std.getenv('ZWE_CLI_PARAMETER_SECURITY_DRY_RUN') == "true") {
common.printMessage("- Dry-run mode, security setup is NOT performed on the system.");
common.printMessage(" Please apply this operator command manually:");
Expand All @@ -277,7 +276,7 @@ export function apfAuthorizeDataset(dataset: string): number {
}

export function createDatasetTmpMember(dataset: string, prefix: string='ZW'): string | null {
common.printTrace(` > create_data_set_tmp_member in ${dataset}`);
common.printTrace(` > createDatasetTmpMember in ${dataset}`);
for (var i = 0; i < 100; i++) {
let rnd=Math.floor(Math.random()*10000);

Expand Down
4 changes: 2 additions & 2 deletions bin/libs/zos-fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function detectFileEncoding(fileName: string, expectedSample: string, exp

export function copyMvsToUss(dataset: string, file: string): number {
common.printDebug(`copyMvsToUss dataset=${dataset}, file=${file}`);
const result = shell.execSync('sh', '-c', `cp "//'${dataset}'" "${file}"`);
const result = shell.execSync('sh', '-c', `cp "//'${stringlib.escapeDollar(dataset)}'" '${file}'`);
return result.rc;
}

Expand All @@ -111,7 +111,7 @@ export function ensureFileEncoding(file: string, expectedSample: string, expecte
}
}
common.printTrace(`- Remove encoding tag of ${file}.`);
zos.changeTag(file, 0);
shell.execSync('sh', '-c', `chtag -r "${file}"`);
} else {
common.printTrace(`- Failed to detect encoding of ${file}.`);
}
Expand Down
2 changes: 1 addition & 1 deletion bin/libs/zos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import * as shell from './shell';
import * as stringlib from './string';

export function tsoCommand(...args:string[]): { rc: number, out: string } {
let message="tsocmd "+args.join(' ');
let message = "tsocmd " + '"' + args.join(' ') + '"';
common.printDebug('- '+message);
//we echo at the end to avoid a configmgr quirk where trying to read stdout when empty can hang waiting for bytes
const result = shell.execOutSync('sh', '-c', `${message} 2>&1 && echo '.'`);
Expand Down
3 changes: 3 additions & 0 deletions bin/libs/zwecli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ zwecli_inline_execute_command() {

export ZWE_PRIVATE_CLI_IS_TOP_LEVEL_COMMAND=false

print_trace "- zwecli_inline_execute_command"
print_trace " * ${*}"

# process new command
. "${ZWE_zowe_runtimeDirectory}/bin/zwe"

Expand Down

0 comments on commit f4f61a7

Please sign in to comment.