Fix R run argument quoting#3271
Conversation
Greptile SummaryThis PR refactors the R binding's subprocess invocation from a single pasted shell string (
Confidence Score: 3/5Safe to merge for shell-quoting improvements at the invocation boundary, but The invocation-boundary fix is correct and well-tested at the R/R/flags.R — the Important Files Changed
|
| status_code <- system(cmd) | ||
| args <- run_argv(flow_file = flow_file, ...) | ||
| #message(paste0("Flow cli:\n", run_cmd(flow_file = flow_file, ...))) | ||
| status_code <- system2("Rscript", args = shell_quote_args(args)) |
There was a problem hiding this comment.
shell_quote_args is redundant when system2 already handles quoting on some platforms
system2 on POSIX (with the default stdout = "", stderr = "") joins the command and args into a shell string, so shQuote is correct and necessary here. However, on Windows system2 passes each element of args directly to CreateProcess and applies its own quoting; pre-quoting with shQuote would cause the double-quote characters to be treated as literal content by the child process.
The practical risk is low (metaflow's R binding primarily targets POSIX), and the old system(cmd) path was equally broken on Windows, so this is not a regression. Consider documenting the POSIX-only assumption in a comment, or passing args unquoted and setting stdout = NULL, stderr = NULL, stdin = NULL (which causes R to use execvp directly on POSIX, where no shell quoting is needed).
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
Hi @fallintoplace, fyi the R integration is basically deprecated so we are not accepting any contributions to it. |
agsaru
left a comment
There was a problem hiding this comment.
R module is deprecated so changes here do not matter anymore. Confirmed by the admin.
Summary
Updates the R
run()path to buildRscriptarguments as an argv vector and execute them throughsystem2(), with shell quoting applied at the execution boundary.Issue
No existing issue.
Reproduction
Runtime: local R binding
Commands to run:
Where evidence shows up: testthat output from the focused R tests.
Before
run_cmd()assembled one command string withpaste(), so values containing spaces, quotes, semicolons, or other shell-sensitive characters were interpreted as part of the shell command line instead of staying as single CLI arguments.After
run_argv()keeps each CLI token as a separate argument.run()passes the quoted argv vector tosystem2("Rscript", ...), andrun_cmd()now returns a shell-quoted display command.Root Cause
The R wrapper built a single shell command string by concatenating the wrapper path, flow RDS path, run mode, tags, parameters, batch identifiers, and extra args. That mixed argument construction with shell parsing, so argument boundaries depended on shell syntax instead of the values passed to
run().Why This Fix Is Correct
The fix separates command construction from command rendering.
run_argv()builds the intended CLI argument vector,run()quotes that vector only at thesystem2()boundary, andrun_cmd()remains available as a quoted display string.Failure Modes Considered
$, and unicode must remain single arguments.batch = TRUE, Step Functions commands, help, and vector-valued parameters.Tests
$, and unicode in tags, parameters, batch user/run IDs, andother_args.system2().git diff --checklocally.Rscriptis not installed in this environment.Non-Goals
run()executes.