com php-src: proc_open(): separate environment va lues that aren't strings: ext/standard/proc_open .c ext/standard/tests/streams/bug60602.phpt
| From: | Tjerk Anne Meesters | Date: | Sun, 02 Mar 2014 21:49:52 +0000 |
| Subject: | com php-src: proc_open(): separate environment va lues that aren't strings: ext/standard/proc_open .c ext/standard/tests/streams/bug60602.phpt | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-76312@lists.php.net to get a copy of this message | ||
Commit: e73c05b75e9b279acffe2320fd65e6e54cbd0b59
Author: Tjerk Meesters <datibbaw@php.net> Thu, 10 Oct 2013 20:21:14 +0800
Parents: 362b70a32cd21a1f31c761b594578c45dd064568
Branches: PHP-5.4 PHP-5.5 PHP-5.6 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=e73c05b75e9b279acffe2320fd65e6e54cbd0b59
Log:
proc_open(): separate environment values that aren't strings
Added a test case
Changed paths:
M ext/standard/proc_open.c
A ext/standard/tests/streams/bug60602.phpt
Diff:
diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c
index b22877c..7ffba0e 100644
--- a/ext/standard/proc_open.c
+++ b/ext/standard/proc_open.c
@@ -112,8 +112,17 @@ static php_process_env_t _php_array_to_envp(zval *environment, int
is_persistent
zend_hash_get_current_data_ex(target_hash, (void **) &element, &pos) == SUCCESS;
zend_hash_move_forward_ex(target_hash, &pos)) {
- convert_to_string_ex(element);
- el_len = Z_STRLEN_PP(element);
+ if (Z_TYPE_PP(element) != IS_STRING) {
+ zval tmp;
+
+ MAKE_COPY_ZVAL(element, &tmp);
+ convert_to_string(&tmp);
+ el_len = Z_STRLEN(tmp);
+
+ zval_dtor(&tmp);
+ } else {
+ el_len = Z_STRLEN_PP(element);
+ }
if (el_len == 0) {
continue;
}
@@ -125,7 +134,7 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent
if (string_length == 0) {
continue;
}
- sizeenv += string_length+1;
+ sizeenv += string_length;
break;
}
}
@@ -138,19 +147,26 @@ static php_process_env_t _php_array_to_envp(zval *environment, int
is_persistent
for (zend_hash_internal_pointer_reset_ex(target_hash, &pos);
zend_hash_get_current_data_ex(target_hash, (void **) &element, &pos) == SUCCESS;
zend_hash_move_forward_ex(target_hash, &pos)) {
+ zval tmp;
- convert_to_string_ex(element);
- el_len = Z_STRLEN_PP(element);
+ if (Z_TYPE_PP(element) != IS_STRING) {
+ MAKE_COPY_ZVAL(element, &tmp);
+ convert_to_string(&tmp);
+ } else {
+ tmp = **element;
+ }
+
+ el_len = Z_STRLEN(tmp);
if (el_len == 0) {
- continue;
+ goto next_element;
}
- data = Z_STRVAL_PP(element);
+ data = Z_STRVAL(tmp);
switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_length,
&num_key, 0, &pos)) {
case HASH_KEY_IS_STRING:
if (string_length == 0) {
- continue;
+ goto next_element;
}
l = string_length + el_len + 1;
@@ -175,6 +191,11 @@ static php_process_env_t _php_array_to_envp(zval *environment, int
is_persistent
case HASH_KEY_NON_EXISTANT:
break;
}
+
+next_element:
+ if (Z_TYPE_PP(element) != IS_STRING) {
+ zval_dtor(&tmp);
+ }
}
assert((uint)(p - env.envp) <= sizeenv);
diff --git a/ext/standard/tests/streams/bug60602.phpt b/ext/standard/tests/streams/bug60602.phpt
new file mode 100644
index 0000000..2c08ce8
--- /dev/null
+++ b/ext/standard/tests/streams/bug60602.phpt
@@ -0,0 +1,57 @@
+--TEST--
+Bug #60602 proc_open() modifies environment if it contains arrays
+--FILE--
+<?php
+
+$descs = array(
+ 0 => array('pipe', 'r'), // stdin
+ 1 => array('pipe', 'w'), // stdout
+ 2 => array('pipe', 'w'), // strerr
+);
+
+$environment = array('test' => array(1, 2, 3));
+
+$cmd = (substr(PHP_OS, 0, 3) == 'WIN') ? 'dir' : 'ls';
+$p = proc_open($cmd, $descs, $pipes, '.', $environment);
+
+if (is_resource($p)) {
+ $data = '';
+
+ while (1) {
+ $w = $e = NULL;
+ $n = stream_select($pipes, $w, $e, 300);
+
+ if ($n === false) {
+ echo "no streams \n";
+ break;
+ } else if ($n === 0) {
+ echo "process timed out\n";
+ proc_terminate($p, 9);
+ break;
+ } else if ($n > 0) {
+ $line = fread($pipes[1], 8192);
+ if (strlen($line) == 0) {
+ /* EOF */
+ break;
+ }
+ $data .= $line;
+ }
+ }
+ var_dump(strlen($data));
+
+ $ret = proc_close($p);
+ var_dump($ret);
+ var_dump(is_array($environment['test']));
+} else {
+ echo "no process\n";
+}
+?>
+==DONE==
+--EXPECTF--
+Notice: Array to string conversion in %s on line %d
+
+Notice: Array to string conversion in %s on line %d
+int(%d)
+int(0)
+bool(true)
+==DONE==