system2 doesn't quote stdin on unix, unlike stdout, stderr & input and on Windows

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

system2 doesn't quote stdin on unix, unlike stdout, stderr & input and on Windows

Ivan Krylov
Hi again!

While investigating the bug report [*] I found out that on unix, system2
does not quote its `stdin` argument while preparing the command line to launch.

It does shQuote the `stdout` and `stderr` arguments, and also the `f <-
tmpfile()` variable (which is used if `input` argument is provided),
which seems to set a precedent. On Windows, stdin, stdout, and stderr are handled independently of the shell, so it also just works without the use of shQuote by the caller.

Have people been relying on system2 not quoting the `stdin` argument, but
quoting `stdout` and `stderr`? For what it's worth, neither R_runR in
src/library/tools/R/check.R, nor .system_with_capture in
src/library/tools/R/utils.R (the only callers of system2(..., stdin = ...)),
nor their callers seem to be shQuote'ing the `stdin` argument.

Nor the rare system2(..., stdin = ...) callers (or their callers) on CRAN
seem to be quoting the `stdin` argument (I did find one exception [**]), it usually being "" or tmpfile() passed across a few function calls.

Given the considerations above, would the following patch be a good idea?

Index: src/library/base/R/unix/system.unix.R
===================================================================
--- src/library/base/R/unix/system.unix.R (revision 77566)
+++ src/library/base/R/unix/system.unix.R (working copy)
@@ -102,7 +102,7 @@
         writeLines(input, f)
         ## here 'command' is a single command, unlike system()
         command <- paste(command, "<", shQuote(f))
-    } else if (nzchar(stdin)) command <- paste(command, "<", stdin)
+    } else if (nzchar(stdin)) command <- paste(command, "<", shQuote(stdin))
     if(!wait && !intern) command <- paste(command, "&")
     .Internal(system(command, intern, timeout))
 }

--
Best regards,
Ivan

[*] https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17673

[**] https://github.com/search?q=org%3Acran+system2%28+stdin&type=Code
The search is probably computationally expensive and thus might only be available to GitHub account holders. The results are:

 - BatchJobs: R/WorkerLinux.R; stdin is "" by default, filenames generated by
   cfBrewTemplate aren't quoted
 - batchtools: callers of runOSCommand actually quote the stdin argument!
   https://github.com/mllg/batchtools/commit/4a5818d70c82c8842c0b8bded224dbb423b79f33
 - nat: R/cmtk.R, R/xformpoints.R; stdin is tempfile(...)
 - credentials: R/credential-api.R; stdin is passed as-is, tempfile() or
   "" in default arguments
 - runjags: R/setup.jags.jagsfile.R; stdin is constant "script.cmd"
 - m2r: R/m2.R; stdin is constant ""
 - scriptexec: R/scriptexec.R; stdin is passed as-is or default value retained
 - BioInstaller: inst/extdata/shiny/global_var.R; stdin is "" by default and
   passed as-is, callers of the sql2sqlite function don't quote the sql.file
   argument
 - annovarR: R/build.R: same sql2sqlite function as above

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: system2 doesn't quote stdin on unix, unlike stdout, stderr & input and on Windows

Tomas Kalibera
Thank you for the report, I agree that system2() should quote stdin. It
will be a change in behavior that is observable, but not documented (so
users/programs should not depend on it) and in addition seems to be a
bug. I'll still test on CRAN+BIOC packages, together with your patches
for PR17673.

Best,
Tomas

On 12/15/19 5:41 PM, Ivan Krylov wrote:

> Hi again!
>
> While investigating the bug report [*] I found out that on unix, system2
> does not quote its `stdin` argument while preparing the command line to launch.
>
> It does shQuote the `stdout` and `stderr` arguments, and also the `f <-
> tmpfile()` variable (which is used if `input` argument is provided),
> which seems to set a precedent. On Windows, stdin, stdout, and stderr are handled independently of the shell, so it also just works without the use of shQuote by the caller.
>
> Have people been relying on system2 not quoting the `stdin` argument, but
> quoting `stdout` and `stderr`? For what it's worth, neither R_runR in
> src/library/tools/R/check.R, nor .system_with_capture in
> src/library/tools/R/utils.R (the only callers of system2(..., stdin = ...)),
> nor their callers seem to be shQuote'ing the `stdin` argument.
>
> Nor the rare system2(..., stdin = ...) callers (or their callers) on CRAN
> seem to be quoting the `stdin` argument (I did find one exception [**]), it usually being "" or tmpfile() passed across a few function calls.
>
> Given the considerations above, would the following patch be a good idea?
>
> Index: src/library/base/R/unix/system.unix.R
> ===================================================================
> --- src/library/base/R/unix/system.unix.R (revision 77566)
> +++ src/library/base/R/unix/system.unix.R (working copy)
> @@ -102,7 +102,7 @@
>           writeLines(input, f)
>           ## here 'command' is a single command, unlike system()
>           command <- paste(command, "<", shQuote(f))
> -    } else if (nzchar(stdin)) command <- paste(command, "<", stdin)
> +    } else if (nzchar(stdin)) command <- paste(command, "<", shQuote(stdin))
>       if(!wait && !intern) command <- paste(command, "&")
>       .Internal(system(command, intern, timeout))
>   }
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel