mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Fix getdelim(2) leaking a freed pointer.
This commit is contained in:
parent
e29f0cdd1e
commit
ecccf4e1f7
1 changed files with 23 additions and 10 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
|
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2014.
|
||||||
|
|
||||||
This file is part of the Sortix C Library.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -28,13 +28,17 @@
|
||||||
|
|
||||||
extern "C" ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* fp)
|
extern "C" ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* fp)
|
||||||
{
|
{
|
||||||
if ( !lineptr || (*lineptr && !n) || !fp ) { errno = EINVAL; return -1; }
|
if ( !lineptr || (*lineptr && !n) || !fp )
|
||||||
|
return errno = EINVAL, -1;
|
||||||
const size_t DEFAULT_BUFSIZE = 32UL;
|
const size_t DEFAULT_BUFSIZE = 32UL;
|
||||||
int malloced = !*lineptr;
|
bool malloced = !*lineptr;
|
||||||
if ( malloced ) { *lineptr = (char*) malloc(DEFAULT_BUFSIZE); }
|
if ( malloced )
|
||||||
if ( !*lineptr ) { return -1; }
|
*lineptr = (char*) malloc(DEFAULT_BUFSIZE);
|
||||||
|
if ( !*lineptr )
|
||||||
|
return -1;
|
||||||
size_t bufsize = malloced ? DEFAULT_BUFSIZE : *n;
|
size_t bufsize = malloced ? DEFAULT_BUFSIZE : *n;
|
||||||
if ( n ) { *n = bufsize; }
|
if ( n )
|
||||||
|
*n = bufsize;
|
||||||
ssize_t written = 0;
|
ssize_t written = 0;
|
||||||
int c;
|
int c;
|
||||||
flockfile(fp);
|
flockfile(fp);
|
||||||
|
@ -42,15 +46,20 @@ extern "C" ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* fp)
|
||||||
{
|
{
|
||||||
if ( (c = getc_unlocked(fp)) == EOF )
|
if ( (c = getc_unlocked(fp)) == EOF )
|
||||||
{
|
{
|
||||||
if ( written ) { break; } else { goto cleanup; }
|
if ( written )
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if ( bufsize <= (size_t) written + 1UL )
|
if ( bufsize <= (size_t) written + 1UL )
|
||||||
{
|
{
|
||||||
size_t newbufsize = 2UL * bufsize;
|
size_t newbufsize = 2UL * bufsize;
|
||||||
char* newbuf = (char*) realloc(*lineptr, newbufsize);
|
char* newbuf = (char*) realloc(*lineptr, newbufsize);
|
||||||
if ( !newbuf ) { goto cleanup; }
|
if ( !newbuf )
|
||||||
|
goto cleanup;
|
||||||
bufsize = newbufsize;
|
bufsize = newbufsize;
|
||||||
if ( n ) { *n = bufsize; }
|
if ( n )
|
||||||
|
*n = bufsize;
|
||||||
*lineptr = newbuf;
|
*lineptr = newbuf;
|
||||||
}
|
}
|
||||||
(*lineptr)[written++] = c;
|
(*lineptr)[written++] = c;
|
||||||
|
@ -61,6 +70,10 @@ extern "C" ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* fp)
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
funlockfile(fp);
|
funlockfile(fp);
|
||||||
free(malloced ? *lineptr : NULL);
|
if ( malloced )
|
||||||
|
{
|
||||||
|
free(*lineptr);
|
||||||
|
*lineptr = NULL;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue