Re: imap_mail_compose(): suggested bugfixes and improvements. Patch included
| From: | Andi Gutmans | Date: | Mon, 30 Apr 2001 04:25:23 +0000 |
| Subject: | Re: imap_mail_compose(): suggested bugfixes and improvements. Patch included | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-53022@lists.php.net to get a copy of this message | ||
Please also address the maintainers (written on the top of the .c file) to make sure this gets the right attention.
Andi
At 01:24 AM 4/30/2001 +0200, Johan Ekenberg wrote:
Hi! I've been working a lot with the imap_*() functions in PHP lately, and have discovered a few shortcomings in the imap_mail_compose() function. Attached is a suggested patch against current CVS (2001-04-29), ext/imap/php_imap.c. Feel free to comment on this. I'm hoping that, after you've reviewed the changes, someone can commit it to CVS. Here is a brief description of the suggested changes: ----------------------------------------------------- 1) The documentation mentions $part["description"] as a valid body-part property, but it was not included in the code and was therefore silently ignored by PHP. It's added in the patch. 2) Added body-part property: $part["disposition.type"]. I guess the most obvious use is:$part["disposition.type"] = "attachment";3) Added body-part property $part["disposition"] which takes an associative array of attributes and values:$part["disposition"]["filename"] = "php.ini"; $part["disposition"]["foobar"] = "any value";renders this header:Content-Disposition: filename="php.ini"; foobar="any value"4) Added envelope property $envelope["custom_headers"] which takes an array of additional headers to be added to the envelope header:$envelope["custom_headers"][] = "Errors-To: foo@bar.com"; $envelope["custom_headers"][] = "Importance: Normal"; $envelope["custom_headers"][] = "X-Mailer: Foobar Mime-Mailer 1.0";adds these three custom header lines to the other mail envelopeheaders, after the standard rfc822 header lines. The custom headers end up in reverse order, ie. the "X-Mailer" line above would be added first and "Errors-To" last. I don't know if this ever matters (?), but if so it shouldn't be that difficult to fix. 5) There were a few formatting issues. Missing CRLF (\015\012) in some cases screwed up placement of MIME-Boundaries and such. The patch attempts to fix this. 6) A few "off-by-one" errors were fixed. These did not always cause errors, but on some occasions they produced segfaults. Best regards, /Johan Ekenberg The patch: (also attached as a separate file) -------------------------------------------------------- php_imap.c.orig Sun Apr 29 23:53:43 2001+++ php_imap.c Mon Apr 30 00:23:29 2001 @@ -52,7 +52,7 @@ MAILSTREAM DEFAULTPROTO; #endif - +#define CRLF "\015\012" #define PHP_EXPUNGE 32768 static void _php_make_header_object(zval *myzvalue, ENVELOPE *en); @@ -3154,14 +3154,14 @@ {zval **envelope, **body; char *key; - zval **data, **pvalue; + zval **data, **pvalue, **disp_data, **env_data; ulong ind; char *cookie = NIL; ENVELOPE *env; BODY *bod=NULL, *topbod=NULL; PART *mypart=NULL, *toppart=NULL, *part; - PARAMETER *param; - char tmp[8*MAILTMPLEN], *mystring=NULL, *t, *tempstring; + PARAMETER *param, *disp_param = NULL, *custom_headers_param = NULL,*tmp_param = NULL;+ char tmp[8 * MAILTMPLEN], *mystring=NULL, *t=NULL, *tempstring=NULL,*tempstring_2=NULL;int myargc = ZEND_NUM_ARGS();if (myargc != 2 || zend_get_parameters_ex(myargc, &envelope, &body) ==FAILURE) { @@ -3220,6 +3220,21 @@env->message_id=cpystr(Z_STRVAL_PP(pvalue)); }+ if (zend_hash_find(Z_ARRVAL_PP(envelope), "custom_headers",sizeof("custom_headers"), (void **) &pvalue)== SUCCESS) {+ if (Z_TYPE_PP(pvalue) == IS_ARRAY) { + custom_headers_param = tmp_param = NULL; + while(zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **)&env_data) == SUCCESS) {+ custom_headers_param = mail_newbody_parameter(); + convert_to_string_ex(env_data); + custom_headers_param->value = (char *) fs_get(Z_STRLEN_PP(env_data) +1);+ memcpy(custom_headers_param->value, Z_STRVAL_PP(env_data),Z_STRLEN_PP(env_data)+1);+ zend_hash_move_forward(Z_ARRVAL_PP(pvalue)); + custom_headers_param->next = tmp_param; + tmp_param = custom_headers_param; + } + } + }+zend_hash_internal_pointer_reset(Z_ARRVAL_PP(body)); zend_hash_get_current_data(Z_ARRVAL_PP(body), (void **) &data); zend_hash_get_current_key(Z_ARRVAL_PP(body), &key, &ind, 0); /* FIXME: isthis necessary? we're not using key/ind */ @@ -3244,9 +3259,35 @@convert_to_string_ex(pvalue); bod->id = cpystr(Z_STRVAL_PP(pvalue)); } + if (zend_hash_find(Z_ARRVAL_PP(data), "description",sizeof("description"), (void **) &pvalue)== SUCCESS) {+ convert_to_string_ex(pvalue); + bod->description = cpystr(Z_STRVAL_PP(pvalue)); + } + if (zend_hash_find(Z_ARRVAL_PP(data), "disposition.type",sizeof("disposition.type"), (void **) &pvalue)== SUCCESS) {+ convert_to_string_ex(pvalue); + bod->disposition.type = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1); + memcpy(bod->disposition.type, Z_STRVAL_PP(pvalue),Z_STRLEN_PP(pvalue)+1);+ } + if (zend_hash_find(Z_ARRVAL_PP(data), "disposition",sizeof("disposition"), (void **) &pvalue)== SUCCESS) {+ if (Z_TYPE_PP(pvalue) == IS_ARRAY) { + disp_param = tmp_param = NULL; + while(zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **)&disp_data) == SUCCESS) {+ disp_param = mail_newbody_parameter(); + zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0); + disp_param->attribute = key; + convert_to_string_ex(disp_data); + disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1); + memcpy(disp_param->value, Z_STRVAL_PP(disp_data),Z_STRLEN_PP(disp_data)+1); + zend_hash_move_forward(Z_ARRVAL_PP(pvalue));+ disp_param->next = tmp_param; + tmp_param = disp_param; + } + bod->disposition.parameter = disp_param; + } + } if (zend_hash_find(Z_ARRVAL_PP(data), "contents.data",sizeof("contents.data"), (void **) &pvalue)== SUCCESS) {convert_to_string_ex(pvalue); - bod->contents.text.data = (char *) fs_get(Z_STRLEN_PP(pvalue)); + bod->contents.text.data = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1); memcpy(bod->contents.text.data, Z_STRVAL_PP(pvalue),Z_STRLEN_PP(pvalue)+1);bod->contents.text.size = Z_STRLEN_PP(pvalue); }@@ -3296,9 +3337,35 @@convert_to_string_ex(pvalue); bod->id = cpystr(Z_STRVAL_PP(pvalue)); } + if (zend_hash_find(Z_ARRVAL_PP(data), "description",sizeof("description"), (void **) &pvalue)== SUCCESS) {+ convert_to_string_ex(pvalue); + bod->description = cpystr(Z_STRVAL_PP(pvalue)); + } + if (zend_hash_find(Z_ARRVAL_PP(data), "disposition.type",sizeof("disposition.type"), (void **) &pvalue)== SUCCESS) {+ convert_to_string_ex(pvalue); + bod->disposition.type = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1); + memcpy(bod->disposition.type, Z_STRVAL_PP(pvalue),Z_STRLEN_PP(pvalue)+1);+ } + if (zend_hash_find(Z_ARRVAL_PP(data), "disposition",sizeof("disposition"), (void **) &pvalue)== SUCCESS) {+ if (Z_TYPE_PP(pvalue) == IS_ARRAY) { + disp_param = tmp_param = NULL; + while(zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **)&disp_data) == SUCCESS) {+ disp_param = mail_newbody_parameter(); + zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0); + disp_param->attribute = key; + convert_to_string_ex(disp_data); + disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1); + memcpy(disp_param->value, Z_STRVAL_PP(disp_data),Z_STRLEN_PP(disp_data)+1); + zend_hash_move_forward(Z_ARRVAL_PP(pvalue));+ disp_param->next = tmp_param; + tmp_param = disp_param; + } + bod->disposition.parameter = disp_param; + } + } if (zend_hash_find(Z_ARRVAL_PP(data), "contents.data",sizeof("contents.data"), (void **) &pvalue)== SUCCESS) {convert_to_string_ex(pvalue); - bod->contents.text.data = (char *) fs_get(Z_STRLEN_PP(pvalue)); + bod->contents.text.data = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1); memcpy(bod->contents.text.data, Z_STRVAL_PP(pvalue),Z_STRLEN_PP(pvalue)+1);bod->contents.text.size = Z_STRLEN_PP(pvalue); }@@ -3320,9 +3387,32 @@}rfc822_encode_body_7bit(env, topbod); - rfc822_header (tmp, env, topbod); - mystring=emalloc(strlen(tmp)+1); - strcpy(mystring, tmp); + rfc822_header (tmp, env, topbod);++ /* add custom envelope headers */ + if (custom_headers_param) { + /* remove last CRLF from tmp */ + tmp[strlen(tmp) - 2] = '\0'; + tempstring = emalloc(strlen(tmp) + 1); + strcpy(tempstring, tmp); + do { + tempstring_2 = emalloc(strlen(tempstring) +strlen(custom_headers_param->value) + strlen(CRLF) + 1);+ sprintf(tempstring_2, "%s%s%s", tempstring, custom_headers_param->value,CRLF);+ efree(tempstring); + tempstring = emalloc(strlen(tempstring_2) + 1); + strcpy(tempstring, tempstring_2); + efree(tempstring_2); + } while ((custom_headers_param = custom_headers_param->next));++ mystring = emalloc(strlen(tempstring) + strlen(CRLF) + 1); + strcpy(mystring, tempstring); + strcat(mystring, CRLF); + efree(tempstring); + } + else { + mystring = emalloc(strlen(tmp) + 1); + strcpy(mystring, tmp); + }bod=topbod;@@ -3346,13 +3436,13 @@/* for each part */ do { /* build cookie */ - sprintf (t=tmp, "--%s\015\012", cookie); + sprintf (t=tmp, "--%s%s", cookie, CRLF);/* append mini-header */ rfc822_write_body_header(&t, &part->body);/* write terminating blank line */ - strcat (t, "\015\012"); + strcat (t, CRLF);/* output cookie, mini-header, and contents */tempstring=emalloc(strlen(mystring)+strlen(tmp)+1); @@ -3363,29 +3453,29 @@bod=&part->body;- tempstring=emalloc(strlen(bod->contents.text.data)+strlen(mystring)+1); + tempstring=emalloc(strlen(bod->contents.text.data)+strlen(CRLF)+strlen(mystr ing)+1);strcpy(tempstring,mystring); efree(mystring); mystring=tempstring; - strcat(mystring, bod->contents.text.data); + sprintf(mystring, "%s%s%s", mystring, bod->contents.text.data, CRLF);} while ((part = part->next));/* until done */ /* output trailing cookie */sprintf(tmp, "--%s--", cookie); - tempstring=emalloc(strlen(tmp)+strlen(mystring)+1); + tempstring=emalloc(strlen(tmp)+strlen(CRLF)+strlen(mystring)+1); strcpy(tempstring,mystring); efree(mystring); mystring=tempstring; - strcat(mystring,tmp); + sprintf(mystring, "%s%s%s", mystring, tmp, CRLF);} else if(bod) {- tempstring=emalloc(strlen(bod->contents.text.data)+strlen(mystring)+1); + tempstring=emalloc(strlen(bod->contents.text.data)+strlen(CRLF)+strlen(mystr ing)+1);strcpy(tempstring,mystring); efree(mystring); mystring=tempstring; - strcat(mystring, bod->contents.text.data); + sprintf(mystring, "%s%s%s", mystring, bod->contents.text.data, CRLF);} else { efree(mystring);-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, e-mail: php-dev-unsubscribe@lists.php.net For additional commands, e-mail: php-dev-help@lists.php.net To contact the list administrators, e-mail: php-list-admin@lists.php.net