diff --git a/ext/standard/mail.c b/ext/standard/mail.c index f6161782bdd76..8c8b4e6717e0b 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -614,34 +614,36 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c size_t msg_len = strlen(message); size_t new_len = 0; - for (size_t i = 0; i < msg_len - 1; ++i) { - if (message[i] == '\r' && message[i + 1] == '\n') { - ++new_len; + if (msg_len > 0) { + for (size_t i = 0; i < msg_len - 1; ++i) { + if (message[i] == '\r' && message[i + 1] == '\n') { + ++new_len; + } } - } - if (new_len == 0) { - fprintf(sendmail, "%s", message); - } else { - converted_message = emalloc(msg_len - new_len + 1); - size_t j = 0; - for (size_t i = 0; i < msg_len; ++i) { - if (i < msg_len - 1 && message[i] == '\r' && message[i + 1] == '\n') { - converted_message[j++] = '\n'; - ++i; /* skip LF part */ - } else { - converted_message[j++] = message[i]; + if (new_len == 0) { + fprintf(sendmail, "%s", message); + } else { + converted_message = emalloc(msg_len - new_len + 1); + size_t j = 0; + for (size_t i = 0; i < msg_len; ++i) { + if (i < msg_len - 1 && message[i] == '\r' && message[i + 1] == '\n') { + converted_message[j++] = '\n'; + ++i; /* skip LF part */ + } else { + converted_message[j++] = message[i]; + } } - } - converted_message[j] = '\0'; - fprintf(sendmail, "%s", converted_message); - efree(converted_message); + converted_message[j] = '\0'; + fprintf(sendmail, "%s", converted_message); + efree(converted_message); + } } } else { fprintf(sendmail, "%s", message); } - + fprintf(sendmail, "%s", line_sep); #ifdef PHP_WIN32 ret = pclose(sendmail); diff --git a/ext/standard/tests/mail/gh20257.phpt b/ext/standard/tests/mail/gh20257.phpt new file mode 100644 index 0000000000000..68374173413fc --- /dev/null +++ b/ext/standard/tests/mail/gh20257.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-20257: heap overflow with empty message and mail.cr_lf_mode=lf set +--INI-- +sendmail_path="exit 1" +mail.cr_lf_mode=lf +--CREDITS-- +YuanchengJiang +--FILE-- + +--EXPECTF-- + +Warning: mail(): Sendmail exited with non-zero exit code 1 in %s on line %d +bool(false)