@@ -333,6 +333,37 @@ PHPAPI char *GetSMErrorText(int index)
333333 }
334334}
335335
336+ /* strtok_r like, but recognizes quoted-strings */
337+ static char * find_address (char * list , char * * state )
338+ {
339+ zend_bool in_quotes = 0 ;
340+ char * p = list ;
341+
342+ if (list == NULL ) {
343+ if (* state == NULL ) {
344+ return NULL ;
345+ }
346+ p = list = * state ;
347+ }
348+ * state = NULL ;
349+ while ((p = strpbrk (p , ",\"\\" )) != NULL ) {
350+ if (* p == '\\' && in_quotes ) {
351+ if (p [1 ] == '\0' ) {
352+ /* invalid address; let SMTP server deal with it */
353+ break ;
354+ }
355+ p ++ ;
356+ } else if (* p == '"' ) {
357+ in_quotes = !in_quotes ;
358+ } else if (* p == ',' && !in_quotes ) {
359+ * p = '\0' ;
360+ * state = p + 1 ;
361+ break ;
362+ }
363+ p ++ ;
364+ }
365+ return list ;
366+ }
336367
337368/*********************************************************************
338369// Name: SendText
@@ -357,7 +388,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
357388{
358389 int res ;
359390 char * p ;
360- char * tempMailTo , * token , * pos1 , * pos2 ;
391+ char * tempMailTo , * token , * token_state , * pos1 , * pos2 ;
361392 char * server_response = NULL ;
362393 char * stripped_header = NULL ;
363394 zend_string * data_cln ;
@@ -410,7 +441,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
410441
411442 tempMailTo = estrdup (mailTo );
412443 /* Send mail to all rcpt's */
413- token = strtok (tempMailTo , "," );
444+ token = find_address (tempMailTo , & token_state );
414445 while (token != NULL )
415446 {
416447 SMTP_SKIP_SPACE (token );
@@ -424,14 +455,14 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
424455 efree (tempMailTo );
425456 return (res );
426457 }
427- token = strtok (NULL , "," );
458+ token = find_address (NULL , & token_state );
428459 }
429460 efree (tempMailTo );
430461
431462 if (mailCc && * mailCc ) {
432463 tempMailTo = estrdup (mailCc );
433464 /* Send mail to all rcpt's */
434- token = strtok (tempMailTo , "," );
465+ token = find_address (tempMailTo , & token_state );
435466 while (token != NULL )
436467 {
437468 SMTP_SKIP_SPACE (token );
@@ -445,7 +476,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
445476 efree (tempMailTo );
446477 return (res );
447478 }
448- token = strtok (NULL , "," );
479+ token = find_address (NULL , & token_state );
449480 }
450481 efree (tempMailTo );
451482 }
@@ -471,7 +502,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
471502 tempMailTo = estrndup (pos1 , pos2 - pos1 );
472503 }
473504
474- token = strtok (tempMailTo , "," );
505+ token = find_address (tempMailTo , & token_state );
475506 while (token != NULL )
476507 {
477508 SMTP_SKIP_SPACE (token );
@@ -485,7 +516,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
485516 efree (tempMailTo );
486517 return (res );
487518 }
488- token = strtok (NULL , "," );
519+ token = find_address (NULL ,& token_state );
489520 }
490521 efree (tempMailTo );
491522 }
@@ -496,7 +527,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
496527 if (mailBcc && * mailBcc ) {
497528 tempMailTo = estrdup (mailBcc );
498529 /* Send mail to all rcpt's */
499- token = strtok (tempMailTo , "," );
530+ token = find_address (tempMailTo , & token_state );
500531 while (token != NULL )
501532 {
502533 SMTP_SKIP_SPACE (token );
@@ -510,7 +541,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
510541 efree (tempMailTo );
511542 return (res );
512543 }
513- token = strtok (NULL , "," );
544+ token = find_address (NULL , & token_state );
514545 }
515546 efree (tempMailTo );
516547 }
@@ -544,7 +575,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
544575 }
545576 }
546577
547- token = strtok (tempMailTo , "," );
578+ token = find_address (tempMailTo , & token_state );
548579 while (token != NULL )
549580 {
550581 SMTP_SKIP_SPACE (token );
@@ -558,7 +589,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char
558589 efree (tempMailTo );
559590 return (res );
560591 }
561- token = strtok (NULL , "," );
592+ token = find_address (NULL , & token_state );
562593 }
563594 efree (tempMailTo );
564595
@@ -978,6 +1009,46 @@ static unsigned long GetAddr(LPSTR szHost)
9781009 return (lAddr );
9791010} /* end GetAddr() */
9801011
1012+ /* returns the contents of an angle-addr (caller needs to efree) or NULL */
1013+ static char * get_angle_addr (char * address )
1014+ {
1015+ zend_bool in_quotes = 0 ;
1016+ char * p1 = address , * p2 ;
1017+
1018+ while ((p1 = strpbrk (p1 , "<\"\\" )) != NULL ) {
1019+ if (* p1 == '\\' && in_quotes ) {
1020+ if (p1 [1 ] == '\0' ) {
1021+ /* invalid address; let SMTP server deal with it */
1022+ return NULL ;
1023+ }
1024+ p1 ++ ;
1025+ } else if (* p1 == '"' ) {
1026+ in_quotes = !in_quotes ;
1027+ } else if (* p1 == '<' && !in_quotes ) {
1028+ break ;
1029+ }
1030+ p1 ++ ;
1031+ }
1032+ if (p1 == NULL ) return NULL ;
1033+ p2 = ++ p1 ;
1034+ while ((p2 = strpbrk (p2 , ">\"\\" )) != NULL ) {
1035+ if (* p2 == '\\' && in_quotes ) {
1036+ if (p2 [1 ] == '\0' ) {
1037+ /* invalid address; let SMTP server deal with it */
1038+ return NULL ;
1039+ }
1040+ p2 ++ ;
1041+ } else if (* p2 == '"' ) {
1042+ in_quotes = !in_quotes ;
1043+ } else if (* p2 == '>' && !in_quotes ) {
1044+ break ;
1045+ }
1046+ p2 ++ ;
1047+ }
1048+ if (p2 == NULL ) return NULL ;
1049+
1050+ return estrndup (p1 , p2 - p1 );
1051+ }
9811052
9821053/*********************************************************************
9831054// Name: int FormatEmailAddress
@@ -993,13 +1064,12 @@ static unsigned long GetAddr(LPSTR szHost)
9931064// History:
9941065//********************************************************************/
9951066static int FormatEmailAddress (char * Buf , char * EmailAddress , char * FormatString ) {
996- char * tmpAddress1 , * tmpAddress2 ;
1067+ char * tmpAddress ;
9971068 int result ;
9981069
999- if ( (tmpAddress1 = strchr (EmailAddress , '<' )) && (tmpAddress2 = strchr (tmpAddress1 , '>' )) ) {
1000- * tmpAddress2 = 0 ; // terminate the string temporarily.
1001- result = snprintf (Buf , MAIL_BUFFER_SIZE , FormatString , tmpAddress1 + 1 );
1002- * tmpAddress2 = '>' ; // put it back the way it was.
1070+ if ((tmpAddress = get_angle_addr (EmailAddress )) != NULL ) {
1071+ result = snprintf (Buf , MAIL_BUFFER_SIZE , FormatString , tmpAddress );
1072+ efree (tmpAddress );
10031073 return result ;
10041074 }
10051075 return snprintf (Buf , MAIL_BUFFER_SIZE , FormatString , EmailAddress );
0 commit comments