exec(): quoting full command in Windows

后端 未结 1 637
一向
一向 2021-01-15 01:21

I\'ve written a web application that makes use of exec() in order to run an external program. The program path is configurable and can be expected to have spaces on its name

相关标签:
1条回答
  • 2021-01-15 02:08

    I've written this quick and dirty workaround:

    <?php
    
    class Thumb{
        const GM_PATH = 'C:\\Archivos de programa\\GraphicsMagick-1.3.12-Q16\\gm.exe';
    
        /**
         * Quote full command if required by server (program + arguments)
         */
        private static function quoteFullCommand($command){
            // Test only once per script
            static $extra_quotes_required=NULL;
    
            if( is_null($extra_quotes_required) ){
                if(PHP_OS=='WINNT'){
                    // This call will be correct (0) if and only if the server requires extra quotes
                    exec('""sort" /?"', $output, $return);
                    $extra_quotes_required = $return==0;
                }else{
                    $extra_quotes_required = FALSE;
                }
            }
            if($extra_quotes_required){
                $command = '"' . $command . '"';
            }
    
            return $command;
        }
    
    
        /**
         * Return output from "gm version"
         */
        public static function graphicsMagickVersion(){
            $command = escapeshellarg(self::GM_PATH) . ' version ';
            $command = self::quoteFullCommand($command);
            exec($command, $output, $return);
    
            return trim(implode(PHP_EOL, $output));
        }
    }
    

    However, it'd be way better to predict it from PHP version or server OS so links to documentation or further tips are welcome.

    Update: I've had a look at the piece of PHP source code that takes care of running external commands in Windows:

    http://svn.php.net/viewvc/php/php-src/trunk/TSRM/tsrm_win32.c

    The following line adds the extra comas to the full command:

    sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command); 
    

    According to the file history, that line was first added on 29th May 2008 (r260429):

    MFH: Fix bug when command is quoted and parameters are quoted during call to exec, the result is that cmd.exe /c strips the first and last quote.

    The following PHP releases were 5.3.0 and 5.2.7 but the line is in the 5_3 branch and not in the 5_2 one. I'm not familiar enough with PHP development process so I can't find the changelog or tell out to which exact PHP releases the fix was ported to but I'd dare say that it was a bug in PHP and it was fixed in PHP/5.3.0 (yet it wasn't backported to 5.2 so they didn't break legacy stuff).

    So my workaround is probably overkill. You just need to test the PHP OS and version:

    if( PHP_OS=='WINNT' && version_compare(PHP_VERSION, '5.3.0', '<') ){
       $command = $command = '"' . $command . '"';
    }
    
    0 讨论(0)
提交回复
热议问题