diff options
author | Rui Hirokawa <hirokawa@php.net> | 2005-11-23 15:17:09 +0000 |
---|---|---|
committer | Rui Hirokawa <hirokawa@php.net> | 2005-11-23 15:17:09 +0000 |
commit | db1be3a1db1584029981c043986e09ad35d5e536 (patch) | |
tree | f0f53763c5d710c4aace7fbac4df62d03ffad9a9 | |
parent | 49ebc7f0469e0263fb6945f449f5d589d20b98d2 (diff) | |
download | php-git-db1be3a1db1584029981c043986e09ad35d5e536.tar.gz |
MFH: fixed 5307 unexpected header can be injected to mb_send_mail().
-rw-r--r-- | ext/mbstring/mbstring.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 95fb770129..d13ba6db76 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2771,6 +2771,15 @@ PHP_FUNCTION(mb_decode_numericentity) */ #if HAVE_SENDMAIL +#define SKIP_LONG_HEADER_SEP_MBSTRING(str, pos) \ + if (str[pos] == '\r' && str[pos + 1] == '\n' && (str[pos + 2] == ' ' || str[pos + 2] == '\t')) { \ + pos += 3; \ + while (str[pos] == ' ' || str[pos] == '\t') { \ + pos++; \ + } \ + continue; \ + } + #define APPEND_ONE_CHAR(ch) do { \ if (token.a > 0) { \ smart_str_appendc(&token, ch); \ @@ -2982,6 +2991,9 @@ PHP_FUNCTION(mb_send_mail) int subject_len; char *extra_cmd=NULL; int extra_cmd_len; + int i; + char *to_r; + char *force_extra_parameters = INI_STR("mail.force_extra_parameters"); struct { int cnt_type:1; int cnt_trans_enc:1; @@ -3087,7 +3099,30 @@ PHP_FUNCTION(mb_send_mail) } /* To: */ - if (to == NULL || to_len <= 0) { + if (to != NULL) { + if (to_len > 0) { + to_r = estrndup(to, to_len); + for (; to_len; to_len--) { + if (!isspace((unsigned char) to_r[to_len - 1])) { + break; + } + to_r[to_len - 1] = '\0'; + } + for (i = 0; to_r[i]; i++) { + if (iscntrl((unsigned char) to_r[i])) { + /* According to RFC 822, section 3.1.1 long headers may be separated into + * parts using CRLF followed at least one linear-white-space character ('\t' or ' '). + * To prevent these separators from being replaced with a space, we use the + * SKIP_LONG_HEADER_SEP_MBSTRING to skip over them. + */ + SKIP_LONG_HEADER_SEP_MBSTRING(to_r, i); + to_r[i] = ' '; + } + } + } else { + to_r = to; + } + } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing To: field"); err = 1; } @@ -3183,12 +3218,20 @@ PHP_FUNCTION(mb_send_mail) mbfl_memory_device_output('\0', &device); headers = (char *)device.buffer; - if (!err && php_mail(to, subject, message, headers, extra_cmd TSRMLS_CC)) { + if (force_extra_parameters) { + extra_cmd = estrdup(force_extra_parameters); + } else if (extra_cmd) { + extra_cmd = php_escape_shell_cmd(extra_cmd); + } + + if (!err && php_mail(to_r, subject, message, headers, extra_cmd TSRMLS_CC)) { RETVAL_TRUE; } else { RETVAL_FALSE; } - + if (to_r != to) { + efree(to_r); + } if (subject_buf) { efree((void *)subject_buf); } @@ -3199,6 +3242,7 @@ PHP_FUNCTION(mb_send_mail) zend_hash_destroy(&ht_headers); } +#undef SKIP_LONG_HEADER_SEP_MBSTRING #undef APPEND_ONE_CHAR #undef SEPARATE_SMART_STR #undef PHP_MBSTR_MAIL_MIME_HEADER1 |