From: Thomas Roessler Date: Sat, 20 May 2000 15:46:39 +0000 (+0000) Subject: String conversion patch from EGE. X-Git-Tag: mutt-1-3-2-rel~14 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=92f926fc34d3cd2dfb5fae7ccb12905e4bc412ad;p=mutt String conversion patch from EGE. --- diff --git a/charset.c b/charset.c index 792229b2..62eac288 100644 --- a/charset.c +++ b/charset.c @@ -378,23 +378,24 @@ bail: /* - * Convert a string in place + * Convert a string * Used in rfc2047.c and rfc2231.c */ -int mutt_convert_string (char *s, size_t len, const char *from, const char *to) +int mutt_convert_string (char **ps, const char *from, const char *to) { iconv_t cd; const char *repls[] = { "\357\277\275", "?", 0 }; + char *s = *ps; if (!s || !*s) return 0; if (to && from && (cd = mutt_iconv_open (to, from)) != (iconv_t)-1) { - int n; + int len; const char *ib; - char *c, *ob; + char *buf, *ob; size_t ibl, obl; const char **inrepls = 0; char *outrepl = 0; @@ -406,14 +407,16 @@ int mutt_convert_string (char *s, size_t len, const char *from, const char *to) else outrepl = "?"; - n = strlen (s); - c = safe_malloc (n); - memcpy (c, s, n); - ib = c, ibl = n, ob = s, obl = len ? len-1 : n; + len = strlen (s); + ib = s, ibl = len + 1; + obl = MB_LEN_MAX * ibl; + ob = buf = safe_malloc (obl + 1); mutt_iconv (cd, &ib, &ibl, &ob, &obl, inrepls, outrepl); - free (c); iconv_close (cd); + free (s); *ob = '\0'; + *ps = safe_strdup (buf); + free (buf); return 0; } else diff --git a/charset.h b/charset.h index d76da234..fa808da9 100644 --- a/charset.h +++ b/charset.h @@ -55,7 +55,7 @@ int mutt_decoder_push_one (DECODER *, char); int mutt_recode_file (const char *, const char *, const char *); -int mutt_convert_string (char *, size_t, const char *, const char *); +int mutt_convert_string (char **, const char *, const char *); size_t mutt_iconv (iconv_t, const char **, size_t *, char **, size_t *, const char **, const char *); diff --git a/curs_lib.c b/curs_lib.c index de0f72e9..ac7dbc6a 100644 --- a/curs_lib.c +++ b/curs_lib.c @@ -467,7 +467,7 @@ int mutt_multi_choice (char *prompt, char *letters) int mutt_addwch (wchar_t wc) { - char buf[6]; /* FIXME */ + char buf[MB_LEN_MAX]; int n; n = wctomb (buf, wc); diff --git a/rfc2047.c b/rfc2047.c index c131b2a5..848da207 100644 --- a/rfc2047.c +++ b/rfc2047.c @@ -186,13 +186,8 @@ void rfc2047_encode_string (char *d, size_t dlen, const unsigned char *s) const unsigned char *p = s; encode_t *encoder; char send_charset[SHORT_STRING]; - unsigned char scratch[LONG_STRING]; - - /* attention: this function will fail for - * strings longer then LONG_STRING. But lots - * of code in mutt will anyway... - */ - + char *scratch; + mutt_get_send_charset(send_charset, sizeof(send_charset), NULL, 0); /* First check to see if there are any 8-bit characters */ @@ -242,11 +237,12 @@ void rfc2047_encode_string (char *d, size_t dlen, const unsigned char *s) s += 5; } - strfcpy((char *)scratch, (const char *) s, sizeof(scratch)); + scratch = safe_strdup ((const char *) s); if (*send_charset && mutt_strcasecmp("us-ascii", send_charset)) - mutt_convert_string ((char *)scratch, LONG_STRING, Charset, send_charset); + mutt_convert_string (&scratch, Charset, send_charset); - (*encoder) (d, dlen, scratch, send_charset); + (*encoder) (d, dlen, (unsigned char *) scratch, send_charset); + safe_free ((void **) &scratch); } void rfc2047_encode_adrlist (ADDRESS *addr) @@ -274,25 +270,27 @@ void rfc2047_encode_adrlist (ADDRESS *addr) static int rfc2047_decode_word (char *d, const char *s, size_t len) { - char *p = safe_strdup (s); - char *pp = p; - char *pd = d; - char *t; - int enc = 0, filter = 0, count = 0, c1, c2, c3, c4; + const char *pp = s, *pp1; + char *pd, *d0; + char *t, *t1; + int enc = 0, count = 0, c1, c2, c3, c4; char *charset = NULL; - size_t olen = len; - while ((pp = strtok (pp, "?")) != NULL) + pd = d0 = safe_malloc (strlen (s)); + + for (pp = s; (pp1 = strchr (pp, '?')); pp = pp1 + 1) { count++; switch (count) { case 2: /* ignore language specification a la RFC 2231 */ - if ((t = strchr (pp, '*'))) - *t = '\0'; - charset = pp; - filter = 1; + t = pp1; + if ((t1 = memchr (pp, '*', t - pp))) + t = t1; + charset = safe_malloc (t - pp + 1); + memcpy (charset, pp, t - pp); + charset[t-pp] = '\0'; break; case 3: if (toupper (*pp) == 'Q') @@ -300,12 +298,16 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) else if (toupper (*pp) == 'B') enc = ENCBASE64; else + { + safe_free ((void **) &charset); + safe_free ((void **) &d0); return (-1); + } break; case 4: if (enc == ENCQUOTEDPRINTABLE) { - while (*pp && len > 0) + while (pp < pp1 && len > 0) { if (*pp == '_') { @@ -331,7 +333,7 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) } else if (enc == ENCBASE64) { - while (*pp && len > 0) + while (pp < pp1 && len > 0) { if (pp[0] == '=' || pp[1] == 0 || pp[1] == '=') break; /* something wrong */ @@ -361,12 +363,13 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len) } break; } - pp = 0; } - if (filter) - mutt_convert_string (d, olen, charset, Charset); - safe_free ((void **) &p); + if (charset) + mutt_convert_string (&d0, charset, Charset); + strfcpy (d, d0, len); + safe_free ((void **) &charset); + safe_free ((void **) &d0); return (0); } diff --git a/rfc2231.c b/rfc2231.c index 61fc9b69..16ce828d 100644 --- a/rfc2231.c +++ b/rfc2231.c @@ -51,7 +51,7 @@ struct rfc2231_parameter static char *rfc2231_get_charset (char *, char *, size_t); static struct rfc2231_parameter *rfc2231_new_parameter (void); -static void rfc2231_decode_one (char *, char *, char *); +static void rfc2231_decode_one (char *, char *); static void rfc2231_free_parameter (struct rfc2231_parameter **); static void rfc2231_join_continuations (PARAMETER **, struct rfc2231_parameter *); static void rfc2231_list_insert (struct rfc2231_parameter **, struct rfc2231_parameter *); @@ -123,8 +123,9 @@ void rfc2231_decode_parameters (PARAMETER **headp) *s = '\0'; s = rfc2231_get_charset (p->value, charset, sizeof (charset)); - rfc2231_decode_one (p->value, s, charset); - + rfc2231_decode_one (p->value, s); + mutt_convert_string (&p->value, charset, Charset); + *last = p; last = &p->next; p->next = NULL; @@ -201,7 +202,7 @@ static char *rfc2231_get_charset (char *value, char *charset, size_t chslen) return t + 1; } -static void rfc2231_decode_one (char *dest, char *src, char *chs) +static void rfc2231_decode_one (char *dest, char *src) { char *d; @@ -217,9 +218,6 @@ static void rfc2231_decode_one (char *dest, char *src, char *chs) } *d = '\0'; - - if (chs && strcmp (chs, "us-ascii") && strcmp (chs, Charset)) - mutt_convert_string (dest, 0, chs, Charset); } /* insert parameter into an ordered list. @@ -278,7 +276,7 @@ static void rfc2231_join_continuations (PARAMETER **head, do { if (encoded && par->encoded) - rfc2231_decode_one (par->value, valp, charset); + rfc2231_decode_one (par->value, valp); vl = strlen (par->value); @@ -294,6 +292,8 @@ static void rfc2231_join_continuations (PARAMETER **head, if (value) { + if (encoded) + mutt_convert_string (&value, charset, Charset); *head = mutt_new_parameter (); (*head)->attribute = safe_strdup (attribute); (*head)->value = value; @@ -304,11 +304,13 @@ static void rfc2231_join_continuations (PARAMETER **head, int rfc2231_encode (char *dest, size_t l, unsigned char *src) { - char buff[LONG_STRING]; + char *buff; unsigned char *s; char *t; int encode = 0; + buff = safe_malloc (3 * strlen ((char *) src) + 1); + for (s = src; *s && !encode; s++) { if (*s & 0x80) @@ -332,12 +334,13 @@ int rfc2231_encode (char *dest, size_t l, unsigned char *src) *t = '\0'; if (Charset && SendCharset && mutt_strcasecmp (Charset, SendCharset)) - mutt_convert_string (buff, LONG_STRING, Charset, SendCharset); + mutt_convert_string (&buff, Charset, SendCharset); snprintf (dest, l, "%s''%s", SendCharset ? SendCharset : (Charset ? Charset : "unknown-8bit"), buff); } + safe_free ((void **) &buff); return encode; }