@@ -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, const char *Subject, const char *mailTo, char *
357388{
358389 int res ;
359390 char * p ;
360- char * tempMailTo , * token ;
391+ char * tempMailTo , * token , * token_state ;
361392 const char * pos1 , * pos2 ;
362393 char * server_response = NULL ;
363394 char * stripped_header = NULL ;
@@ -411,7 +442,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
411442
412443 tempMailTo = estrdup (mailTo );
413444 /* Send mail to all rcpt's */
414- token = strtok (tempMailTo , "," );
445+ token = find_address (tempMailTo , & token_state );
415446 while (token != NULL )
416447 {
417448 SMTP_SKIP_SPACE (token );
@@ -425,14 +456,14 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
425456 efree (tempMailTo );
426457 return (res );
427458 }
428- token = strtok (NULL , "," );
459+ token = find_address (NULL , & token_state );
429460 }
430461 efree (tempMailTo );
431462
432463 if (mailCc && * mailCc ) {
433464 tempMailTo = estrdup (mailCc );
434465 /* Send mail to all rcpt's */
435- token = strtok (tempMailTo , "," );
466+ token = find_address (tempMailTo , & token_state );
436467 while (token != NULL )
437468 {
438469 SMTP_SKIP_SPACE (token );
@@ -446,7 +477,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
446477 efree (tempMailTo );
447478 return (res );
448479 }
449- token = strtok (NULL , "," );
480+ token = find_address (NULL , & token_state );
450481 }
451482 efree (tempMailTo );
452483 }
@@ -472,7 +503,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
472503 tempMailTo = estrndup (pos1 , pos2 - pos1 );
473504 }
474505
475- token = strtok (tempMailTo , "," );
506+ token = find_address (tempMailTo , & token_state );
476507 while (token != NULL )
477508 {
478509 SMTP_SKIP_SPACE (token );
@@ -486,7 +517,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
486517 efree (tempMailTo );
487518 return (res );
488519 }
489- token = strtok (NULL , "," );
520+ token = find_address (NULL ,& token_state );
490521 }
491522 efree (tempMailTo );
492523 }
@@ -497,7 +528,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
497528 if (mailBcc && * mailBcc ) {
498529 tempMailTo = estrdup (mailBcc );
499530 /* Send mail to all rcpt's */
500- token = strtok (tempMailTo , "," );
531+ token = find_address (tempMailTo , & token_state );
501532 while (token != NULL )
502533 {
503534 SMTP_SKIP_SPACE (token );
@@ -511,7 +542,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
511542 efree (tempMailTo );
512543 return (res );
513544 }
514- token = strtok (NULL , "," );
545+ token = find_address (NULL , & token_state );
515546 }
516547 efree (tempMailTo );
517548 }
@@ -545,7 +576,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
545576 }
546577 }
547578
548- token = strtok (tempMailTo , "," );
579+ token = find_address (tempMailTo , & token_state );
549580 while (token != NULL )
550581 {
551582 SMTP_SKIP_SPACE (token );
@@ -559,7 +590,7 @@ static int SendText(char *RPath, const char *Subject, const char *mailTo, char *
559590 efree (tempMailTo );
560591 return (res );
561592 }
562- token = strtok (NULL , "," );
593+ token = find_address (NULL , & token_state );
563594 }
564595 efree (tempMailTo );
565596
@@ -979,6 +1010,46 @@ static unsigned long GetAddr(LPSTR szHost)
9791010 return (lAddr );
9801011} /* end GetAddr() */
9811012
1013+ /* returns the contents of an angle-addr (caller needs to efree) or NULL */
1014+ static char * get_angle_addr (char * address )
1015+ {
1016+ zend_bool in_quotes = 0 ;
1017+ char * p1 = address , * p2 ;
1018+
1019+ while ((p1 = strpbrk (p1 , "<\"\\" )) != NULL ) {
1020+ if (* p1 == '\\' && in_quotes ) {
1021+ if (p1 [1 ] == '\0' ) {
1022+ /* invalid address; let SMTP server deal with it */
1023+ return NULL ;
1024+ }
1025+ p1 ++ ;
1026+ } else if (* p1 == '"' ) {
1027+ in_quotes = !in_quotes ;
1028+ } else if (* p1 == '<' && !in_quotes ) {
1029+ break ;
1030+ }
1031+ p1 ++ ;
1032+ }
1033+ if (p1 == NULL ) return NULL ;
1034+ p2 = ++ p1 ;
1035+ while ((p2 = strpbrk (p2 , ">\"\\" )) != NULL ) {
1036+ if (* p2 == '\\' && in_quotes ) {
1037+ if (p2 [1 ] == '\0' ) {
1038+ /* invalid address; let SMTP server deal with it */
1039+ return NULL ;
1040+ }
1041+ p2 ++ ;
1042+ } else if (* p2 == '"' ) {
1043+ in_quotes = !in_quotes ;
1044+ } else if (* p2 == '>' && !in_quotes ) {
1045+ break ;
1046+ }
1047+ p2 ++ ;
1048+ }
1049+ if (p2 == NULL ) return NULL ;
1050+
1051+ return estrndup (p1 , p2 - p1 );
1052+ }
9821053
9831054/*********************************************************************
9841055// Name: int FormatEmailAddress
@@ -994,13 +1065,12 @@ static unsigned long GetAddr(LPSTR szHost)
9941065// History:
9951066//********************************************************************/
9961067static int FormatEmailAddress (char * Buf , char * EmailAddress , char * FormatString ) {
997- char * tmpAddress1 , * tmpAddress2 ;
1068+ char * tmpAddress ;
9981069 int result ;
9991070
1000- if ( (tmpAddress1 = strchr (EmailAddress , '<' )) && (tmpAddress2 = strchr (tmpAddress1 , '>' )) ) {
1001- * tmpAddress2 = 0 ; // terminate the string temporarily.
1002- result = snprintf (Buf , MAIL_BUFFER_SIZE , FormatString , tmpAddress1 + 1 );
1003- * tmpAddress2 = '>' ; // put it back the way it was.
1071+ if ((tmpAddress = get_angle_addr (EmailAddress )) != NULL ) {
1072+ result = snprintf (Buf , MAIL_BUFFER_SIZE , FormatString , tmpAddress );
1073+ efree (tmpAddress );
10041074 return result ;
10051075 }
10061076 return snprintf (Buf , MAIL_BUFFER_SIZE , FormatString , EmailAddress );
0 commit comments