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: [EMAIL PROTECTED]";
        $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 envelope
headers, 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: is
this 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_imap.patch

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to