fix lengthcheck in m_getfld2()
[mmh] / sbr / m_getfld2.c
index 970a3f0..74d25e4 100644 (file)
@@ -10,6 +10,7 @@
 #include <h/utils.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <h/utils.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <stdbool.h>
 
 
 enum threestate {
 
 
 enum threestate {
@@ -23,7 +24,9 @@ enum threestate {
 */
 static enum threestate is_falted(FILE *);
 static size_t copyname(char *, char *);
 */
 static enum threestate is_falted(FILE *);
 static size_t copyname(char *, char *);
-static int is_separator(char *);
+static bool is_separator(char *);
+
+struct field free_field = { "\0", 0, NULL, 0, 0 };
 
 
 /*
 
 
 /*
@@ -46,12 +49,15 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
        char *tmpline = NULL;
        size_t len = 0;
        ssize_t nchars;
        char *tmpline = NULL;
        size_t len = 0;
        ssize_t nchars;
-       enum threestate falted;
+       enum threestate falted = B_FALSE;
+       enum state ret = s;
 
        switch (s) {
        case FLD2:
                nchars = getline(&tmpline, &len, msg);
                if (nchars < 1) {
 
        switch (s) {
        case FLD2:
                nchars = getline(&tmpline, &len, msg);
                if (nchars < 1) {
+                       free(f->value);
+                       *f = free_field;
                        if (feof(msg)) {
                                return FILEEOF2;
                        } else {
                        if (feof(msg)) {
                                return FILEEOF2;
                        } else {
@@ -59,29 +65,15 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                        }
                }
 
                        }
                }
 
-               *f->name = '\0';
-               f->namelen = 0;
-
                if (nchars >= NAMESZ) {
                if (nchars >= NAMESZ) {
-                       if (f->value) {
-                               free(f->value);
-                       }
-                       f->value = tmpline;
-                       f->valuelen = nchars;
-                       return LENERR2;
+                       ret = LENERR2;
                }
 
                if (*(tmpline + nchars - 1) != '\n') {
                }
 
                if (*(tmpline + nchars - 1) != '\n') {
-                       if (f->value) {
-                               free(f->value);
-                       }
-                       f->value = tmpline;
-                       f->valuelen = nchars;
-                       f->alloclen = len;
-                       return FMTERR2;
+                       ret = FMTERR2;
                }
 
                }
 
-               if (is_separator(tmpline)) {
+               if (ret == FLD2 && is_separator(tmpline)) {
                        /* header/body separator found */
                        free(tmpline);
                        return m_getfld2(BODY2, f, msg);
                        /* header/body separator found */
                        free(tmpline);
                        return m_getfld2(BODY2, f, msg);
@@ -89,13 +81,9 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
 
                f->namelen = copyname(f->name, tmpline);
                if (f->namelen < 1) {
 
                f->namelen = copyname(f->name, tmpline);
                if (f->namelen < 1) {
-                       if (f->value) {
-                               free(f->value);
-                       }
-                       f->value = tmpline;
-                       f->valuelen = nchars;
-                       f->alloclen = len;
-                       return FMTERR2;
+                       *f->name = '\0';
+                       f->namelen = 0;
+                       ret = FMTERR2;
                }
 
                /* copy the field's value */
                }
 
                /* copy the field's value */
@@ -103,10 +91,15 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                        f->value = mh_xrealloc(f->value, f->alloclen + len);
                        f->alloclen += len;
                }
                        f->value = mh_xrealloc(f->value, f->alloclen + len);
                        f->alloclen += len;
                }
-               strcpy(f->value, tmpline + f->namelen + 1);
-               f->valuelen = nchars - f->namelen - 1;
+               if (f->namelen != 0) {
+                       strcpy(f->value, tmpline + f->namelen + 1);
+                       f->valuelen = nchars - f->namelen - 1;
+               } else {
+                       strcpy(f->value, tmpline);
+                       f->valuelen = nchars;
+               }
 
 
-               while ((falted = is_falted(msg)) == B_TRUE) {
+               while (ret == FLD2 && (falted = is_falted(msg)) == B_TRUE) {
                        nchars = getline(&tmpline, &len, msg);
                        if (nchars <= 0) {
                                free(tmpline);
                        nchars = getline(&tmpline, &len, msg);
                        if (nchars <= 0) {
                                free(tmpline);
@@ -114,22 +107,11 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                        }
 
                        if (nchars >= NAMESZ) {
                        }
 
                        if (nchars >= NAMESZ) {
-                               if (f->value) {
-                                       free(f->value);
-                               }
-                               f->value = tmpline;
-                               f->valuelen = nchars;
-                               return LENERR2;
+                               ret = LENERR2;
                        }
 
                        if (*(tmpline + nchars - 1) != '\n') {
                        }
 
                        if (*(tmpline + nchars - 1) != '\n') {
-                               if (f->value) {
-                                       free(f->value);
-                               }
-                               f->value = tmpline;
-                               f->valuelen = nchars;
-                               f->alloclen = len;
-                               return FMTERR2;
+                               ret = FMTERR2;
                        }
 
                        if (f->alloclen - f->valuelen <= nchars) {
                        }
 
                        if (f->alloclen - f->valuelen <= nchars) {
@@ -143,16 +125,19 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                }
 
                if (falted == FAIL) {
                }
 
                if (falted == FAIL) {
-                       free(tmpline);
-                       return IOERR2;
+                       ret = IOERR2;
                }
 
                free(tmpline);
                }
 
                free(tmpline);
-               return FLD2;
+               return ret;
 
        case BODY2:
 
        case BODY2:
+               free(f->value);
+               *f = free_field;
+
                nchars = getline(&tmpline, &len, msg);
                if (nchars < 1) {
                nchars = getline(&tmpline, &len, msg);
                if (nchars < 1) {
+                       free(tmpline);
                        if (feof(msg)) {
                                return FILEEOF2;
                        } else {
                        if (feof(msg)) {
                                return FILEEOF2;
                        } else {
@@ -160,24 +145,14 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                        }
                }
 
                        }
                }
 
-               *f->name = '\0';
-               f->namelen = 0;
-
                if (nchars >= NAMESZ) {
                if (nchars >= NAMESZ) {
-                       if (f->value) {
-                               free(f->value);
-                       }
-                       f->value = tmpline;
-                       f->valuelen = nchars;
-                       return LENERR2;
-               }
-               if (f->value) {
-                       free(f->value);
+                       ret = LENERR2;
                }
                }
+
                f->value = tmpline;
                f->valuelen = nchars;
                f->alloclen = len;
                f->value = tmpline;
                f->valuelen = nchars;
                f->alloclen = len;
-               return BODY2;
+               return ret;
 
        default:
                /* give error states back as received */
 
        default:
                /* give error states back as received */
@@ -227,7 +202,7 @@ copyname(char *dst, char *src)
        }
 
        len = sep - src;
        }
 
        len = sep - src;
-       if (len >= NAMESZ) {
+       if (len >= NAMESZ - 1) {
                return 0;
        }
 
                return 0;
        }
 
@@ -237,7 +212,7 @@ copyname(char *dst, char *src)
        return strlen(dst);
 }
 
        return strlen(dst);
 }
 
-static int
+static bool
 is_separator(char *line)
 {
        /*
 is_separator(char *line)
 {
        /*
@@ -247,8 +222,8 @@ is_separator(char *line)
        while (*line == '-') {
                line++;
        }
        while (*line == '-') {
                line++;
        }
-       if (strcmp("\n", line)==0) {
-               return 1;
+       if (strcmp("\n", line) == 0 || strcmp("\r\n", line) == 0 ) {
+               return true;
        }
        }
-       return 0;
+       return false;
 }
 }