]> granicus.if.org Git - php/commitdiff
fixed bug #60116 escapeshellcmd() cannot escape the dangerous quotes.
authorRui Hirokawa <hirokawa@php.net>
Sun, 23 Oct 2011 13:49:54 +0000 (13:49 +0000)
committerRui Hirokawa <hirokawa@php.net>
Sun, 23 Oct 2011 13:49:54 +0000 (13:49 +0000)
ext/standard/basic_functions.c
ext/standard/exec.c
ext/standard/exec.h

index 568e719e03d288a7cd02b9b18090f52f53006ef4..fa80fd230d862d07c52e0c753b3de40a193aab43 100644 (file)
@@ -3614,6 +3614,7 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
 #endif
 
        register_phpinfo_constants(INIT_FUNC_ARGS_PASSTHRU);
+       register_exec_constants(INIT_FUNC_ARGS_PASSTHRU);
        register_html_constants(INIT_FUNC_ARGS_PASSTHRU);
        register_string_constants(INIT_FUNC_ARGS_PASSTHRU);
 
index ac96fe68155ff38d9af560e66d1481897401621f..ab3100dfbc9b773ec648de4833d0db9246da9d23 100644 (file)
 #include <unistd.h>
 #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
  * If type==0, only last line of output is returned (exec)
  * 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
 */
-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);
        char *cmd;
@@ -266,14 +276,26 @@ PHPAPI char *php_escape_shell_cmd(char *str)
 #ifndef PHP_WIN32
                        case '"':
                        case '\'':
-                               if (!p && (p = memchr(str + x + 1, str[x], l - x - 1))) {
-                                       /* noop */
-                               } else if (p && *p == str[x]) {
-                                       p = NULL;
-                               } else {
+                               if (flag == ESCAPE_CMD_ALL) {
                                        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;
 #else
                        /* % 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
  */
 PHPAPI char *php_escape_shell_arg(char *str)
@@ -397,14 +427,15 @@ PHP_FUNCTION(escapeshellcmd)
 {
        char *command;
        int command_len;
+       long flag = ESCAPE_CMD_PAIR;
        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;
        }
 
        if (command_len) {
-               cmd = php_escape_shell_cmd(command);
+               cmd = php_escape_shell_cmd_ex(command, flag);
                RETVAL_STRING(cmd, 0);
        } else {
                RETVAL_EMPTY_STRING();
index 394ac213ca64a3f762f28ef0461f966e5f2fd97b..f6b1fa42e9e39ecd44d728f59e01e1c298e36dc3 100644 (file)
 #ifndef 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(exec);
 PHP_FUNCTION(escapeshellcmd);