summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2021-03-01 18:50:58 +0100
committerChristoph M. Becker <cmbecker69@gmx.de>2021-03-01 18:50:58 +0100
commit87a5a0e2cb7bec3d308c2e5f879d4e729297dfb3 (patch)
treebf3a81fd6d44c0196d3a9be541ff1b018aba049d /win32
parent1cb823c82eaf48c62ceab14e8ad01edee1cbe745 (diff)
parent37c9728615818efe73df8f11710099ea88739da5 (diff)
downloadphp-git-87a5a0e2cb7bec3d308c2e5f879d4e729297dfb3.tar.gz
Merge branch 'PHP-8.0'
* PHP-8.0: Fix #80751: Comma in recipient name breaks email delivery
Diffstat (limited to 'win32')
-rw-r--r--win32/sendmail.c102
1 files changed, 86 insertions, 16 deletions
diff --git a/win32/sendmail.c b/win32/sendmail.c
index a3d4eac353..83b2b97112 100644
--- a/win32/sendmail.c
+++ b/win32/sendmail.c
@@ -333,6 +333,37 @@ PHPAPI char *GetSMErrorText(int index)
}
}
+/* strtok_r like, but recognizes quoted-strings */
+static char *find_address(char *list, char **state)
+{
+ zend_bool in_quotes = 0;
+ char *p = list;
+
+ if (list == NULL) {
+ if (*state == NULL) {
+ return NULL;
+ }
+ p = list = *state;
+ }
+ *state = NULL;
+ while ((p = strpbrk(p, ",\"\\")) != NULL) {
+ if (*p == '\\' && in_quotes) {
+ if (p[1] == '\0') {
+ /* invalid address; let SMTP server deal with it */
+ break;
+ }
+ p++;
+ } else if (*p == '"') {
+ in_quotes = !in_quotes;
+ } else if (*p == ',' && !in_quotes) {
+ *p = '\0';
+ *state = p + 1;
+ break;
+ }
+ p++;
+ }
+ return list;
+}
/*********************************************************************
// Name: SendText
@@ -357,7 +388,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
{
int res;
char *p;
- char *tempMailTo, *token;
+ char *tempMailTo, *token, *token_state;
const char *pos1, *pos2;
char *server_response = NULL;
char *stripped_header = NULL;
@@ -411,7 +442,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
tempMailTo = estrdup(mailTo);
/* Send mail to all rcpt's */
- token = strtok(tempMailTo, ",");
+ token = find_address(tempMailTo, &token_state);
while (token != NULL)
{
SMTP_SKIP_SPACE(token);
@@ -425,14 +456,14 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
efree(tempMailTo);
return (res);
}
- token = strtok(NULL, ",");
+ token = find_address(NULL, &token_state);
}
efree(tempMailTo);
if (mailCc && *mailCc) {
tempMailTo = estrdup(mailCc);
/* Send mail to all rcpt's */
- token = strtok(tempMailTo, ",");
+ token = find_address(tempMailTo, &token_state);
while (token != NULL)
{
SMTP_SKIP_SPACE(token);
@@ -446,7 +477,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
efree(tempMailTo);
return (res);
}
- token = strtok(NULL, ",");
+ token = find_address(NULL, &token_state);
}
efree(tempMailTo);
}
@@ -472,7 +503,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
tempMailTo = estrndup(pos1, pos2 - pos1);
}
- token = strtok(tempMailTo, ",");
+ token = find_address(tempMailTo, &token_state);
while (token != NULL)
{
SMTP_SKIP_SPACE(token);
@@ -486,7 +517,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
efree(tempMailTo);
return (res);
}
- token = strtok(NULL, ",");
+ token = find_address(NULL,&token_state);
}
efree(tempMailTo);
}
@@ -497,7 +528,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
if (mailBcc && *mailBcc) {
tempMailTo = estrdup(mailBcc);
/* Send mail to all rcpt's */
- token = strtok(tempMailTo, ",");
+ token = find_address(tempMailTo, &token_state);
while (token != NULL)
{
SMTP_SKIP_SPACE(token);
@@ -511,7 +542,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
efree(tempMailTo);
return (res);
}
- token = strtok(NULL, ",");
+ token = find_address(NULL, &token_state);
}
efree(tempMailTo);
}
@@ -545,7 +576,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
}
}
- token = strtok(tempMailTo, ",");
+ token = find_address(tempMailTo, &token_state);
while (token != NULL)
{
SMTP_SKIP_SPACE(token);
@@ -559,7 +590,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
efree(tempMailTo);
return (res);
}
- token = strtok(NULL, ",");
+ token = find_address(NULL, &token_state);
}
efree(tempMailTo);
@@ -979,6 +1010,46 @@ static unsigned long GetAddr(LPSTR szHost)
return (lAddr);
} /* end GetAddr() */
+/* returns the contents of an angle-addr (caller needs to efree) or NULL */
+static char *get_angle_addr(char *address)
+{
+ zend_bool in_quotes = 0;
+ char *p1 = address, *p2;
+
+ while ((p1 = strpbrk(p1, "<\"\\")) != NULL) {
+ if (*p1 == '\\' && in_quotes) {
+ if (p1[1] == '\0') {
+ /* invalid address; let SMTP server deal with it */
+ return NULL;
+ }
+ p1++;
+ } else if (*p1 == '"') {
+ in_quotes = !in_quotes;
+ } else if (*p1 == '<' && !in_quotes) {
+ break;
+ }
+ p1++;
+ }
+ if (p1 == NULL) return NULL;
+ p2 = ++p1;
+ while ((p2 = strpbrk(p2, ">\"\\")) != NULL) {
+ if (*p2 == '\\' && in_quotes) {
+ if (p2[1] == '\0') {
+ /* invalid address; let SMTP server deal with it */
+ return NULL;
+ }
+ p2++;
+ } else if (*p2 == '"') {
+ in_quotes = !in_quotes;
+ } else if (*p2 == '>' && !in_quotes) {
+ break;
+ }
+ p2++;
+ }
+ if (p2 == NULL) return NULL;
+
+ return estrndup(p1, p2 - p1);
+}
/*********************************************************************
// Name: int FormatEmailAddress
@@ -994,13 +1065,12 @@ static unsigned long GetAddr(LPSTR szHost)
// History:
//********************************************************************/
static int FormatEmailAddress(char* Buf, char* EmailAddress, char* FormatString) {
- char *tmpAddress1, *tmpAddress2;
+ char *tmpAddress;
int result;
- if( (tmpAddress1 = strchr(EmailAddress, '<')) && (tmpAddress2 = strchr(tmpAddress1, '>')) ) {
- *tmpAddress2 = 0; // terminate the string temporarily.
- result = snprintf(Buf, MAIL_BUFFER_SIZE, FormatString , tmpAddress1+1);
- *tmpAddress2 = '>'; // put it back the way it was.
+ if ((tmpAddress = get_angle_addr(EmailAddress)) != NULL) {
+ result = snprintf(Buf, MAIL_BUFFER_SIZE, FormatString, tmpAddress);
+ efree(tmpAddress);
return result;
}
return snprintf(Buf, MAIL_BUFFER_SIZE , FormatString , EmailAddress );