mirror of git://git.musl-libc.org/musl
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.
This commit is contained in:
parent
42216742cd
commit
d87f0a9a95
|
@ -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;
|
k = z ? z - f->rpos + 1 : f->rend - f->rpos;
|
||||||
if (i+k+1 >= *n) {
|
if (i+k+1 >= *n) {
|
||||||
if (k >= SIZE_MAX/2-i) goto oom;
|
if (k >= SIZE_MAX/2-i) goto oom;
|
||||||
*n = i+k+2;
|
size_t m = i+k+2;
|
||||||
if (*n < SIZE_MAX/4) *n *= 2;
|
if (m < SIZE_MAX/4) m *= 2;
|
||||||
tmp = realloc(*s, *n);
|
tmp = realloc(*s, m);
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
*n = i+k+2;
|
m = i+k+2;
|
||||||
tmp = realloc(*s, *n);
|
tmp = realloc(*s, m);
|
||||||
if (!tmp) goto oom;
|
if (!tmp) goto oom;
|
||||||
}
|
}
|
||||||
*s = tmp;
|
*s = tmp;
|
||||||
|
*n = m;
|
||||||
}
|
}
|
||||||
memcpy(*s+i, f->rpos, k);
|
memcpy(*s+i, f->rpos, k);
|
||||||
f->rpos += k;
|
f->rpos += k;
|
||||||
|
|
Loading…
Reference in New Issue