]> git.mikk.net Git - liburl/commitdiff
More robust test of "end of parts" boundary -- compile second
authorchris mikkelson <chris@mikk.net>
Tue, 9 Mar 2010 22:43:36 +0000 (16:43 -0600)
committerchris mikkelson <chris@mikk.net>
Tue, 9 Mar 2010 22:43:36 +0000 (16:43 -0600)
regexp for end boundary, and check matched boundary line against
this.

multipart.c

index 4707c776bd5cc71be1b3e779065f99f3386e293e..84468df1edbdffecf0130271252dcf93dac82300 100644 (file)
@@ -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);