fix(regen-defs): Fix globs and clean tempfiles on INT, TERM - #381
fix(regen-defs): Fix globs and clean tempfiles on INT, TERM#381aaronliu0130 wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds signal handling to the regen-defs.zsh script to clean up temporary files when interrupted, and uses eval to fix glob expansion in cpplint commands. The script processes .def test fixture files that contain cpplint commands with glob patterns (like src/*) and their expected outputs.
- Added trap handler for INT and TERM signals to clean up temporary files on interruption
- Changed command execution to use
evalto properly expand glob patterns in the commands - Refactored cleanup logic into a dedicated function
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| # Clean up temporary files | ||
| rm "$stdout_file" "$stderr_file" | ||
| cleanup |
There was a problem hiding this comment.
The cleanup function is only called on successful completion of a loop iteration (line 51), but not when errors occur earlier. If uv run fails or if any operation between lines 23-48 causes the script to exit, the temporary files will not be cleaned up.
Additionally, the trap handler won't catch normal exit conditions (like the exit calls on lines 6 and 11). Consider:
- Adding
EXITto the trap signals:trap cleanup INT TERM EXIT - Moving the trap setup earlier in the script to catch early exits
Note: If you add EXIT to the trap, you may need to prevent double-cleanup on line 51.
There was a problem hiding this comment.
I don't think a command in between can cause termination of the entire script, and as mentioned trapping EXIT can get a bit messy.
|
@aaronliu0130 I've opened a new pull request, #415, to work on those changes. Once the pull request is ready, I'll request review from you. |
I do not think "attackers controlling .def content" is a plausible scenario, but this does seem to be the better tool for the job.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughUpdates Changesregen-defs script updates
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
regen-defs.zsh(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build-test (3.x, windows-latest)
- GitHub Check: build-test (3.10, windows-latest)
🔇 Additional comments (2)
regen-defs.zsh (2)
51-51: Cleanup function call is well-placed.Calling
cleanupafter successful iteration completion ensures temp files are removed on the normal (non-signal) path. Combined with the trap handler, this provides cleanup in both success and interruption scenarios.
33-33: Zsh syntax${(~)cmd}is correct for enabling glob and tilde expansion.The syntax
${(~)cmd}is indeed the correct zsh parameter expansion flag for enablingGLOB_SUBST. This causes the expanded variable value to undergo glob pattern matching and tilde expansion—wildcards and~characters in the.deffile's first line will be expanded as patterns before being passed touv run "$cpplint".This aligns with the PR objective to fix globbing. However, the security concern you raised is legitimate: since
.deffile content is read directly without validation (line 20) and then expanded with glob patterns enabled (line 33), any glob patterns in.deffiles will be evaluated by the shell. This is safe only if.deffiles are from trusted sources. If.deffiles can be supplied by untrusted users, consider adding validation or escaping mechanisms to prevent unintended pattern expansion.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
regen-defs.zsh (2)
26-30: Add-fflag tormfor idempotent cleanup.The cleanup function should use
rm -finstead of plainrmto prevent errors if the temporary files don't exist and to make cleanup idempotent. This is especially important for signal handlers, which may be invoked at unexpected times.Apply this diff:
- cleanup() { - rm "$stdout_file" "$stderr_file" - } + cleanup() { + rm -f "$stdout_file" "$stderr_file" + }This aligns with the best practice discussed in prior review feedback for robust cleanup handlers.
33-33: Add a security note documenting that.deffiles must be trusted.Using
evalto execute the command line extracted from.deffiles requires that those files remain under your control. If a.deffile is compromised or maliciously modified, arbitrary code could execute. While this is a developer-internal tool and.deffiles are repo-controlled, it's good practice to document this assumption.Apply this diff to add a clarifying comment:
+ # Note: eval is used to enable glob expansion. .def files must be trusted; + # do not run this script on untrusted .def file input. eval uv run "$cpplint" $cmd > "$stdout_file" 2> "$stderr_file"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
regen-defs.zsh(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build-test (3.10, windows-latest)
- GitHub Check: build-test (3.x, windows-latest)
lovewave02
left a comment
There was a problem hiding this comment.
The signal handler cleans the temp files but does not terminate the script. In zsh, a handled INT or TERM resumes after the trap; a minimal reproduction prints CLEANED and then CONTINUED_AFTER_INT.
Here that means regen-defs.zsh can continue after Ctrl-C and rewrite the current .def file from partial output. Please have the handler clean up and exit with the matching signal status, and add a small regression check for the interrupted path.
see https://blog.tenstral.net/2026/04/hello-projects-directory.html . change mostly because this is what i now use
androvonx95
left a comment
There was a problem hiding this comment.
Nice to see the trap actually terminating now, but I think 53a1696 has a side effect: exit went into cleanup, and cleanup is also what replaced the rm at the end of each loop iteration.
# Clean up temporary files
cleanup # <- ends in `exit`, so the success path exits tooSo the run stops after the first .def file instead of continuing through the rest.
Also, trap cleanup INT TERM invokes the function with no arguments — $1 is only set in the TRAPINT()-style form — so exit $((128 + $1)) isn't valid arithmetic on either path.
Splitting the two responsibilities keeps the loop intact and still satisfies the signal-status request:
cleanup() { rm -f "$stdout_file" "$stderr_file"; }
trap 'cleanup; exit 130' INT
trap 'cleanup; exit 143' TERMWith the end-of-iteration call left as plain cleanup. I verified this control flow in bash (loop completes; INT exits 130) — I don't have the environment here, so you'll want to confirm on your side.
Unrelated to the title: e89746c swaps $HOME/Documents/cpplint for $HOME/Projects/cpplint, which just trades one local layout for another. Deriving it would work for everyone:
cpplint="${0:A:h}/cpplint.py"(set before the cd samples/).
yangfan-yf-yf
left a comment
There was a problem hiding this comment.
eval also drops the argument boundary provided by the quotes around $cpplint. For example, with:
cpplint='/tmp/cpplint checkout/cpplint.py'
cmd='--flag'
eval uv run "$cpplint" $cmdthe second parse passes /tmp/cpplint and checkout/cpplint.py as separate arguments. The previous non-eval form passed the configured path as one argument. This affects any checkout path containing whitespace, and deriving the path from the script location would still have the same problem if a parent directory contains a space.
Could the command expansion preserve $cpplint as one shell word through the second parse (for example, using zsh-safe quoting), with a regression case for a path containing whitespace? The Python suite is green on both the exact head (222 passed) and the current merge ref (231 passed), but it does not exercise regen-defs.zsh.
Summary by CodeRabbit
Bug Fixes
Refactor