mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-07-09 17:19:02 +00:00
fix(shell): handle pgrep review cases
This commit is contained in:
parent
abeafce818
commit
a74d45dde4
2 changed files with 94 additions and 4 deletions
|
|
@ -609,7 +609,13 @@ describe('detectSelfKillCommand', () => {
|
|||
it('detects kill commands using pgrep selectors for qwen-code hosts', () => {
|
||||
expect(detectSelfKillCommand('kill -9 $(pgrep node)')).toBe(true);
|
||||
expect(detectSelfKillCommand('kill $(pgrep -f node)')).toBe(true);
|
||||
expect(detectSelfKillCommand('kill -9 $(pgrep node | head -1)')).toBe(true);
|
||||
expect(detectSelfKillCommand('kill -9 `pgrep node | head -1`')).toBe(true);
|
||||
expect(detectSelfKillCommand('pgrep node | xargs kill')).toBe(true);
|
||||
expect(detectSelfKillCommand('pgrep node | xargs sudo kill')).toBe(true);
|
||||
expect(detectSelfKillCommand('pgrep node | xargs -I {} kill -9 {}')).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('detects taskkill inline and dash-prefixed image options', () => {
|
||||
|
|
|
|||
|
|
@ -208,6 +208,8 @@ export function splitCommands(command: string): string[] {
|
|||
let currentCommand = '';
|
||||
let inSingleQuotes = false;
|
||||
let inDoubleQuotes = false;
|
||||
let inBackticks = false;
|
||||
let substitutionDepth = 0;
|
||||
let i = 0;
|
||||
|
||||
const previousNonWhitespaceChar = (index: number): string | undefined => {
|
||||
|
|
@ -235,13 +237,42 @@ export function splitCommands(command: string): string[] {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (char === "'" && !inDoubleQuotes) {
|
||||
if (!inSingleQuotes && char === '`') {
|
||||
inBackticks = !inBackticks;
|
||||
} else if (
|
||||
!inSingleQuotes &&
|
||||
!inBackticks &&
|
||||
char === '$' &&
|
||||
nextChar === '('
|
||||
) {
|
||||
substitutionDepth++;
|
||||
currentCommand += '$(';
|
||||
i += 2;
|
||||
continue;
|
||||
} else if (!inBackticks && substitutionDepth > 0 && char === ')') {
|
||||
substitutionDepth--;
|
||||
} else if (
|
||||
!inBackticks &&
|
||||
substitutionDepth === 0 &&
|
||||
char === "'" &&
|
||||
!inDoubleQuotes
|
||||
) {
|
||||
inSingleQuotes = !inSingleQuotes;
|
||||
} else if (char === '"' && !inSingleQuotes) {
|
||||
} else if (
|
||||
!inBackticks &&
|
||||
substitutionDepth === 0 &&
|
||||
char === '"' &&
|
||||
!inSingleQuotes
|
||||
) {
|
||||
inDoubleQuotes = !inDoubleQuotes;
|
||||
}
|
||||
|
||||
if (!inSingleQuotes && !inDoubleQuotes) {
|
||||
if (
|
||||
!inSingleQuotes &&
|
||||
!inDoubleQuotes &&
|
||||
!inBackticks &&
|
||||
substitutionDepth === 0
|
||||
) {
|
||||
if (
|
||||
(char === '&' && nextChar === '&') ||
|
||||
(char === '|' && (nextChar === '|' || nextChar === '&'))
|
||||
|
|
@ -460,6 +491,28 @@ const PKILL_OPTIONS_WITH_VALUES = new Set([
|
|||
'--euid',
|
||||
]);
|
||||
|
||||
const XARGS_OPTIONS_WITH_VALUES = new Set([
|
||||
'-I',
|
||||
'-n',
|
||||
'-P',
|
||||
'-s',
|
||||
'-E',
|
||||
'-d',
|
||||
'-L',
|
||||
'-l',
|
||||
'-a',
|
||||
'-J',
|
||||
'-R',
|
||||
'--replace',
|
||||
'--max-args',
|
||||
'--max-procs',
|
||||
'--max-chars',
|
||||
'--eof',
|
||||
'--delimiter',
|
||||
'--max-lines',
|
||||
'--arg-file',
|
||||
]);
|
||||
|
||||
export const SHELL_SELF_KILL_REJECTION =
|
||||
'Blocked: this command may terminate the running qwen-code process because it targets all node/qwen-code processes. Use task_stop for managed background shells, or kill a specific PID instead.';
|
||||
|
||||
|
|
@ -773,6 +826,34 @@ function pgrepSubstitutionArgs(segment: string): string[] {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (char === '`') {
|
||||
let end = index + 1;
|
||||
let innerEscaped = false;
|
||||
for (; end < segment.length; end++) {
|
||||
const innerChar = segment[end]!;
|
||||
if (innerEscaped) {
|
||||
innerEscaped = false;
|
||||
continue;
|
||||
}
|
||||
if (innerChar === '\\') {
|
||||
innerEscaped = true;
|
||||
continue;
|
||||
}
|
||||
if (innerChar === '`') break;
|
||||
}
|
||||
if (end >= segment.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
const inner = segment.slice(index + 1, end).trim();
|
||||
const match = inner.match(/^pgrep\b(.*)$/i);
|
||||
if (match) {
|
||||
args.push(match[1] ?? '');
|
||||
}
|
||||
index = end;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char !== '$' || segment[index + 1] !== '(') {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -813,7 +894,10 @@ function xargsInvokesKill(segment: string | undefined): boolean {
|
|||
return false;
|
||||
}
|
||||
|
||||
const command = tokens.slice(1).find((token) => !isOptionToken(token));
|
||||
const commandTokens = unwrapExecutionPrefixes(
|
||||
commandArguments(tokens, XARGS_OPTIONS_WITH_VALUES),
|
||||
);
|
||||
const command = commandTokens.find((token) => !isOptionToken(token));
|
||||
return normalizeExecutableName(command ?? '') === 'kill';
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue