[evolution-patches] 47824, multipart messages re-using teh same boundary
- From: Not Zed <notzed ximian com>
- To: asdf <evolution-patches lists ximian com>
- Subject: [evolution-patches] 47824, multipart messages re-using teh same boundary
- Date: Wed, 12 Jan 2005 16:32:50 +0800
this includes the 64 bit patches from a previous mail too, too hard to extract right now.
for stable, and same needs to go into head.
includes fixes for tests too.
? camel/tests/folder/test10
? camel/tests/message/test4
? camel/tests/mime-filter/test-tohtml
? camel/tests/misc/test2
? camel/tests/misc/url-scan
Index: camel/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/camel/Attic/ChangeLog,v
retrieving revision 1.2251.2.30
diff -u -p -r1.2251.2.30 ChangeLog
--- camel/ChangeLog 6 Jan 2005 09:25:02 -0000 1.2251.2.30
+++ camel/ChangeLog 12 Jan 2005 08:33:36 -0000
@@ -1,3 +1,29 @@
+2005-01-12 Not Zed <NotZed Ximian com>
+
+ ** See bug #47824.
+
+ * camel-multipart-signed.c (parse_content): re-implemented to use
+ camel-mime-parser. For the annoying pathalogical case of re-used
+ multipart boundary markers.
+
+ * camel-mime-parser.c (folder_scan_step): modified the multipart
+ state so that we don't try to match the same boundary again if
+ we've already seen an end boundary for this part. This is for the
+ annoying case of a multipart inside a multipart which shares an
+ identical boundary marker (groupwise!).
+ (camel_mime_parser_tell_start_boundary): new function to indicate
+ the offset of the start of the last boundary.
+
+ * tests/lib/folders.c (test_folder_message_ops): fix test case for
+ deleting message - marks message read too.
+ (test_folder_counts): fix typo.
+
+ * tests/message/test3.c (main): remove the nonfatal fixme & put
+ extra null check for pre/postface text checks.
+
+ * tests/message/test2.c (convert): use size_t for iconv length
+ types.
+
2004-12-23 Not Zed <NotZed Ximian com>
** See bug #70556.
Index: camel/camel-mime-parser.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/Attic/camel-mime-parser.c,v
retrieving revision 1.60.26.1
diff -u -p -r1.60.26.1 camel-mime-parser.c
--- camel/camel-mime-parser.c 30 Nov 2004 07:56:07 -0000 1.60.26.1
+++ camel/camel-mime-parser.c 12 Jan 2005 08:33:36 -0000
@@ -46,6 +46,8 @@
#include "camel-stream.h"
#include "camel-seekable-stream.h"
+#include "e-util/e-memory.h"
+
#define r(x)
#define h(x)
#define c(x)
@@ -57,8 +59,6 @@
#define MEMPOOL
-#define STRUCT_ALIGN 4
-
#ifdef PURIFY
int inend_id = -1,
inbuffer_id = -1;
@@ -71,115 +71,6 @@ int inend_id = -1,
#define _header_scan_state _CamelMimeParserPrivate
#define _PRIVATE(o) (((CamelMimeParser *)(o))->priv)
-#ifdef MEMPOOL
-typedef struct _MemPoolNode {
- struct _MemPoolNode *next;
-
- int free;
- char data[1];
-} MemPoolNode;
-
-typedef struct _MemPoolThresholdNode {
- struct _MemPoolThresholdNode *next;
- char data[1];
-} MemPoolThresholdNode;
-
-typedef struct _MemPool {
- int blocksize;
- int threshold;
- struct _MemPoolNode *blocks;
- struct _MemPoolThresholdNode *threshold_blocks;
-} MemPool;
-
-MemPool *mempool_new(int blocksize, int threshold);
-void *mempool_alloc(MemPool *pool, int size);
-void mempool_flush(MemPool *pool, int freeall);
-void mempool_free(MemPool *pool);
-
-MemPool *mempool_new(int blocksize, int threshold)
-{
- MemPool *pool;
-
- pool = g_malloc(sizeof(*pool));
- if (threshold >= blocksize)
- threshold = blocksize * 2 / 3;
- pool->blocksize = blocksize;
- pool->threshold = threshold;
- pool->blocks = NULL;
- pool->threshold_blocks = NULL;
- return pool;
-}
-
-void *mempool_alloc(MemPool *pool, int size)
-{
- size = (size + STRUCT_ALIGN) & (~(STRUCT_ALIGN-1));
- if (size>=pool->threshold) {
- MemPoolThresholdNode *n;
-
- n = g_malloc(sizeof(*n) - sizeof(char) + size);
- n->next = pool->threshold_blocks;
- pool->threshold_blocks = n;
- return &n->data[0];
- } else {
- MemPoolNode *n;
-
- n = pool->blocks;
- while (n) {
- if (n->free >= size) {
- n->free -= size;
- return &n->data[n->free];
- }
- n = n->next;
- }
-
- n = g_malloc(sizeof(*n) - sizeof(char) + pool->blocksize);
- n->next = pool->blocks;
- pool->blocks = n;
- n->free = pool->blocksize - size;
- return &n->data[n->free];
- }
-}
-
-void mempool_flush(MemPool *pool, int freeall)
-{
- MemPoolThresholdNode *tn, *tw;
- MemPoolNode *pw, *pn;
-
- tw = pool->threshold_blocks;
- while (tw) {
- tn = tw->next;
- g_free(tw);
- tw = tn;
- }
- pool->threshold_blocks = NULL;
-
- if (freeall) {
- pw = pool->blocks;
- while (pw) {
- pn = pw->next;
- g_free(pw);
- pw = pn;
- }
- pool->blocks = NULL;
- } else {
- pw = pool->blocks;
- while (pw) {
- pw->free = pool->blocksize;
- pw = pw->next;
- }
- }
-}
-
-void mempool_free(MemPool *pool)
-{
- if (pool) {
- mempool_flush(pool, 1);
- g_free(pool);
- }
-}
-
-#endif
-
struct _header_scan_state {
/* global state */
@@ -213,6 +104,7 @@ struct _header_scan_state {
unsigned int eof:1; /* reached eof? */
off_t start_of_from; /* where from started */
+ off_t start_of_boundary; /* where the last boundary started */
off_t start_of_headers; /* where headers started from the last scan */
off_t header_start; /* start of last header, or -1 */
@@ -232,7 +124,7 @@ struct _header_scan_stack {
enum _camel_mime_parser_state savestate; /* state at invocation of this part */
#ifdef MEMPOOL
- MemPool *pool; /* memory pool to keep track of headers/etc at this level */
+ EMemPool *pool; /* memory pool to keep track of headers/etc at this level */
#endif
struct _camel_header_raw *headers; /* headers for this part */
@@ -269,6 +161,8 @@ static int folder_scan_skip_line(struct
static off_t folder_seek(struct _header_scan_state *s, off_t offset, int whence);
static off_t folder_tell(struct _header_scan_state *s);
static int folder_read(struct _header_scan_state *s);
+static void folder_push_part(struct _header_scan_state *s, struct _header_scan_stack *h);
+
#ifdef MEMPOOL
static void header_append_mempool(struct _header_scan_state *s, struct _header_scan_stack *h, char *header, int offset);
#endif
@@ -856,6 +750,24 @@ camel_mime_parser_tell_start_from (Camel
}
/**
+ * camel_mime_parser_tell_start_boundary:
+ * @parser: MIME parser object
+ *
+ * When parsing a multipart, this returns the start of the last
+ * boundary.
+ *
+ * Return value: The start of the boundary, or -1 if there
+ * was no boundary encountered yet.
+ **/
+off_t
+camel_mime_parser_tell_start_boundary(CamelMimeParser *parser)
+{
+ struct _header_scan_state *s = _PRIVATE (parser);
+
+ return s->start_of_boundary;
+}
+
+/**
* camel_mime_parser_seek:
* @parser: MIME parser object
* @offset: Number of bytes to offset the seek by.
@@ -897,6 +809,30 @@ camel_mime_parser_state (CamelMimeParser
}
/**
+ * camel_mime_parser_push_state:
+ * @mp: MIME parser object
+ * @newstate: New state
+ * @boundary: Boundary marker for state.
+ *
+ * Pre-load a new parser state. Used to post-parse multipart content
+ * without headers.
+ **/
+void
+camel_mime_parser_push_state(CamelMimeParser *mp, enum _camel_mime_parser_state newstate, const char *boundary)
+{
+ struct _header_scan_stack *h;
+ struct _header_scan_state *s = _PRIVATE(mp);
+
+ h = g_malloc0(sizeof(*h));
+ h->boundarylen = strlen(boundary)+2;
+ h->boundarylenfinal = h->boundarylen+2;
+ h->boundary = g_malloc(h->boundarylen+3);
+ sprintf(h->boundary, "--%s--", boundary);
+ folder_push_part(s, h);
+ s->state = newstate;
+}
+
+/**
* camel_mime_parser_stream:
* @parser: MIME parser object
*
@@ -1067,7 +1003,7 @@ folder_pull_part(struct _header_scan_sta
s->parts = h->parent;
g_free(h->boundary);
#ifdef MEMPOOL
- mempool_free(h->pool);
+ e_mempool_destroy(h->pool);
#else
camel_header_raw_clear(&h->headers);
#endif
@@ -1175,18 +1111,18 @@ header_append_mempool(struct _header_sca
content = strchr(header, ':');
if (content) {
register int len;
- n = mempool_alloc(h->pool, sizeof(*n));
+ n = e_mempool_alloc(h->pool, sizeof(*n));
n->next = NULL;
len = content-header;
- n->name = mempool_alloc(h->pool, len+1);
+ n->name = e_mempool_alloc(h->pool, len+1);
memcpy(n->name, header, len);
n->name[len] = 0;
content++;
len = s->outptr - content;
- n->value = mempool_alloc(h->pool, len+1);
+ n->value = e_mempool_alloc(h->pool, len+1);
memcpy(n->value, content, len);
n->value[len] = 0;
@@ -1246,7 +1182,7 @@ folder_scan_header(struct _header_scan_s
h = g_malloc0(sizeof(*h));
#ifdef MEMPOOL
- h->pool = mempool_new(8192, 4096);
+ h->pool = e_mempool_new(8192, 4096, E_MEMPOOL_ALIGN_STRUCT);
#endif
if (s->parts)
@@ -1518,6 +1454,7 @@ folder_scan_init(void)
s->start_of_from = -1;
s->start_of_headers = -1;
+ s->start_of_boundary = -1;
s->midline = FALSE;
s->scan_from = FALSE;
@@ -1589,8 +1526,7 @@ folder_scan_step(struct _header_scan_sta
struct _header_scan_stack *h, *hb;
const char *content;
const char *bound;
- int type;
- int state;
+ int type, state, seenlast;
CamelContentType *ct = NULL;
struct _header_scan_filter *f;
size_t presize;
@@ -1760,6 +1696,14 @@ tail_recurse:
case CAMEL_MIME_PARSER_STATE_MULTIPART:
h = s->parts;
+ /* This mess looks for the next boundary on this
+ level. Once it finds the last one, it keeps going,
+ looking for post-multipart content ('postface').
+ Because messages might have duplicate boundaries for
+ different parts, it makes sure it stops if its already
+ found an end boundary for this part. It handles
+ truncated and missing boundaries appropriately too. */
+ seenlast = FALSE;
do {
do {
hb = folder_scan_content(s, &state, databuffer, datalength);
@@ -1780,15 +1724,17 @@ tail_recurse:
}
} while (hb==h && *datalength>0);
h->prestage++;
- if (*datalength==0 && hb==h) {
- d(printf("got boundary: %s\n", hb->boundary));
+ if (*datalength==0 && hb==h && !seenlast) {
+ d(printf("got boundary: %s last=%d\n", hb->boundary, state));
+ s->start_of_boundary = folder_tell(s);
folder_scan_skip_line(s, NULL);
if (!state) {
s->state = CAMEL_MIME_PARSER_STATE_FROM;
folder_scan_step(s, databuffer, datalength);
s->parts->savestate = CAMEL_MIME_PARSER_STATE_MULTIPART; /* set return state for the new head part */
return;
- }
+ } else
+ seenlast = TRUE;
} else {
break;
}
Index: camel/camel-mime-parser.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/Attic/camel-mime-parser.h,v
retrieving revision 1.21
diff -u -p -r1.21 camel-mime-parser.h
--- camel/camel-mime-parser.h 18 Sep 2003 17:06:20 -0000 1.21
+++ camel/camel-mime-parser.h 12 Jan 2005 08:33:36 -0000
@@ -106,6 +106,7 @@ enum _camel_mime_parser_state camel_mime
void camel_mime_parser_unstep (CamelMimeParser *parser);
void camel_mime_parser_drop_step (CamelMimeParser *parser);
enum _camel_mime_parser_state camel_mime_parser_state (CamelMimeParser *parser);
+void camel_mime_parser_push_state(CamelMimeParser *mp, enum _camel_mime_parser_state newstate, const char *boundary);
/* read through the parser */
int camel_mime_parser_read (CamelMimeParser *parser, const char **databuffer, int len);
@@ -138,6 +139,7 @@ off_t camel_mime_parser_seek (CamelMimeP
off_t camel_mime_parser_tell_start_headers (CamelMimeParser *parser);
off_t camel_mime_parser_tell_start_from (CamelMimeParser *parser);
+off_t camel_mime_parser_tell_start_boundary(CamelMimeParser *parser);
#ifdef __cplusplus
}
Index: camel/camel-multipart-signed.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/Attic/camel-multipart-signed.c,v
retrieving revision 1.22.26.1
diff -u -p -r1.22.26.1 camel-multipart-signed.c
--- camel/camel-multipart-signed.c 1 Dec 2004 03:59:14 -0000 1.22.26.1
+++ camel/camel-multipart-signed.c 12 Jan 2005 08:33:36 -0000
@@ -181,47 +181,60 @@ camel_multipart_signed_new (void)
return multipart;
}
-/* find the next boundary @bound from @start, return the start of the actual data
- @end points to the end of the data BEFORE the boundary */
-static char *parse_boundary(char *start, char *last, const char *bound, char **end)
+static int
+skip_content(CamelMimeParser *cmp)
{
- char *data, *begin;
-
- while ((begin = memchr(start, bound[0], last-start))) {
- if (memcmp(begin, bound, strlen(bound)) == 0)
+ char *buf;
+ size_t len;
+ int state;
+
+ switch (camel_mime_parser_state(cmp)) {
+ case CAMEL_MIME_PARSER_STATE_HEADER:
+ /* body part */
+ while (camel_mime_parser_step(cmp, &buf, &len) != CAMEL_MIME_PARSER_STATE_BODY_END)
+ /* NOOP */ ;
+ break;
+ case CAMEL_MIME_PARSER_STATE_MESSAGE:
+ /* message body part */
+ skip_content(cmp);
+
+ /* clean up followon state if any, see camel-mime-message.c */
+ state = camel_mime_parser_step(cmp, &buf, &len);
+ switch (state) {
+ case CAMEL_MIME_PARSER_STATE_EOF:
+ case CAMEL_MIME_PARSER_STATE_FROM_END: /* these doesn't belong to us */
+ camel_mime_parser_unstep(cmp);
+ case CAMEL_MIME_PARSER_STATE_MESSAGE_END:
break;
- start = begin+1;
+ default:
+ g_error ("Bad parser state: Expecing MESSAGE_END or EOF or EOM, got: %d", camel_mime_parser_state (cmp));
+ camel_mime_parser_unstep(cmp);
+ return -1;
+ }
+ break;
+ case CAMEL_MIME_PARSER_STATE_MULTIPART:
+ /* embedded multipart */
+ while ((state = camel_mime_parser_step(cmp, &buf, &len)) != CAMEL_MIME_PARSER_STATE_MULTIPART_END)
+ skip_content(cmp);
+ break;
+ default:
+ g_warning("Invalid state encountered???: %d", camel_mime_parser_state(cmp));
}
- if (begin == NULL)
- return NULL;
-
- data = begin+strlen(bound);
- if (begin > start && begin[-1] == '\n')
- begin--;
- if (begin > start && begin[-1] == '\r')
- begin--;
- if (data[0] == '\r')
- data++;
- if (data[0] == '\n')
- data++;
-
- *end = begin;
- return data;
+ return 0;
}
-/* yeah yuck.
- Well, we could probably use the normal mime parser, but then it would change our
- headers.
- This is good enough ... till its not! */
static int
parse_content(CamelMultipartSigned *mps)
{
+ CamelMimeParser *cmp;
CamelMultipart *mp = (CamelMultipart *)mps;
- char *start, *end, *start2, *end2, *last, *post;
CamelStreamMem *mem;
- char *bound;
const char *boundary;
+ char *buf;
+ size_t len;
+ off_t head = -1, tail = -1;
+ int state;
boundary = camel_multipart_get_boundary(mp);
if (boundary == NULL) {
@@ -229,45 +242,59 @@ parse_content(CamelMultipartSigned *mps)
return -1;
}
- /* turn it into a string, and 'fix' it up */
- /* this is extremely dodgey but should work! */
mem = (CamelStreamMem *)((CamelDataWrapper *)mps)->stream;
if (mem == NULL) {
g_warning("Trying to parse multipart/signed without constructing first");
return -1;
}
- last = mem->buffer->data + mem->buffer->len;
+ /* This is all seriously complex.
+ This is so we can parse all cases properly, without altering the content.
+ All we are doing is finding part offsets. */
+
+ camel_stream_reset((CamelStream *)mem);
+ cmp = camel_mime_parser_new();
+ camel_mime_parser_init_with_stream(cmp, (CamelStream *)mem);
+ camel_mime_parser_push_state(cmp, CAMEL_MIME_PARSER_STATE_MULTIPART, boundary);
+
+ mps->start1 = -1;
+ mps->end1 = -1;
+ mps->start2 = -1;
+ mps->end2 = -1;
+
+ while ((state = camel_mime_parser_step(cmp, &buf, &len)) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) {
+ if (mps->start1 == -1) {
+ head = camel_mime_parser_tell_start_boundary(cmp);
+ mps->start1 = camel_mime_parser_tell_start_headers(cmp);
+ } else if (mps->start2 == -1) {
+ mps->start2 = camel_mime_parser_tell_start_headers(cmp);
+ mps->end1 = camel_mime_parser_tell_start_boundary(cmp);
+ if (mps->end1 > mps->start1 && mem->buffer->data[mps->end1-1] == '\n')
+ mps->end1--;
+ if (mps->end1 > mps->start1 && mem->buffer->data[mps->end1-1] == '\r')
+ mps->end1--;
+ } else {
+ g_warning("multipart/signed has more than 2 parts, remaining parts ignored");
+ break;
+ }
- bound = alloca(strlen(boundary)+5);
- sprintf(bound, "--%s", boundary);
+ if (skip_content(cmp) == -1)
+ break;
+ }
- start = parse_boundary(mem->buffer->data, last, bound, &end);
- if (start == NULL || start[0] == 0)
- return -1;
+ if (state == CAMEL_MIME_PARSER_STATE_MULTIPART_END) {
+ mps->end2 = camel_mime_parser_tell_start_boundary(cmp);
+ tail = camel_mime_parser_tell(cmp);
- if (end > (char *)mem->buffer->data) {
- char *tmp = g_strndup(mem->buffer->data, start-(char *)mem->buffer->data-1);
- camel_multipart_set_preface(mp, tmp);
- g_free(tmp);
+ camel_multipart_set_preface(mp, camel_mime_parser_preface(cmp));
+ camel_multipart_set_postface(mp, camel_mime_parser_postface(cmp));
}
- start2 = parse_boundary(start, last, bound, &end);
- if (start2 == NULL || start2[0] == 0)
- return -1;
+ camel_object_unref(cmp);
- sprintf(bound, "--%s--", boundary);
- post = parse_boundary(start2, last, bound, &end2);
- if (post == NULL)
+ if (mps->end2 == -1 || mps->start2 == -1) {
return -1;
-
- if (post[0])
- camel_multipart_set_postface(mp, post);
-
- mps->start1 = start-(char *)mem->buffer->data;
- mps->end1 = end-(char *)mem->buffer->data;
- mps->start2 = start2-(char *)mem->buffer->data;
- mps->end2 = end2-(char *)mem->buffer->data;
+ }
return 0;
}
Index: camel/tests/lib/folders.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/tests/lib/Attic/folders.c,v
retrieving revision 1.10.58.1
diff -u -p -r1.10.58.1 folders.c
--- camel/tests/lib/folders.c 30 Nov 2004 07:56:07 -0000 1.10.58.1
+++ camel/tests/lib/folders.c 12 Jan 2005 08:33:36 -0000
@@ -12,13 +12,19 @@ test_folder_counts(CamelFolder *folder,
{
GPtrArray *s;
int i, myunread;
+ guint32 gottotal, gotunread;
CamelMessageInfo *info;
push("test folder counts %d total %d unread", total, unread);
/* first, use the standard functions */
check(camel_folder_get_message_count(folder) == total);
- check(camel_folder_get_unread_message_count(folder) == total);
+ check(camel_folder_get_unread_message_count(folder) == unread);
+
+ /* accessors */
+ camel_object_get(folder, NULL, CAMEL_FOLDER_TOTAL, &gottotal, CAMEL_FOLDER_UNREAD, &gotunread, 0);
+ check(gottotal == total);
+ check(gotunread == unread);
/* next, use the summary */
s = camel_folder_get_summary(folder);
@@ -469,7 +475,8 @@ test_folder_message_ops(CamelSession *se
push("deleting first message & expunging");
camel_folder_delete_message(folder, uids->pdata[0]);
- test_folder_counts(folder, 10, 10);
+ /* deleting marks message read implictly */
+ test_folder_counts(folder, 10, 9);
camel_folder_expunge(folder, ex);
check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
test_folder_not_message(folder, uids->pdata[0]);
@@ -498,7 +505,7 @@ test_folder_message_ops(CamelSession *se
push("deleting last message & expunging");
camel_folder_delete_message(folder, uids->pdata[8]);
/* sync? */
- test_folder_counts(folder, 9, 9);
+ test_folder_counts(folder, 9, 8);
camel_folder_expunge(folder, ex);
check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
test_folder_not_message(folder, uids->pdata[8]);
@@ -529,7 +536,7 @@ test_folder_message_ops(CamelSession *se
camel_folder_delete_message(folder, uids->pdata[j]);
}
/* sync? */
- test_folder_counts(folder, 8, 8);
+ test_folder_counts(folder, 8, 0);
camel_folder_expunge(folder, ex);
check_msg(!camel_exception_is_set(ex), "%s", camel_exception_get_description(ex));
for (j=0;j<8;j++) {
Index: camel/tests/message/test2.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/tests/message/Attic/test2.c,v
retrieving revision 1.5
diff -u -p -r1.5 test2.c
--- camel/tests/message/test2.c 26 Apr 2001 18:21:32 -0000 1.5
+++ camel/tests/message/test2.c 12 Jan 2005 08:33:37 -0000
@@ -19,7 +19,7 @@ static char *convert(const char *in, con
iconv_t ic = iconv_open(to, from);
char *out, *outp;
const char *inp;
- int inlen, outlen;
+ size_t inlen, outlen;
if (ic == (iconv_t)-1)
return g_strdup(in);
Index: camel/tests/message/test3.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/tests/message/Attic/test3.c,v
retrieving revision 1.3
diff -u -p -r1.3 test3.c
--- camel/tests/message/test3.c 17 Jan 2001 01:07:02 -0000 1.3
+++ camel/tests/message/test3.c 12 Jan 2005 08:33:37 -0000
@@ -140,10 +140,7 @@ int main(int argc, char **argv)
check(strcmp(camel_multipart_get_boundary(mp2), "_=,.XYZ_Kangaroo_Meat_is_!_ABADF00D") == 0);
check(mp2->preface == NULL || strlen(mp2->preface) == 0);
- /* FIXME */
- camel_test_nonfatal("postface may gain a single \\n?");
check_msg(mp2->postface == NULL || strlen(mp2->postface) == 0, "postface: '%s'", mp2->postface);
- camel_test_fatal();
test_message_compare_content(camel_medium_get_content_object(CAMEL_MEDIUM(camel_multipart_get_part(mp2, 0))),
"content part 1", strlen("content part 1"));
@@ -175,8 +172,8 @@ int main(int argc, char **argv)
check(camel_multipart_get_number(mp2) == 3);
check(strcmp(camel_multipart_get_boundary(mp2), "_=,.XYZ_Kangaroo_Meat_is_!_ABADF00D") == 0);
- check(strcmp(mp2->preface, "pre-text\nLines.") == 0);
- check(strcmp(mp2->postface, "post-text, no lines.\nOne line.\n") == 0);
+ check(mp2->preface && strcmp(mp2->preface, "pre-text\nLines.") == 0);
+ check(mp2->postface && strcmp(mp2->postface, "post-text, no lines.\nOne line.\n") == 0);
test_message_compare_content(camel_medium_get_content_object(CAMEL_MEDIUM(camel_multipart_get_part(mp2, 0))),
"content part 1", strlen("content part 1"));
test_message_compare_content(camel_medium_get_content_object(CAMEL_MEDIUM(camel_multipart_get_part(mp2, 1))),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]