Skip to content

Commit 42a70f4

Browse files
committed
Review
1 parent 94ccab6 commit 42a70f4

File tree

2 files changed

+57
-11
lines changed

2 files changed

+57
-11
lines changed

ext/pcntl/pcntl.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -651,14 +651,18 @@ PHP_FUNCTION(pcntl_exec)
651651
efree(argv);
652652
RETURN_THROWS();
653653
}
654-
// TODO Check element does not have nul bytes?
654+
if (zend_str_has_nul_byte(Z_STR_P(element))) {
655+
zend_argument_value_error(2, "individual argument must not contain null bytes");
656+
efree(argv);
657+
RETURN_THROWS();
658+
}
655659

656660
*current_arg = Z_STRVAL_P(element);
657661
current_arg++;
658662
} ZEND_HASH_FOREACH_END();
659663
*current_arg = NULL;
660664
} else {
661-
argv = safe_emalloc(2, sizeof(char *), 0);
665+
argv = emalloc(2 * sizeof(char *));
662666
argv[0] = path;
663667
argv[1] = NULL;
664668
}
@@ -679,25 +683,31 @@ PHP_FUNCTION(pcntl_exec)
679683
goto cleanup_env_vars;
680684
}
681685

686+
if (zend_str_has_nul_byte(element_str)) {
687+
zend_argument_value_error(3, "value for environment variable must not contain null bytes");
688+
zend_string_release_ex(element_str, false);
689+
goto cleanup_env_vars;
690+
}
691+
692+
/* putenv() allows integer environment variables */
682693
if (!key) {
683-
// TODO Does it even make sense to have an environment variable which is an integer?
684694
key = zend_long_to_str((zend_long) key_num);
685695
} else {
696+
if (zend_str_has_nul_byte(key)) {
697+
zend_argument_value_error(3, "name for environment variable must not contain null bytes");
698+
zend_string_release_ex(element_str, false);
699+
goto cleanup_env_vars;
700+
}
686701
zend_string_addref(key);
687702
}
688703

689-
// TODO Check key and element do not have nul bytes?
690-
691704
/* Length of element + equal sign + length of key + null */
692-
const uint8_t equal_len = strlen("=");
693-
size_t pair_length = ZSTR_LEN(element_str) + equal_len + ZSTR_LEN(key) + 1;
694-
ZEND_ASSERT(pair_length < SIZE_MAX);
695-
*pair = emalloc(pair_length);
705+
*pair = safe_emalloc(ZSTR_LEN(element_str) + 1, sizeof(char), ZSTR_LEN(key) + 1);
696706
/* Copy key=element + final null byte into buffer */
697707
memcpy(*pair, ZSTR_VAL(key), ZSTR_LEN(key));
698-
memcpy(*pair + ZSTR_LEN(key), "=", equal_len);
708+
(*pair)[ZSTR_LEN(key)] = '=';
699709
/* Copy null byte */
700-
memcpy(*pair + ZSTR_LEN(key) + equal_len, ZSTR_VAL(element_str), ZSTR_LEN(element_str) + 1);
710+
memcpy(*pair + ZSTR_LEN(key) + 1, ZSTR_VAL(element_str), ZSTR_LEN(element_str) + 1);
701711

702712
/* Cleanup */
703713
zend_string_release_ex(key, false);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
pcntl_exec(): Test cleanup after value that contain null bytes has been encountered for $args and $env_vars.
3+
--EXTENSIONS--
4+
pcntl
5+
--FILE--
6+
<?php
7+
try {
8+
pcntl_exec('cmd', ['-n', "value\0null\0byte"]);
9+
} catch (Throwable $e) {
10+
echo $e::class, ': ', $e->getMessage(), "\n";
11+
}
12+
13+
try {
14+
pcntl_exec(
15+
'cmd',
16+
['-n'],
17+
['var1' => 'value1', 'var2' => "value\0null\0byte"],
18+
);
19+
} catch (Throwable $e) {
20+
echo $e::class, ': ', $e->getMessage(), "\n";
21+
}
22+
23+
try {
24+
pcntl_exec(
25+
'cmd',
26+
['-n'],
27+
['var1' => 'value1', "key\0null\0byte" => "value2"],
28+
);
29+
} catch (Throwable $e) {
30+
echo $e::class, ': ', $e->getMessage(), "\n";
31+
}
32+
?>
33+
--EXPECT--
34+
ValueError: pcntl_exec(): Argument #2 ($args) individual argument must not contain null bytes
35+
ValueError: pcntl_exec(): Argument #3 ($env_vars) value for environment variable must not contain null bytes
36+
ValueError: pcntl_exec(): Argument #3 ($env_vars) name for environment variable must not contain null bytes

0 commit comments

Comments
 (0)