Skip to content

Commit d06081b

Browse files
committed
ext/standard: Make php_escape_shell_cmd() take a zend_string* instead of char*
This saves on an expensive strlen() computation
1 parent 5c19806 commit d06081b

File tree

5 files changed

+18
-16
lines changed

5 files changed

+18
-16
lines changed

UPGRADING.INTERNALS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ PHP 8.4 INTERNALS UPGRADE NOTES
246246
g. ext/standard
247247
- Added the php_base64_encode_ex() API with flag parameters, value can be
248248
PHP_BASE64_NO_PADDING to encode without the padding character '='.
249+
- The php_escape_shell_cmd() now takes a zend_string* instead of a char*
250+
Moreover, providing it with a binary safe string is the responsibility of
251+
the caller now.
249252

250253
========================
251254
4. OpCode changes

ext/mbstring/mbstring.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4654,9 +4654,9 @@ PHP_FUNCTION(mb_send_mail)
46544654

46554655
zend_string *force_extra_parameters = zend_ini_str_ex("mail.force_extra_parameters", strlen("mail.force_extra_parameters"), false, NULL);
46564656
if (force_extra_parameters) {
4657-
extra_cmd = php_escape_shell_cmd(ZSTR_VAL(force_extra_parameters));
4657+
extra_cmd = php_escape_shell_cmd(force_extra_parameters);
46584658
} else if (extra_cmd) {
4659-
extra_cmd = php_escape_shell_cmd(ZSTR_VAL(extra_cmd));
4659+
extra_cmd = php_escape_shell_cmd(extra_cmd);
46604660
}
46614661

46624662
RETVAL_BOOL(php_mail(to_r, ZSTR_VAL(subject), message, ZSTR_VAL(str_headers), extra_cmd ? ZSTR_VAL(extra_cmd) : NULL));

ext/standard/exec.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -279,16 +279,20 @@ PHP_FUNCTION(passthru)
279279
280280
*NOT* safe for binary strings
281281
*/
282-
PHPAPI zend_string *php_escape_shell_cmd(const char *str)
282+
PHPAPI zend_string *php_escape_shell_cmd(const zend_string *unescaped_cmd)
283283
{
284284
size_t x, y;
285-
size_t l = strlen(str);
286-
uint64_t estimate = (2 * (uint64_t)l) + 1;
287285
zend_string *cmd;
288286
#ifndef PHP_WIN32
289287
char *p = NULL;
290288
#endif
291289

290+
ZEND_ASSERT(ZSTR_LEN(unescaped_cmd) == strlen(ZSTR_VAL(unescaped_cmd)) && "Must be a binary safe string");
291+
size_t l = ZSTR_LEN(unescaped_cmd);
292+
const char *str = ZSTR_VAL(unescaped_cmd);
293+
294+
uint64_t estimate = (2 * (uint64_t)l) + 1;
295+
292296
/* max command line length - two single quotes - \0 byte length */
293297
if (l > cmd_max_len - 2 - 1) {
294298
php_error_docref(NULL, E_ERROR, "Command exceeds the allowed length of %zu bytes", cmd_max_len);
@@ -471,18 +475,13 @@ PHPAPI zend_string *php_escape_shell_arg(const char *str)
471475
/* {{{ Escape shell metacharacters */
472476
PHP_FUNCTION(escapeshellcmd)
473477
{
474-
char *command;
475-
size_t command_len;
478+
zend_string *command;
476479

477480
ZEND_PARSE_PARAMETERS_START(1, 1)
478-
Z_PARAM_STRING(command, command_len)
481+
Z_PARAM_PATH_STR(command)
479482
ZEND_PARSE_PARAMETERS_END();
480483

481-
if (command_len) {
482-
if (command_len != strlen(command)) {
483-
zend_argument_value_error(1, "must not contain any null bytes");
484-
RETURN_THROWS();
485-
}
484+
if (ZSTR_LEN(command)) {
486485
RETVAL_STR(php_escape_shell_cmd(command));
487486
} else {
488487
RETVAL_EMPTY_STRING();

ext/standard/exec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
PHP_MINIT_FUNCTION(proc_open);
2121
PHP_MINIT_FUNCTION(exec);
2222

23-
PHPAPI zend_string *php_escape_shell_cmd(const char *str);
23+
PHPAPI zend_string *php_escape_shell_cmd(const zend_string *unescaped_cmd);
2424
PHPAPI zend_string *php_escape_shell_arg(const char *str);
2525
PHPAPI int php_exec(int type, const char *cmd, zval *array, zval *return_value);
2626

ext/standard/mail.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,9 @@ PHP_FUNCTION(mail)
313313

314314
zend_string *force_extra_parameters = zend_ini_str_ex("mail.force_extra_parameters", strlen("mail.force_extra_parameters"), false, NULL);
315315
if (force_extra_parameters) {
316-
extra_cmd = php_escape_shell_cmd(ZSTR_VAL(force_extra_parameters));
316+
extra_cmd = php_escape_shell_cmd(force_extra_parameters);
317317
} else if (extra_cmd) {
318-
extra_cmd = php_escape_shell_cmd(ZSTR_VAL(extra_cmd));
318+
extra_cmd = php_escape_shell_cmd(extra_cmd);
319319
}
320320

321321
if (php_mail(to_r, subject_r, message, headers_str && ZSTR_LEN(headers_str) ? ZSTR_VAL(headers_str) : NULL, extra_cmd ? ZSTR_VAL(extra_cmd) : NULL)) {

0 commit comments

Comments
 (0)