m_getfld2 is more tranceparent on error
authorPhilipp Takacs <philipp@bureaucracy.de>
Thu, 26 Nov 2015 22:07:12 +0000 (23:07 +0100)
committerPhilipp Takacs <philipp@bureaucracy.de>
Fri, 27 Nov 2015 01:01:17 +0000 (02:01 +0100)
now all read content of the file is given to the caller,
so he can possible fix this error.

sbr/m_getfld2.c

index a2b8ae9..cd1c6be 100644 (file)
@@ -47,12 +47,15 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
        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) {
+                       free(f->value);
+                       *f = (struct field) { "\0", 0, NULL, 0, 0 };
                        if (feof(msg)) {
                                return FILEEOF2;
                        } else {
@@ -60,29 +63,15 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                        }
                }
 
-               *f->name = '\0';
-               f->namelen = 0;
-
                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 (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);
@@ -90,13 +79,9 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
 
                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 */
@@ -104,10 +89,15 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                        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);
@@ -115,22 +105,11 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                        }
 
                        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 (f->value) {
-                                       free(f->value);
-                               }
-                               f->value = tmpline;
-                               f->valuelen = nchars;
-                               f->alloclen = len;
-                               return FMTERR2;
+                               ret = FMTERR2;
                        }
 
                        if (f->alloclen - f->valuelen <= nchars) {
@@ -144,16 +123,22 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                }
 
                if (falted == FAIL) {
-                       free(tmpline);
-                       return IOERR2;
+                       ret = IOERR2;
                }
 
                free(tmpline);
-               return FLD2;
+               return ret;
 
        case BODY2:
+               *f->name = '\0';
+               f->namelen = 0;
+
                nchars = getline(&tmpline, &len, msg);
                if (nchars < 1) {
+                       free(f->value);
+                       f->value = NULL;
+                       f->valuelen = 0;
+                       f->alloclen = 0;
                        if (feof(msg)) {
                                return FILEEOF2;
                        } else {
@@ -161,24 +146,15 @@ m_getfld2(enum state s, struct field *f, FILE *msg)
                        }
                }
 
-               *f->name = '\0';
-               f->namelen = 0;
-
                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;
                }
+
+               free(f->value);
                f->value = tmpline;
                f->valuelen = nchars;
                f->alloclen = len;
-               return BODY2;
+               return ret;
 
        default:
                /* give error states back as received */