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.
|
||||
|
||||
|
@ -28,13 +28,17 @@
|
|||
|
||||
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;
|
||||
int malloced = !*lineptr;
|
||||
if ( malloced ) { *lineptr = (char*) malloc(DEFAULT_BUFSIZE); }
|
||||
if ( !*lineptr ) { return -1; }
|
||||
bool malloced = !*lineptr;
|
||||
if ( malloced )
|
||||
*lineptr = (char*) malloc(DEFAULT_BUFSIZE);
|
||||
if ( !*lineptr )
|
||||
return -1;
|
||||
size_t bufsize = malloced ? DEFAULT_BUFSIZE : *n;
|
||||
if ( n ) { *n = bufsize; }
|
||||
if ( n )
|
||||
*n = bufsize;
|
||||
ssize_t written = 0;
|
||||
int c;
|
||||
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 ( written ) { break; } else { goto cleanup; }
|
||||
if ( written )
|
||||
break;
|
||||
else
|
||||
goto cleanup;
|
||||
}
|
||||
if ( bufsize <= (size_t) written + 1UL )
|
||||
{
|
||||
size_t newbufsize = 2UL * bufsize;
|
||||
char* newbuf = (char*) realloc(*lineptr, newbufsize);
|
||||
if ( !newbuf ) { goto cleanup; }
|
||||
if ( !newbuf )
|
||||
goto cleanup;
|
||||
bufsize = newbufsize;
|
||||
if ( n ) { *n = bufsize; }
|
||||
if ( n )
|
||||
*n = bufsize;
|
||||
*lineptr = newbuf;
|
||||
}
|
||||
(*lineptr)[written++] = c;
|
||||
|
@ -61,6 +70,10 @@ extern "C" ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* fp)
|
|||
|
||||
cleanup:
|
||||
funlockfile(fp);
|
||||
free(malloced ? *lineptr : NULL);
|
||||
if ( malloced )
|
||||
{
|
||||
free(*lineptr);
|
||||
*lineptr = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue