[asterisk-dev] [svn-commits] tilghman: branch 1.4 r148916 - /branches/1.4/apps/app_voicemail.c

Johansson Olle E oej at edvina.net
Wed Oct 15 02:53:30 CDT 2008


Please check app_minivm too.

Thanks,
/O
14 okt 2008 kl. 19.41 skrev SVN commits to the Digium repositories:

> Author: tilghman
> Date: Tue Oct 14 12:41:08 2008
> New Revision: 148916
>
> URL: http://svn.digium.com/view/asterisk?view=rev&rev=148916
> Log:
> Ensure that mail headers are 7-bit clean, even when UTF-8 characters  
> are used
> in headers like 'Subject' and 'To'.
> Closes AST-107.
>
> Modified:
>    branches/1.4/apps/app_voicemail.c
>
> Modified: branches/1.4/apps/app_voicemail.c
> URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_voicemail.c?view=diff&rev=148916&r1=148915&r2=148916
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- branches/1.4/apps/app_voicemail.c (original)
> +++ branches/1.4/apps/app_voicemail.c Tue Oct 14 12:41:08 2008
> @@ -2979,6 +2979,70 @@
> 	return tm;
> }
>
> +/*!\brief Check if the string would need encoding within the MIME  
> standard, to
> + * avoid confusing certain mail software that expects messages to  
> be 7-bit
> + * clean.
> + */
> +static int check_mime(const char *str)
> +{
> +	for (; *str; str++) {
> +		if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
> +			return 1;
> +		}
> +	}
> +	return 0;
> +}
> +
> +/*!\brief Encode a string according to the MIME rules for encoding  
> strings
> + * that are not 7-bit clean or contain control characters.
> + *
> + * Additionally, if the encoded string would exceed the MIME limit  
> of 76
> + * characters per line, then the encoding will be broken up into  
> multiple
> + * sections, separated by a space character, in order to facilitate
> + * breaking up the associated header across multiple lines.
> + *
> + * \param start A string to be encoded
> + * \param end An expandable buffer for holding the result
> + * \param preamble The length of the first line already used for  
> this string,
> + * to ensure that each line maintains a maximum length of 76 chars.
> + * \param postamble the length of any additional characters  
> appended to the
> + * line, used to ensure proper field wrapping.
> + * \retval The encoded string.
> + */
> +static char *encode_mime_str(const char *start, char *end, size_t  
> endsize, size_t preamble, size_t postamble)
> +{
> +	char tmp[80];
> +	int first_section = 1;
> +	size_t endlen = 0, tmplen = 0;
> +	*end = '\0';
> +
> +	tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
> +	for (; *start; start++) {
> +		int need_encoding = 0;
> +		if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_",  
> *start)) {
> +			need_encoding = 1;
> +		}
> +		if ((first_section && need_encoding && preamble + tmplen > 70) ||
> +			(first_section && !need_encoding && preamble + tmplen > 72) ||
> +			(!first_section && need_encoding && tmplen > 70) ||
> +			(!first_section && !need_encoding && tmplen > 72)) {
> +			/* Start new line */
> +			endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=",  
> first_section ? "" : " ", tmp);
> +			tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
> +			first_section = 0;
> +		}
> +		if (need_encoding && *start == ' ') {
> +			tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_");
> +		} else if (need_encoding) {
> +			tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX",  
> *start);
> +		} else {
> +			tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c",  
> *start);
> +		}
> +	}
> +	snprintf(end + endlen, endsize - endlen, "%s%s?=%s",  
> first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : "");
> +	return end;
> +}
> +
> static void make_email_file(FILE *p, char *srcemail, struct  
> ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char  
> *cidnum, char *cidname, char *attach, char *format, int duration,  
> int attach_user_voicemail, struct ast_channel *chan, const char  
> *category, int imap)
> {
> 	char date[256];
> @@ -2990,14 +3054,28 @@
> 	char tmpcmd[256];
> 	char enc_cidnum[256] = "", enc_cidname[256] = "";
> 	struct tm tm;
> -	char *passdata2;
> -	size_t len_passdata;
> +	char *passdata = NULL, *passdata2;
> +	size_t len_passdata, len_passdata2, tmplen;
> #ifdef IMAP_STORAGE
> #define ENDL "\r\n"
> #else
> #define ENDL "\n"
> #endif
>
> +	/* One alloca for multiple fields */
> +	len_passdata2 = strlen(vmu->fullname);
> +	if (emailsubject && (tmplen = strlen(emailsubject)) >  
> len_passdata2) {
> +		len_passdata2 = tmplen;
> +	}
> +	if ((tmplen = strlen(emailtitle)) > len_passdata2) {
> +		len_passdata2 = tmplen;
> +	}
> +	if ((tmplen = strlen(fromstring)) > len_passdata2) {
> +		len_passdata2 = tmplen;
> +	}
> +	len_passdata2 = len_passdata2 * 3 + 200;
> +	passdata2 = alloca(len_passdata2);
> +
> 	if (cidnum) {
> 		strip_control(cidnum, enc_cidnum, sizeof(enc_cidnum));
> 	}
> @@ -3020,37 +3098,71 @@
> 	if (*fromstring) {
> 		struct ast_channel *ast;
> 		if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "",  
> 0, 0))) {
> -			char *passdata;
> -			int vmlen = strlen(fromstring)*3 + 200;
> -			if ((passdata = alloca(vmlen))) {
> -				memset(passdata, 0, vmlen);
> -				prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox,  
> enc_cidnum, enc_cidname, dur, date, passdata, vmlen, category);
> -				pbx_substitute_variables_helper(ast, fromstring, passdata,  
> vmlen);
> -				len_passdata = strlen(passdata) * 2 + 3;
> -				passdata2 = alloca(len_passdata);
> -				fprintf(p, "From: %s <%s>" ENDL, quote(passdata, passdata2,  
> len_passdata), who);
> -			} else
> -				ast_log(LOG_WARNING, "Cannot allocate workspace for variable  
> substitution\n");
> +			char *ptr;
> +			memset(passdata2, 0, len_passdata2);
> +			prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox,  
> enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2,  
> category);
> +			pbx_substitute_variables_helper(ast, fromstring, passdata2,  
> len_passdata2);
> +			len_passdata = strlen(passdata2) * 3 + 300;
> +			passdata = alloca(len_passdata);
> +			if (check_mime(passdata2)) {
> +				int first_line = 1;
> +				encode_mime_str(passdata2, passdata, len_passdata,  
> strlen("From: "), strlen(who) + 3);
> +				while ((ptr = strchr(passdata, ' '))) {
> +					*ptr = '\0';
> +					fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", passdata);
> +					first_line = 0;
> +					passdata = ptr + 1;
> +				}
> +				fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "",  
> passdata, who);
> +			} else {
> +				fprintf(p, "From: %s <%s>" ENDL, quote(passdata, passdata2,  
> len_passdata2), who);
> +			}
> 			ast_channel_free(ast);
> 		} else
> 			ast_log(LOG_WARNING, "Cannot allocate the channel for variables  
> substitution\n");
> 	} else
> 		fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
> -	len_passdata = strlen(vmu->fullname) * 2 + 3;
> -	passdata2 = alloca(len_passdata);
> -	fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2,  
> len_passdata), vmu->email);
> +
> +	if (check_mime(vmu->fullname)) {
> +		int first_line = 1;
> +		char *ptr;
> +		encode_mime_str(vmu->fullname, passdata2, len_passdata2,  
> strlen("To: "), strlen(vmu->email) + 3);
> +		while ((ptr = strchr(passdata2, ' '))) {
> +			*ptr = '\0';
> +			fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", passdata2);
> +			first_line = 0;
> +			passdata2 = ptr + 1;
> +		}
> +		fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", passdata2,  
> vmu->email);
> +	} else {
> +		fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2,  
> len_passdata2), vmu->email);
> +	}
> 	if (emailsubject) {
> 		struct ast_channel *ast;
> 		if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "",  
> 0, 0))) {
> -			char *passdata;
> -			int vmlen = strlen(emailsubject)*3 + 200;
> -			if ((passdata = alloca(vmlen))) {
> -				memset(passdata, 0, vmlen);
> -				prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox,  
> cidnum, cidname, dur, date, passdata, vmlen, category);
> -				pbx_substitute_variables_helper(ast, emailsubject, passdata,  
> vmlen);
> +			int vmlen = strlen(emailsubject) * 3 + 200;
> +			/* Only allocate more space if the previous was not large enough  
> */
> +			if (vmlen > len_passdata) {
> +				passdata = alloca(vmlen);
> +				len_passdata = vmlen;
> +			}
> +
> +			memset(passdata, 0, len_passdata);
> +			prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox,  
> cidnum, cidname, dur, date, passdata, len_passdata, category);
> +			pbx_substitute_variables_helper(ast, emailsubject, passdata,  
> len_passdata);
> +			if (check_mime(passdata)) {
> +				int first_line = 1;
> +				char *ptr;
> +				encode_mime_str(passdata, passdata2, len_passdata2,  
> strlen("Subject: "), 0);
> +				while ((ptr = strchr(passdata2, ' '))) {
> +					*ptr = '\0';
> +					fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "",  
> passdata2);
> +					first_line = 0;
> +					passdata2 = ptr + 1;
> +				}
> +				fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "",  
> passdata2);
> +			} else {
> 				fprintf(p, "Subject: %s" ENDL, passdata);
> -			} else {
> -				ast_log(LOG_WARNING, "Cannot allocate workspace for variable  
> substitution\n");
> 			}
> 			ast_channel_free(ast);
> 		} else {
>
>
> _______________________________________________
> --Bandwidth and Colocation Provided by http://www.api-digital.com--
>
> svn-commits mailing list
> To UNSUBSCRIBE or update options visit:
>   http://lists.digium.com/mailman/listinfo/svn-commits

---
* Olle E Johansson - oej at edvina.net
* Cell phone +46 70 593 68 51, Office +46 8 96 40 20, Sweden






More information about the asterisk-dev mailing list