fixed bug #60116 escapeshellcmd() cannot escape the dangerous quotes.

This commit is contained in:
Rui Hirokawa 2011-10-23 13:49:54 +00:00
parent 71a94c2225
commit f17a215493
3 changed files with 45 additions and 9 deletions

View File

@ -3614,6 +3614,7 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
#endif #endif
register_phpinfo_constants(INIT_FUNC_ARGS_PASSTHRU); register_phpinfo_constants(INIT_FUNC_ARGS_PASSTHRU);
register_exec_constants(INIT_FUNC_ARGS_PASSTHRU);
register_html_constants(INIT_FUNC_ARGS_PASSTHRU); register_html_constants(INIT_FUNC_ARGS_PASSTHRU);
register_string_constants(INIT_FUNC_ARGS_PASSTHRU); register_string_constants(INIT_FUNC_ARGS_PASSTHRU);

View File

@ -50,6 +50,16 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
/* {{{ register_exec_constants
* */
void register_exec_constants(INIT_FUNC_ARGS)
{
REGISTER_LONG_CONSTANT("ESCAPE_CMD_PAIR", ESCAPE_CMD_PAIR, CONST_PERSISTENT|CONST_CS);
REGISTER_LONG_CONSTANT("ESCAPE_CMD_END", ESCAPE_CMD_END, CONST_PERSISTENT|CONST_CS);
REGISTER_LONG_CONSTANT("ESCAPE_CMD_ALL", ESCAPE_CMD_ALL, CONST_PERSISTENT|CONST_CS);
}
/* }}} */
/* {{{ php_exec /* {{{ php_exec
* If type==0, only last line of output is returned (exec) * If type==0, only last line of output is returned (exec)
* If type==1, all lines will be printed and last lined returned (system) * If type==1, all lines will be printed and last lined returned (system)
@ -238,7 +248,7 @@ PHP_FUNCTION(passthru)
*NOT* safe for binary strings *NOT* safe for binary strings
*/ */
PHPAPI char *php_escape_shell_cmd(char *str) PHPAPI char *php_escape_shell_cmd_ex(char *str, int flag)
{ {
register int x, y, l = strlen(str); register int x, y, l = strlen(str);
char *cmd; char *cmd;
@ -266,14 +276,26 @@ PHPAPI char *php_escape_shell_cmd(char *str)
#ifndef PHP_WIN32 #ifndef PHP_WIN32
case '"': case '"':
case '\'': case '\'':
if (!p && (p = memchr(str + x + 1, str[x], l - x - 1))) { if (flag == ESCAPE_CMD_ALL) {
/* noop */
} else if (p && *p == str[x]) {
p = NULL;
} else {
cmd[y++] = '\\'; cmd[y++] = '\\';
cmd[y++] = str[x];
} else if (flag == ESCAPE_CMD_END) {
if (x == 0 || x == l - 1) {
cmd[y++] = str[x];
} else {
cmd[y++] = '\\';
cmd[y++] = str[x];
}
} else { /* ESCAPE_CMD_PAIR */
if (!p && (p = memchr(str + x + 1, str[x], l - x - 1))) {
/* noop */
} else if (p && *p == str[x]) {
p = NULL;
} else {
cmd[y++] = '\\';
}
cmd[y++] = str[x];
} }
cmd[y++] = str[x];
break; break;
#else #else
/* % is Windows specific for enviromental variables, ^%PATH% will /* % is Windows specific for enviromental variables, ^%PATH% will
@ -327,6 +349,14 @@ PHPAPI char *php_escape_shell_cmd(char *str)
} }
/* }}} */ /* }}} */
/* {{{ php_escape_shell_cmd
*/
PHPAPI char *php_escape_shell_cmd(char *str)
{
return php_escape_shell_cmd_ex(str, ESCAPE_CMD_PAIR);
}
/* }}} */
/* {{{ php_escape_shell_arg /* {{{ php_escape_shell_arg
*/ */
PHPAPI char *php_escape_shell_arg(char *str) PHPAPI char *php_escape_shell_arg(char *str)
@ -397,14 +427,15 @@ PHP_FUNCTION(escapeshellcmd)
{ {
char *command; char *command;
int command_len; int command_len;
long flag = ESCAPE_CMD_PAIR;
char *cmd = NULL; char *cmd = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &command, &command_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &command, &command_len, &flag) == FAILURE) {
return; return;
} }
if (command_len) { if (command_len) {
cmd = php_escape_shell_cmd(command); cmd = php_escape_shell_cmd_ex(command, flag);
RETVAL_STRING(cmd, 0); RETVAL_STRING(cmd, 0);
} else { } else {
RETVAL_EMPTY_STRING(); RETVAL_EMPTY_STRING();

View File

@ -21,6 +21,10 @@
#ifndef EXEC_H #ifndef EXEC_H
#define EXEC_H #define EXEC_H
#define ESCAPE_CMD_PAIR 0
#define ESCAPE_CMD_END 1
#define ESCAPE_CMD_ALL 2
PHP_FUNCTION(system); PHP_FUNCTION(system);
PHP_FUNCTION(exec); PHP_FUNCTION(exec);
PHP_FUNCTION(escapeshellcmd); PHP_FUNCTION(escapeshellcmd);