diff --git a/packages/core/src/codewhispererChat/tools/executeBash.ts b/packages/core/src/codewhispererChat/tools/executeBash.ts index bc6a517210d..7d916ca12d3 100644 --- a/packages/core/src/codewhispererChat/tools/executeBash.ts +++ b/packages/core/src/codewhispererChat/tools/executeBash.ts @@ -16,7 +16,9 @@ export enum CommandCategory { Destructive, } -export const dangerousPatterns = new Set(['<(', '$(', '`', '>', '&&', '||']) +export const dangerousPatterns = new Set(['<(', '$(', '`']) +export const splitOperators = new Set(['|', '&&', '||', '>']) +export const splitOperatorsArray = Array.from(splitOperators) export const commandCategories = new Map([ // ReadOnly commands ['ls', CommandCategory.ReadOnly], @@ -163,17 +165,17 @@ export class ExecuteBash { return { requiresAcceptance: true } } - // Split commands by pipe and process each segment + // Split commands by operators and process each segment let currentCmd: string[] = [] const allCommands: string[][] = [] for (const arg of args) { - if (arg === '|') { + if (splitOperators.has(arg)) { if (currentCmd.length > 0) { allCommands.push(currentCmd) } currentCmd = [] - } else if (arg.includes('|')) { + } else if (splitOperatorsArray.some((op) => arg.includes(op))) { return { requiresAcceptance: true } } else { currentCmd.push(arg) @@ -208,12 +210,12 @@ export class ExecuteBash { ) { return { requiresAcceptance: true, warning: highRiskCommandWarningMessage } } - return { requiresAcceptance: false } + continue default: return { requiresAcceptance: true, warning: highRiskCommandWarningMessage } } } - return { requiresAcceptance: true } + return { requiresAcceptance: false } } catch (error) { this.logger.warn(`Error while checking acceptance: ${(error as Error).message}`) return { requiresAcceptance: true } diff --git a/packages/core/src/test/codewhispererChat/tools/executeBash.test.ts b/packages/core/src/test/codewhispererChat/tools/executeBash.test.ts index 38a2e411187..b8c4baf9439 100644 --- a/packages/core/src/test/codewhispererChat/tools/executeBash.test.ts +++ b/packages/core/src/test/codewhispererChat/tools/executeBash.test.ts @@ -5,7 +5,7 @@ import { strict as assert } from 'assert' import sinon from 'sinon' -import { ExecuteBash } from '../../../codewhispererChat/tools/executeBash' +import { destructiveCommandWarningMessage, ExecuteBash } from '../../../codewhispererChat/tools/executeBash' import { ChildProcess } from '../../../shared/utilities/processUtils' describe('ExecuteBash Tool', () => { @@ -46,6 +46,11 @@ describe('ExecuteBash Tool', () => { const execBash = new ExecuteBash({ command: 'ls && rm -rf /' }) const needsAcceptance = execBash.requiresAcceptance().requiresAcceptance assert.equal(needsAcceptance, true, 'Should require acceptance for dangerous pattern') + assert.equal( + execBash.requiresAcceptance().warning, + destructiveCommandWarningMessage, + 'Warning message should match the destructiveCommandWarningMessage' + ) }) it('set requiresAcceptance=false if it is a read-only command', () => {