瀏覽代碼

avoid updating caller's size when getdelim fails to realloc

getdelim was updating *n, the caller's stored buffer size, before
calling realloc. if getdelim then failed due to realloc failure, the
caller would see in *n a value larger than the actual size of the
allocated block, and use of that value is unsafe. in particular,
passing it again to getdelim is unsafe.

now, temporary storage is used for the desired new size, and *n is not
written until realloc succeeds.
Rich Felker 9 年之前
父節點
當前提交
d87f0a9a95
共有 1 個文件被更改,包括 6 次插入5 次删除
  1. 6 5
      src/stdio/getdelim.c

+ 6 - 5
src/stdio/getdelim.c

@@ -29,15 +29,16 @@ ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restric
 		k = z ? z - f->rpos + 1 : f->rend - f->rpos;
 		if (i+k+1 >= *n) {
 			if (k >= SIZE_MAX/2-i) goto oom;
-			*n = i+k+2;
-			if (*n < SIZE_MAX/4) *n *= 2;
-			tmp = realloc(*s, *n);
+			size_t m = i+k+2;
+			if (m < SIZE_MAX/4) m *= 2;
+			tmp = realloc(*s, m);
 			if (!tmp) {
-				*n = i+k+2;
-				tmp = realloc(*s, *n);
+				m = i+k+2;
+				tmp = realloc(*s, m);
 				if (!tmp) goto oom;
 			}
 			*s = tmp;
+			*n = m;
 		}
 		memcpy(*s+i, f->rpos, k);
 		f->rpos += k;