]> granicus.if.org Git - mutt/commitdiff
String conversion patch from EGE.
authorThomas Roessler <roessler@does-not-exist.org>
Sat, 20 May 2000 15:46:39 +0000 (15:46 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Sat, 20 May 2000 15:46:39 +0000 (15:46 +0000)
charset.c
charset.h
curs_lib.c
rfc2047.c
rfc2231.c

index 792229b2f0c615dfcd9d1099bfe979378a16dcc4..62eac2887a41a8ca4211577941a23ace2e38c79c 100644 (file)
--- 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
index d76da2348074fd5362e73843b680f267746036fa..fa808da956c7c20ddabdd49a71363f1dcf527b92 100644 (file)
--- 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 *);
 
index de0f72e9b75bbd67160ffe3fc8ae7e31b8c21359..ac7dbc6a5d7eba26039a32da87fa42da8f09d7ca 100644 (file)
@@ -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);
index c131b2a5bd898c0e8722fa302a10e415de029e2a..848da2074ce5f60e5ad9fba68547490dff5bc55f 100644 (file)
--- 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);
 }
 
index 61fc9b692ff541fa96c0c57791dc1a17a2c7727d..16ce828d3c5ce927ba67954899e6551dbd365371 100644 (file)
--- 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;
 }