From 029305e754dde022c4c8ee48d392c16b61fffe2a Mon Sep 17 00:00:00 2001 From: Greg Sherwood Date: Mon, 27 Feb 2017 09:15:53 +1100 Subject: [PATCH] Code that uses shell_exec() and exec() now escapes cmds and args in case PHPCS is being used in a web service --- CodeSniffer/Fixer.php | 4 +++- CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php | 2 +- .../Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php | 5 +++-- CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php | 5 ++++- CodeSniffer/Standards/Generic/Sniffs/PHP/SyntaxSniff.php | 6 +++--- CodeSniffer/Standards/Squiz/Sniffs/Debug/JSLintSniff.php | 5 ++++- .../Standards/Squiz/Sniffs/Debug/JavaScriptLintSniff.php | 2 +- .../Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php | 2 +- package.xml | 3 +++ 9 files changed, 23 insertions(+), 11 deletions(-) diff --git a/CodeSniffer/Fixer.php b/CodeSniffer/Fixer.php index 302ccd4694..3481878361 100644 --- a/CodeSniffer/Fixer.php +++ b/CodeSniffer/Fixer.php @@ -266,7 +266,9 @@ public function generateDiff($filePath=null, $colors=true) // We must use something like shell_exec() because whitespace at the end // of lines is critical to diff files. - $cmd = "diff -u -L\"$filename\" -LPHP_CodeSniffer \"$filename\" \"$tempName\""; + $filename = escapeshellarg($filename); + $cmd = "diff -u -L$filename -LPHP_CodeSniffer $filename \"$tempName\""; + $diff = shell_exec($cmd); fclose($fixedFile); diff --git a/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php b/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php index feecdc5a0e..d73fd3db3a 100644 --- a/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php +++ b/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php @@ -66,7 +66,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) return; } - $cmd = $csslintPath.' '.escapeshellarg($fileName); + $cmd = escapeshellcmd($csslintPath).' '.escapeshellarg($fileName).' 2>&1'; exec($cmd, $output, $retval); if (is_array($output) === false) { diff --git a/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php b/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php index b264d575c3..8ef19460ae 100644 --- a/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php +++ b/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php @@ -83,8 +83,9 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) return; } - $cmd = "$lintPath --nosummary --notime --unix_mode \"$fileName\""; - $msg = exec($cmd, $output, $retval); + $lintPath = escapeshellcmd($lintPath); + $cmd = '$lintPath --nosummary --notime --unix_mode '.escapeshellarg($fileName); + $msg = exec($cmd, $output, $retval); if (is_array($output) === false) { return; diff --git a/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php b/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php index 715278e6b5..3c7c9b62a3 100644 --- a/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php +++ b/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php @@ -70,7 +70,10 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) return; } - $cmd = "$rhinoPath \"$jshintPath\" \"$fileName\""; + $rhinoPath = escapeshellcmd($rhinoPath); + $jshintPath = escapeshellcmd($jshintPath); + + $cmd = "$rhinoPath \"$jshintPath\" ".escapeshellarg($fileName); $msg = exec($cmd, $output, $retval); if (is_array($output) === true) { diff --git a/CodeSniffer/Standards/Generic/Sniffs/PHP/SyntaxSniff.php b/CodeSniffer/Standards/Generic/Sniffs/PHP/SyntaxSniff.php index 42b4e48b4f..3f76e84836 100644 --- a/CodeSniffer/Standards/Generic/Sniffs/PHP/SyntaxSniff.php +++ b/CodeSniffer/Standards/Generic/Sniffs/PHP/SyntaxSniff.php @@ -73,11 +73,11 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) } } - $fileName = $phpcsFile->getFilename(); + $fileName = escapeshellarg($phpcsFile->getFilename()); if (defined('HHVM_VERSION') === false) { - $cmd = $this->_phpPath." -l -d error_prepend_string='' \"$fileName\" 2>&1"; + $cmd = escapeshellcmd($this->_phpPath)." -l -d error_prepend_string='' $fileName 2>&1"; } else { - $cmd = $this->_phpPath." -l \"$fileName\" 2>&1"; + $cmd = escapeshellcmd($this->_phpPath)." -l $fileName 2>&1"; } $output = shell_exec($cmd); diff --git a/CodeSniffer/Standards/Squiz/Sniffs/Debug/JSLintSniff.php b/CodeSniffer/Standards/Squiz/Sniffs/Debug/JSLintSniff.php index dab011400c..4e3e6d14ff 100644 --- a/CodeSniffer/Standards/Squiz/Sniffs/Debug/JSLintSniff.php +++ b/CodeSniffer/Standards/Squiz/Sniffs/Debug/JSLintSniff.php @@ -68,7 +68,10 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) return; } - $cmd = "$rhinoPath \"$jslintPath\" \"$fileName\""; + $rhinoPath = escapeshellcmd($rhinoPath); + $jslintPath = escapeshellcmd($jslintPath); + + $cmd = "$rhinoPath \"$jslintPath\" ".escapeshellarg($fileName); $msg = exec($cmd, $output, $retval); if (is_array($output) === true) { diff --git a/CodeSniffer/Standards/Squiz/Sniffs/Debug/JavaScriptLintSniff.php b/CodeSniffer/Standards/Squiz/Sniffs/Debug/JavaScriptLintSniff.php index 75c8838af3..7cd992544a 100644 --- a/CodeSniffer/Standards/Squiz/Sniffs/Debug/JavaScriptLintSniff.php +++ b/CodeSniffer/Standards/Squiz/Sniffs/Debug/JavaScriptLintSniff.php @@ -66,7 +66,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) return; } - $cmd = '"'.$jslPath.'" -nologo -nofilelisting -nocontext -nosummary -output-format __LINE__:__ERROR__ -process "'.$fileName.'"'; + $cmd = '"'.escapeshellcmd($jslPath).'" -nologo -nofilelisting -nocontext -nosummary -output-format __LINE__:__ERROR__ -process '.escapeshellarg($fileName); $msg = exec($cmd, $output, $retval); // Variable $exitCode is the last line of $output if no error occurs, on diff --git a/CodeSniffer/Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php b/CodeSniffer/Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php index 3ee734dc79..25590372d8 100644 --- a/CodeSniffer/Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php +++ b/CodeSniffer/Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php @@ -63,7 +63,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) // In the command, 2>&1 is important because the code analyzer sends its // findings to stderr. $output normally contains only stdout, so using 2>&1 // will pipe even stderr to stdout. - $cmd = $analyzerPath.' '.$fileName.' 2>&1'; + $cmd = escapeshellcmd($analyzerPath).' '.escapeshellarg($fileName).' 2>&1'; // There is the possibility to pass "--ide" as an option to the analyzer. // This would result in an output format which would be easier to parse. diff --git a/package.xml b/package.xml index 84c884d1b1..2021af0c54 100644 --- a/package.xml +++ b/package.xml @@ -27,6 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> BSD 3-Clause License - The PHP-supplied T_COALESCE_EQUAL token has been replicated for PHP versions before 7.2 + - Code that uses shell_exec() and exec() now escapes cmds and args in case PHPCS is being used in a web service + -- This changes saves having to do filename and config validation before passing content to PHPCS + -- Thanks to Klaus Purer for reporting this - PEAR.Functions.FunctionDeclaration now reports an error for blank lines found inside a function declaration - PEAR.Functions.FunctionDeclaration no longer reports indent errors for blank lines in a function declaration - Squiz.Functions.MultiLineFunctionDeclaration no longer reports errors for blank lines in a function declaration