aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog8
-rw-r--r--camel/camel-mime-utils.c138
2 files changed, 114 insertions, 32 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index eab69a3617..09e4973925 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,11 @@
+2001-06-28 Jeffrey Stedfast <fejj@ximian.com>
+
+ * camel-mime-utils.c (header_decode_param_list): Fix a memory
+ leak. Also if the decoded value is NULL, that means it wasn't
+ encoded so we don't want to toss the old value.
+ (header_param_list_format_append): Correctly wrap long parameter
+ values according to rfc2184.
+
2001-06-28 Dan Winship <danw@ximian.com>
* providers/imap/camel-imap-folder.c (imap_refresh_info): If the
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 802514bf02..91f89b5947 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -1867,6 +1867,9 @@ header_decode_rfc2184_param (const char **in, char **paramp, int *part, gboolean
const char *inptr = *in;
char *param;
+ *value_is_encoded = FALSE;
+ *part = -1;
+
param = decode_param_token (&inptr);
header_decode_lwsp (&inptr);
@@ -1929,8 +1932,10 @@ header_decode_param(const char **in, char **paramp, char **valuep, int *is_rfc21
char *val;
val = rfc2184_decode (value, strlen (value));
- g_free (value);
- value = val;
+ if (val) {
+ g_free (value);
+ value = val;
+ }
} else {
/* Since we are expecting to find the rest of
* this paramter value later, let our caller know.
@@ -2634,15 +2639,15 @@ header_decode_param_list(const char **in)
header_decode_lwsp (&inptr);
while (*inptr == ';') {
- char *param, *value;
- struct _header_param *p;
+ struct _header_param *param;
+ char *name, *value;
inptr++;
/* invalid format? */
- if (header_decode_param (&inptr, &param, &value, &is_rfc2184) != 0)
+ if (header_decode_param (&inptr, &name, &value, &is_rfc2184) != 0)
break;
- if (is_rfc2184 && tail && !g_strcasecmp (param, tail->name)) {
+ if (is_rfc2184 && tail && !g_strcasecmp (name, tail->name)) {
/* rfc2184 allows a parameter to be broken into multiple parts
* and it looks like we've found one. Append this value to the
* last value.
@@ -2653,6 +2658,7 @@ header_decode_param_list(const char **in)
g_string_append (gvalue, value);
g_free (tail->value);
g_free (value);
+ g_free (name);
tail->value = gvalue->str;
g_string_free (gvalue, FALSE);
@@ -2664,19 +2670,21 @@ header_decode_param_list(const char **in)
char *val;
val = rfc2184_decode (tail->value, strlen (tail->value));
- g_free (tail->value);
- tail->value = val;
+ if (val) {
+ g_free (tail->value);
+ tail->value = val;
+ }
}
- p = g_malloc (sizeof (struct _header_param));
- p->name = param;
- p->value = value;
- p->next = NULL;
+ param = g_malloc (sizeof (struct _header_param));
+ param->name = name;
+ param->value = value;
+ param->next = NULL;
if (head == NULL)
- head = p;
+ head = param;
if (tail)
- tail->next = p;
- tail = p;
+ tail->next = param;
+ tail = param;
}
last_was_rfc2184 = is_rfc2184;
@@ -2691,11 +2699,14 @@ header_decode_param_list(const char **in)
char *val;
val = rfc2184_decode (tail->value, strlen (tail->value));
- g_free (tail->value);
- tail->value = val;
+ if (val) {
+ g_free (tail->value);
+ tail->value = val;
+ }
}
*in = inptr;
+
return head;
}
@@ -2786,38 +2797,96 @@ header_encode_param (const unsigned char *in, gboolean *encoded)
void
header_param_list_format_append(GString *out, struct _header_param *p)
{
- int len = out->len;
+ int used = out->len;
while (p) {
gboolean encoded = FALSE;
- char *value, *ch = NULL;
+ gboolean quote = FALSE;
int here = out->len;
+ int nlen, vlen;
+ char *value;
+
+ if (!p->value) {
+ p = p->next;
+ continue;
+ }
value = header_encode_param (p->value, &encoded);
if (!encoded) {
+ char *ch;
+
for (ch = value; *ch; ch++) {
if (is_tspecial (*ch) || is_lwsp (*ch))
break;
}
+
+ quote = ch && *ch;
}
- if (len + strlen (p->name) + strlen (value) > 60) {
+ nlen = strlen (p->name);
+ vlen = strlen (value);
+
+ if (used + nlen + vlen > CAMEL_FOLD_SIZE - 8) {
out = g_string_append (out, ";\n\t");
- len = 0;
+ here = out->len;
+ used = 0;
} else
out = g_string_append (out, "; ");
- g_string_sprintfa (out, "%s%s=", p->name, encoded ? "*" : "");
-
- if (!ch || !*ch)
- g_string_append (out, value);
- else
- quote_word (out, TRUE, value, strlen (value));
+ if (nlen + vlen > CAMEL_FOLD_SIZE - 8) {
+ /* we need to do special rfc2184 parameter wrapping */
+ int maxlen = CAMEL_FOLD_SIZE - (nlen + 8);
+ char *inptr, *inend;
+ int i = 0;
+
+ inptr = value;
+ inend = value + vlen;
+
+ while (inptr < inend) {
+ char *ptr = inptr + MIN (inend - inptr, maxlen);
+
+ if (encoded && ptr < inend) {
+ /* be careful not to break an encoded char (ie %20) */
+ char *q = ptr;
+ int j = 2;
+
+ for ( ; j > 0 && q > inptr && *q != '%'; j--, q--);
+ if (*q == '%')
+ ptr = q;
+ }
+
+ if (i != 0) {
+ g_string_append (out, ";\n\t");
+ here = out->len;
+ used = 0;
+ }
+
+ g_string_sprintfa (out, "%s*%d%s=", p->name, i++, encoded ? "*" : "");
+ if (encoded || !quote)
+ g_string_append_len (out, inptr, ptr - inptr);
+ else
+ quote_word (out, TRUE, inptr, ptr - inptr);
+
+ printf ("wrote: %s\n", out->str + here);
+
+ used += (out->len - here);
+
+ inptr = ptr;
+ }
+ } else {
+ g_string_sprintfa (out, "%s%s=", p->name, encoded ? "*" : "");
+
+ if (encoded || !quote)
+ g_string_append (out, value);
+ else
+ quote_word (out, TRUE, value, vlen);
+
+ used += (out->len - here);
+ }
g_free (value);
- len += (out->len - here);
p = p->next;
}
}
@@ -2934,7 +3003,8 @@ header_content_encoding_decode(const char *in)
return NULL;
}
-CamelMimeDisposition *header_disposition_decode(const char *in)
+CamelMimeDisposition *
+header_disposition_decode(const char *in)
{
CamelMimeDisposition *d = NULL;
const char *inptr = in;
@@ -2951,12 +3021,15 @@ CamelMimeDisposition *header_disposition_decode(const char *in)
return d;
}
-void header_disposition_ref(CamelMimeDisposition *d)
+void
+header_disposition_ref(CamelMimeDisposition *d)
{
if (d)
d->refcount++;
}
-void header_disposition_unref(CamelMimeDisposition *d)
+
+void
+header_disposition_unref(CamelMimeDisposition *d)
{
if (d) {
if (d->refcount<=1) {
@@ -2969,7 +3042,8 @@ void header_disposition_unref(CamelMimeDisposition *d)
}
}
-char *header_disposition_format(CamelMimeDisposition *d)
+char *
+header_disposition_format(CamelMimeDisposition *d)
{
GString *out;
char *ret;