From 93c320de5e5fa5054b559a24c1246a63512210d4 Mon Sep 17 00:00:00 2001 From: chris mikkelson Date: Tue, 9 Mar 2010 16:43:36 -0600 Subject: [PATCH] More robust test of "end of parts" boundary -- compile second regexp for end boundary, and check matched boundary line against this. --- multipart.c | 56 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/multipart.c b/multipart.c index 4707c77..84468df 100644 --- a/multipart.c +++ b/multipart.c @@ -18,7 +18,7 @@ static msgproc_module *nextmod; struct multipart_state { struct stream_re *boundre; - pcre *bre; + pcre *bre, *endre; int state; }; @@ -52,7 +52,7 @@ setboundary(msgproc *m, int type, void *data, size_t size) if (type != MULTIPART_BOUNDARY) return; if (!mps) return; - boundpat = malloc(2*size + strlen("^--(--)?$") + 1); + boundpat = malloc(2*size + strlen("^----.*\r\n") + 1); if (!boundpat) goto fail; strcpy(boundpat, "^--"); @@ -72,11 +72,15 @@ setboundary(msgproc *m, int type, void *data, size_t size) *s++ = *b; } } - strcpy(s, "(--)?$"); + strcpy(s, ".*\r?\n"); mps->bre = pcre_compile(boundpat, PCRE_MULTILINE, &etxt, &epos, 0); if (!mps->bre) goto fail; + strcpy(s, "--.*\r?\n"); + mps->endre = pcre_compile(boundpat, PCRE_MULTILINE, &etxt, &epos, 0); + if (!mps->endre) goto fail; + /* fprintf(stderr, "multipart_init: boundpat = %s\n", boundpat); */ free(boundpat); /* no longer needed */ @@ -86,12 +90,20 @@ setboundary(msgproc *m, int type, void *data, size_t size) if (!sre) goto fail; re_stream_start(sre, mps->bre, 0); - mps->boundre = sre; + + sre = malloc(sizeof(struct stream_re)); + if (!sre) goto fail; + return; fail: if (boundpat) free(boundpat); if (mps->bre) pcre_free(mps->bre); + if (mps->endre) pcre_free(mps->endre); + if (mps->boundre) { + re_stream_stop(mps->boundre); + free(mps->boundre); + } } #define STATE_PREAMBLE 0 @@ -104,7 +116,8 @@ multipart_process(msgproc *m, char *buf, size_t len) struct multipart_state *mps = msgproc_getpriv(m); char *s = buf; size_t p, l = len; - int ml; + int ml, match, ematch; + int ovec[30]; msgproc *next; char *pmatch = 0; @@ -132,12 +145,14 @@ multipart_process(msgproc *m, char *buf, size_t len) pmatch); */ p = re_stream_exec(mps->boundre, s, l); if (p < 0) break; + match = re_stream_result(mps->boundre); + /* fprintf(stderr, "multipart_process: p = %d, result = %d\n", p, re_stream_result(mps->boundre)); */ switch(mps->state) { case STATE_PREAMBLE: - if (re_stream_result(mps->boundre) == 1) { + if (match == 1) { s += p; l -= p; mps->state = STATE_PARTS; @@ -150,18 +165,16 @@ multipart_process(msgproc *m, char *buf, size_t len) break; case STATE_PARTS: next = msgproc_next(m); - if (re_stream_result(mps->boundre) == 0) { + if (match == 0) { msgproc_process(next, s, l); s += l; l = 0; - break; - } else if (re_stream_result(mps->boundre) == -1) { + } else if (match == -1) { ml = strlen(re_stream_getresult(mps->boundre)); if (p > ml) msgproc_process(next, s, p - ml); s += l; l = 0; - break; } else { /* full match */ char *bm = re_stream_getresult(mps->boundre); ml = strlen(bm); @@ -172,24 +185,24 @@ multipart_process(msgproc *m, char *buf, size_t len) msgproc_process(next, s, p - ml); } msgproc_finish(next); - /* check for -- at end of match */ - /* fprintf(stderr, "endofmatch = %s\n", - bm + ml - 2); */ - if (!strcmp("--", bm + ml - 2)) { + + ematch = pcre_exec(mps->endre, 0, bm, ml, + 0, 0, ovec, 30); + + if (ematch > 0) { mps->state = STATE_END; - s += l; - l = 0; - break; + } else { + next = msgproc_create(m, nextmod); + msgproc_start(next); + s += p; + l -= p; } - next = msgproc_create(m, nextmod); - msgproc_start(next); - s += p; - l -= p; } } if (pmatch) free(pmatch); pmatch = 0; } + if (pmatch) free(pmatch); } void @@ -202,6 +215,7 @@ multipart_finish(msgproc *m) free(mps->boundre); } if (mps->bre) pcre_free(mps->bre); + if (mps->endre) pcre_free(mps->endre); } free(mps); msgproc_free(m); -- 2.50.1