Repository navigation
fix(analyzer): treat a command wrapper with no command as complete - #779
Open
elliottwaves-20 wants to merge 1 commit into
Open
elliottwaves-20 wants to merge 1 commit into
elliottwaves-20 wants to merge 1 commit into
Conversation
A clause such as `| timeout |` in a Markdown parameter table, or `signal.alarm(timeout)` in host code, makes `_command_string_from_clause` see the wrapper `timeout` (also `sudo`, `nice`, `xargs`) followed directly by a control operator. Those branches returned "unresolved command string", so the file was recorded as `static_parse_limit`. The `env`, `command` and `nohup` branches already treat the same situation as "no command". When the wrapper's next token is `;`, `|`, `)` or `&` (but not `&>`), no other command can run, so report no command string. A redirection, a `(`, `&>` and the end of the view stay unresolved. Refs NVIDIA#694 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: elliottwaves-20 <pail1217@web.de>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A Markdown parameter table such as
makes
has_bounded_parse_exhaustion(static_patterns_tool_misuse) reportstatic_parse_limit, so the file is recorded as partially inspected and everySKILL.mdreference to it becomes anAE1. The same happens in host code such assignal.alarm(timeout)orif (timeout) {. Refs #694 (the Markdown table-cell case reported there).Root cause
_shell_clause_startsopens a new clause after every|and(, sotimeoutabove is read as the wrapper commandtimeout. Its next token is the control operator|, so_next_shell_invocation_wordreturnsNone. In_command_string_from_clausethesudo/nice/xargsandtimeoutbranches answerNonewith(True, None), which means "unresolved command string" and leads to exhaustion. Theenv/command/nohuppath answers the same situation with(False, None)(no command). That is whytimeout,sudo,niceandxargsreproduce andenv,nohupandcommanddo not, as noted in #694.timeout 5 |was already complete, because there the empty command is seen by the generic path.Fix
The wrappers that report no command string are
sudo,nice,xargsandtimeout. They do so when their next token is;,|,)or&, as long as the&is not followed by>. None of these wrappers can run another command at that point:sudoandtimeoutfail with usage,niceprints the niceness, andxargsdefaults toecho. A new helper_ends_wrapped_clausedecides this.Unchanged (stay partial):
sudo >log $CMD -rf /,sudo <in …,sudo &>log …).(, and the end of the view, where a fragment may continue.--handling.sh -c/evalcommand strings.analyze(). For example,`sudo rm -rf /`in a table cell still produces TM1.Tests
tests/nodes/analyzers/test_command_wrapper_without_command.pyhas 29 tests. 17 of them fail onmain, and all 12 fail-closed controls pass on both.timeout,sudo,niceandxargs, with and without a long tail.sudo | cat,sudo |& cat,timeout; echo,timeout && echo,xargs || true,nice & wait,(nice), anice ;;case item andsudo -u | cat.signal.alarm(timeout)and JavaScriptif (timeout).>,<,&>),timeout ($CMD) -rf /,x | sudo sh -c "$CMD",sudo |& sh -c "$CMD",sudo && eval "$CMD",sudo -s; eval "$CMD",case $a in sudo) $CMD -rf / ;; esac, and a wrapper at the end of the view (complete and fragment context).`sudo rm -rf /`keeps TM1, and`sudo $CMD -rf /`stays partial.run_static_patterns_with_ledgergives COMPLETED for the table and PARTIAL/STATIC_PARSE_LIMITfor the redirected wrapper.mainand are unrelated: release/CLI path tests and three parametrized collection errors.ruff checkandruff format --checkare clean.urllib3/connectionpool.py,grpc/_channel.pyand two Tavily reference pages. No file goes from complete to partial, and the TM1 count is unchanged (60).main: I generated about 3000 random shell fragments built from wrappers, operators, quotes, substitutions andrm/-rf /pieces. Every input that went from partial to complete was checked. The ones thatbash -naccepts are heredoc text, comments or wrappers without a command, such astimeout |echoand$(sudo ). No input went from complete to partial.Residual
sudo -s/sudo -ibefore a control operator now counts as "no command string", the same asshat the end of a pipeline already does. Stdin-fed shells are outside what this check models, and the docstring says so.#778 also handles the
timeoutwrapper names inside valid Python through Python token ownership. This PR covers the same root cause for every file type, including Markdown, JavaScript and Python fragments, and does not conflict with #778.🤖 Generated with Claude Code