[gmime] Rfc2046 allows boundary merkers to be followed by lwsp



commit 06bc90fee2a87cafc89bc421f6607951073369db
Author: Jeffrey Stedfast <fejj gnome org>
Date:   Wed Aug 7 11:51:38 2013 -0400

    Rfc2046 allows boundary merkers to be followed by lwsp
    
    2013-08-07  Jeffrey Stedfast  <fejj gnome org>
    
        According to Rfc2046 Section 5.1.1, boundary markers may optionally
        be followed by lwsp.
    
        * gmime/gmime-parser.c (is_boundary): New convenience function to
        check that the text matches a boundary, possibly followed by lwsp.
        (check_boundary): Use is_boundary().
        (found_immediate_boundary): Use is_boundary().
    
        Fixes bug #705612

 ChangeLog            |   12 ++++++++++++
 gmime/gmime-parser.c |   45 +++++++++++++++++++++++++++++++++++----------
 2 files changed, 47 insertions(+), 10 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ef9a13a..2afba9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2013-08-07  Jeffrey Stedfast  <fejj gnome org>
+
+       According to Rfc2046 Section 5.1.1, boundary markers may optionally
+       be followed by lwsp.
+
+       * gmime/gmime-parser.c (is_boundary): New convenience function to
+       check that the text matches a boundary, possibly followed by lwsp.
+       (check_boundary): Use is_boundary().
+       (found_immediate_boundary): Use is_boundary().
+
+       Fixes bug #705612
+
 2013-07-02  Jeffrey Stedfast  <fejj gnome org>
 
        * gmime/gmime-stream-cat.c (stream_substream): Fixed to properly
diff --git a/gmime/gmime-parser.c b/gmime/gmime-parser.c
index 4e26c7e..ebf4e58 100644
--- a/gmime/gmime-parser.c
+++ b/gmime/gmime-parser.c
@@ -1353,6 +1353,30 @@ enum {
                          ((scan_from && len >= 5 && !strncmp (start, "From ", 5)) ||  \
                          (len >= 2 && (start[0] == '-' && start[1] == '-')))
 
+static gboolean
+is_boundary (const char *text, size_t len, const char *boundary, size_t boundary_len)
+{
+       const char *inptr = text + boundary_len;
+       const char *inend = text + len;
+       
+       if (boundary_len > len)
+               return FALSE;
+       
+       /* make sure that the text matches the boundary */
+       if (strncmp (text, boundary, boundary_len) != 0)
+               return FALSE;
+       
+       /* the boundary may be optionally followed by linear whitespace */
+       while (inptr < inend) {
+               if (!is_lwsp (*inptr))
+                       return FALSE;
+               
+               inptr++;
+       }
+       
+       return TRUE;
+}
+
 static int
 check_boundary (struct _GMimeParserPrivate *priv, const char *start, size_t len)
 {
@@ -1368,19 +1392,14 @@ check_boundary (struct _GMimeParserPrivate *priv, const char *start, size_t len)
                
                s = priv->bounds;
                while (s) {
-                       /* we use >= here because From lines are > 5 chars */
                        if (offset >= s->content_end &&
-                           len >= s->boundarylenfinal &&
-                           !strncmp (s->boundary, start,
-                                     s->boundarylenfinal)) {
+                           is_boundary (start, len, s->boundary, s->boundarylenfinal)) {
                                d(printf ("found %s\n", s->content_end != -1 && offset >= s->content_end ?
                                          "end of content" : "end boundary"));
                                return FOUND_END_BOUNDARY;
                        }
                        
-                       if (len == s->boundarylen &&
-                           !strncmp (s->boundary, start,
-                                     s->boundarylen)) {
+                       if (is_boundary (start, len, s->boundary, s->boundarylen)) {
                                d(printf ("found boundary\n"));
                                return FOUND_BOUNDARY;
                        }
@@ -1398,10 +1417,16 @@ static gboolean
 found_immediate_boundary (struct _GMimeParserPrivate *priv, gboolean end)
 {
        BoundaryStack *s = priv->bounds;
-       size_t len = end ? s->boundarylenfinal : s->boundarylen;
+       size_t boundary_len = end ? s->boundarylenfinal : s->boundarylen;
+       register char *inptr = priv->inptr;
+       char *inend = priv->inend;
+       
+       /* Note: see optimization comment [1] */
+       *inend = '\n';
+       while (*inptr != '\n')
+               inptr++;
        
-       return !strncmp (priv->inptr, s->boundary, len)
-               && (priv->inptr[len] == '\n' || priv->inptr[len] == '\r');
+       return is_boundary (priv->inptr, inptr - priv->inptr, s->boundary, boundary_len);
 }
 
 /* Optimization Notes:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]