hellow
hellow

Reputation: 13420

Combination of escapeshellcmd and escapeshellarg

I found a very strange bug in my application today and I am not properly sure, how to fix it.

A form allows a user to do something. For this it needs to invoke a external command via system. So I decided to use escapeshellcmd for this purpose.

<?php
$foo = "abc&d";
$bar = "abc d";

$command = sprintf("/bin/command '%s' '%s'", $foo, $bar);
var_dump(escapeshellcmd($command)); //"/bin/command 'abc\&d' 'abc d'"
?>

which is not what I wanted (note the wrong \& which gives an extra, unwanted char '\'). So I came up with three different solutions and I don't know which one I should prefer, because only one gives me correct solution.

<?php
$foo = "abc&d";
$bar = "abc d";

$command1 = sprintf("/bin/command %s %s", $foo, $bar);
var_dump(escapeshellcmd($command1)); //"/bin/command abc\&d abc d" <- now we have three arguments

$command2 = sprintf("/bin/command %s %s", escapeshellarg($foo), escapeshellarg($bar));
var_dump($command2); //"/bin/command 'abc&d' 'abc d'" <- correct-ish?

$command3 = sprintf("/bin/command %s %s", escapeshellarg($foo), escapeshellarg($bar));
var_dump(escapeshellcmd($command3)); //"/bin/command 'abc\&d' 'abc d'" <- extra '\'
?>

Which of these solutions is prefered other the other? Why? Is there another (proper) solution for this dilemma?

Upvotes: 1

Views: 419

Answers (1)

Anonymous
Anonymous

Reputation: 12017

You should use:

$command2 = sprintf("/bin/command %s %s", escapeshellarg($foo), escapeshellarg($bar));
var_dump($command2); //"/bin/command 'abc&d' 'abc d'" <- correct-ish?

The only reason you would ever want to use escapeshellcmd is if you wanted to allow spaces within variables to separate arguments. If you just want to pass the arguments with escaping, use escapeshellarg.

Upvotes: 1

Related Questions