prevent CNAME/PTR parsing from reading data past the response end
[musl] / src / stdio / fgets.c
index ee0ac30..4a100b3 100644 (file)
@@ -1,4 +1,5 @@
 #include "stdio_impl.h"
+#include <string.h>
 
 #define MIN(a,b) ((a)<(b) ? (a) : (b))
 
@@ -9,23 +10,28 @@ char *fgets(char *restrict s, int n, FILE *restrict f)
        size_t k;
        int c;
 
-       if (n--<=1) {
-               if (n) return 0;
+       FLOCK(f);
+
+       if (n<=1) {
+               f->mode |= f->mode-1;
+               FUNLOCK(f);
+               if (n<1) return 0;
                *s = 0;
                return s;
        }
-
-       FLOCK(f);
+       n--;
 
        while (n) {
-               z = memchr(f->rpos, '\n', f->rend - f->rpos);
-               k = z ? z - f->rpos + 1 : f->rend - f->rpos;
-               k = MIN(k, n);
-               memcpy(p, f->rpos, k);
-               f->rpos += k;
-               p += k;
-               n -= k;
-               if (z || !n) break;
+               if (f->rpos != f->rend) {
+                       z = memchr(f->rpos, '\n', f->rend - f->rpos);
+                       k = z ? z - f->rpos + 1 : f->rend - f->rpos;
+                       k = MIN(k, n);
+                       memcpy(p, f->rpos, k);
+                       f->rpos += k;
+                       p += k;
+                       n -= k;
+                       if (z || !n) break;
+               }
                if ((c = getc_unlocked(f)) < 0) {
                        if (p==s || !feof(f)) s = 0;
                        break;
@@ -33,7 +39,7 @@ char *fgets(char *restrict s, int n, FILE *restrict f)
                n--;
                if ((*p++ = c) == '\n') break;
        }
-       *p = 0;
+       if (s) *p = 0;
 
        FUNLOCK(f);