jani Tue Nov 6 17:58:41 2007 UTC Modified files: /php-src/ext/standard mail.c Log: Ws + cs + missing fix for MOPB-33-2007:PHP mail() Message ASCIIZ Byte Truncation http://cvs.php.net/viewvc.cgi/php-src/ext/standard/mail.c?r1=1.94&r2=1.95&diff_format=u Index: php-src/ext/standard/mail.c diff -u php-src/ext/standard/mail.c:1.94 php-src/ext/standard/mail.c:1.95 --- php-src/ext/standard/mail.c:1.94 Wed Jul 11 17:39:04 2007 +++ php-src/ext/standard/mail.c Tue Nov 6 17:58:41 2007 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mail.c,v 1.94 2007/07/11 17:39:04 johannes Exp $ */ +/* $Id: mail.c,v 1.95 2007/11/06 17:58:41 jani Exp $ */ #include <stdlib.h> #include <ctype.h> @@ -44,14 +44,21 @@ #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ #endif -#define SKIP_LONG_HEADER_SEP(str, pos) \ +#define SKIP_LONG_HEADER_SEP(str, pos) \ if (str[pos] == '\r' && str[pos + 1] == '\n' && (str[pos + 2] == ' ' || str[pos + 2] == '\t')) { \ - pos += 2; \ - while (str[pos + 1] == ' ' || str[pos + 1] == '\t') { \ - pos++; \ - } \ - continue; \ - } \ + pos += 2; \ + while (str[pos + 1] == ' ' || str[pos + 1] == '\t') { \ + pos++; \ + } \ + continue; \ + } \ + +#define MAIL_ASCIIZ_CHECK(str, len) \ + p = str; \ + e = p + len; \ + while ((p = memchr(p, '\0', (e - p)))) { \ + *p = ' '; \ + } \ /* {{{ proto int ezmlm_hash(string addr) U Calculate EZMLM list hash value. */ @@ -60,7 +67,7 @@ char *str = NULL; unsigned long h = 5381L; int j, str_len; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &str, &str_len, UG(ascii_conv)) == FAILURE) { return; } @@ -68,9 +75,9 @@ for (j = 0; j < str_len; j++) { h = (h + (h << 5)) ^ (unsigned long) (unsigned char) tolower(str[j]); } - + h = (h % 53); - + RETURN_LONG((int) h); } /* }}} */ @@ -86,16 +93,23 @@ char *force_extra_parameters = INI_STR("mail.force_extra_parameters"); char *to_r, *subject_r; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss", - &to, &to_len, - &subject, &subject_len, - &message, &message_len, - &headers, &headers_len, - &extra_cmd, &extra_cmd_len - ) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ss", &to, &to_len, &subject, &subject_len, &message, &message_len, + &headers, &headers_len, &extra_cmd, &extra_cmd_len) == FAILURE + ) { return; } + /* ASCIIZ check */ + MAIL_ASCIIZ_CHECK(to, to_len); + MAIL_ASCIIZ_CHECK(subject, subject_len); + MAIL_ASCIIZ_CHECK(message, message_len); + if (headers) { + MAIL_ASCIIZ_CHECK(headers, headers_len); + } + if (extra_cmd) { + MAIL_ASCIIZ_CHECK(extra_cmd, extra_cmd_len); + } + if (to_len > 0) { to_r = estrndup(to, to_len); for (; to_len; to_len--) { @@ -109,15 +123,14 @@ /* 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 to skip over them. - */ + * SKIP_LONG_HEADER_SEP to skip over them. */ SKIP_LONG_HEADER_SEP(to_r, i); to_r[i] = ' '; } } } else { to_r = to; - } + } if (subject_len > 0) { subject_r = estrndup(subject, subject_len); @@ -127,7 +140,7 @@ } subject_r[subject_len - 1] = '\0'; } - for(i = 0; subject_r[i]; i++) { + for (i = 0; subject_r[i]; i++) { if (iscntrl((unsigned char) subject_r[i])) { SKIP_LONG_HEADER_SEP(subject_r, i); subject_r[i] = ' '; @@ -142,7 +155,7 @@ } else if (extra_cmd) { extra_cmd = php_escape_shell_cmd(extra_cmd); } - + if (php_mail(to_r, subject_r, message, headers, extra_cmd TSRMLS_CC)) { RETVAL_TRUE; } else { @@ -192,10 +205,7 @@ #endif } if (extra_cmd != NULL) { - sendmail_cmd = emalloc (strlen (sendmail_path) + strlen (extra_cmd) + 2); - strcpy (sendmail_cmd, sendmail_path); - strcat (sendmail_cmd, " "); - strcat (sendmail_cmd, extra_cmd); + spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, extra_cmd); } else { sendmail_cmd = sendmail_path; } @@ -209,8 +219,9 @@ errno = 0; sendmail = popen(sendmail_cmd, "w"); #endif - if (extra_cmd != NULL) + if (extra_cmd != NULL) { efree (sendmail_cmd); + } if (sendmail) { #ifndef PHP_WIN32 @@ -227,6 +238,7 @@ } fprintf(sendmail, "\n%s\n", message); ret = pclose(sendmail); + #ifdef PHP_WIN32 if (ret == -1) #else
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php