Skip to content

feat: detect unbalanced quotes in terminal commands to prevent hanging#11202

Draft
roomote[bot] wants to merge 1 commit intomainfrom
feature/EXT-737-handle-unbalanced-quotes
Draft

feat: detect unbalanced quotes in terminal commands to prevent hanging#11202
roomote[bot] wants to merge 1 commit intomainfrom
feature/EXT-737-handle-unbalanced-quotes

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Feb 4, 2026

Related GitHub Issue

Closes: EXT-737

Roo Code Task Context (Optional)

View task on Roo Code Cloud

Description

When a command has unbalanced quotes (e.g., echo "hello with a missing closing quote), the shell enters continuation mode waiting for more input. Since stdin is ignored in non-interactive mode (via execa), this causes the terminal to hang indefinitely.

This PR addresses the issue by:

  • Adding a validateCommandQuotes() function in parse-command.ts that detects unbalanced single and double quotes before command execution
  • Correctly handling escaped quotes (\" and ') and escaped backslashes (\\)
  • Handling special cases like heredocs (<<EOF) and ANSI-C quoting (`$'...'ExecuteCommandTool.tsbash

Important

Adds validateCommandQuotes to detect unbalanced quotes in commands, preventing terminal hangs, and integrates it into ExecuteCommandTool.

  • Behavior:
    • Adds validateCommandQuotes() in parse-command.ts to detect unbalanced quotes in commands.
    • Integrates quote validation in ExecuteCommandTool to prevent execution of commands with unbalanced quotes.
    • Handles escaped quotes, heredocs, and ANSI-C quoting.
  • Tests:
    • Adds tests in executeCommandTool.spec.ts for unbalanced quote detection.
    • Adds comprehensive tests in parse-command.spec.ts for validateCommandQuotes() covering various edge cases and shell-specific patterns.

This description was created by Ellipsis for 05bf270. You can customize this summary. It will automatically update as commits are pushed.

When a command has unbalanced quotes (missing closing quote), the shell
enters continuation mode waiting for more input. Since stdin is ignored
in non-interactive mode, this causes the terminal to hang indefinitely.

This change:
- Adds validateCommandQuotes() function in parse-command.ts to detect
  unbalanced single and double quotes before command execution
- Correctly handles escaped quotes (\" and \') and escaped backslashes (\\)
- Handles special cases like heredocs (<<EOF) and ANSI-C quoting ($'...')
- Integrates validation into ExecuteCommandTool.ts to reject commands
  with unbalanced quotes with a helpful error message
- Adds comprehensive tests for both the validation function and integration

Resolves EXT-737
@roomote
Copy link
Contributor Author

roomote bot commented Feb 4, 2026

Rooviewer Clock   See task on Roo Cloud

Review complete. Found 2 issues with the quote validation logic.

  • Heredoc pattern match bypasses quote validation, allowing commands like echo "hello && cat <<EOF to pass even though they would hang
  • ANSI-C quoting ($'...') doesn't handle escaped quotes inside the string, causing valid commands like echo $'it\'s' to be rejected

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

Comment on lines +36 to +42
// Check for heredoc patterns which legitimately expect more input
// Common heredoc patterns: <<EOF, <<-EOF, <<'EOF', <<"EOF", << 'EOF'
const heredocPattern = /<<-?\s*['"]?\w+['"]?\s*$/
if (heredocPattern.test(command.trim())) {
// Heredocs are valid multi-line constructs - don't flag as unbalanced
return { valid: true }
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The heredoc pattern check returns early before quote validation runs. This allows commands like echo "hello && cat <<EOF to pass validation, but the shell would still hang because <<EOF appears inside an unclosed double quote string. The heredoc syntax wouldn't be recognized since the << characters are part of the quoted content. Consider moving this check after the quote validation, or only applying the heredoc exemption when quotes up to that point are balanced.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +53 to +61
// Handle ANSI-C quoting: $'...' - treat as single quote
if (char === "$" && i + 1 < command.length && command[i + 1] === "'") {
if (!inSingleQuote && !inDoubleQuote) {
inSingleQuote = true
singleQuoteStart = i
i += 2 // Skip $'
continue
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ANSI-C quoting handling sets inSingleQuote = true but doesn't distinguish it from regular single quotes. Inside ANSI-C strings ($'...'), backslash escapes work differently than in regular single quotes. For example, echo $'it\'s' is a valid command that produces it's, but the current code would incorrectly flag it as having unbalanced quotes because \' inside the string is treated as a closing quote rather than an escaped quote. Consider tracking ANSI-C mode separately and allowing \' escapes within it.

Fix it with Roo Code or mention @roomote and request a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant