path: root/src/erec.c
diff options
authorPhil Sutter <>2017-08-24 19:14:10 +0200
committerPablo Neira Ayuso <>2017-08-24 19:20:29 +0200
commit80ee176dccf6954c8cc6493283ddadba42b8f694 (patch)
treea43b67b66a4d0c231ca971c137a134ef0a55ff9e /src/erec.c
parenta67af69a32cffbd727a48ea7b1d23ce92f1327ee (diff)
scanner: Fix for memleak due to unclosed file pointer
When including a file, it is opened by fopen() and therefore needs to be closed after scanning has finished using fclose(), otherwise valgrind will report a memleak. This patch changes struct input_descriptor to track the opened FILE pointer instead of the file descriptor so the pointer is available for closing in scanner_destroy(). While at it, change erec_print() to work on the open FILE pointer so it doesn't have to call fileno() in beforehand. And as a little bonus, use C99 initializer of the buffer to get rid of the call to memset(). Note that it is necessary to call erec_print_list() prior to destroying the scanner, otherwise it will start manipulating an already freed FILE pointer (and therefore crash the program). Signed-off-by: Phil Sutter <>
Diffstat (limited to 'src/erec.c')
1 files changed, 5 insertions, 6 deletions
diff --git a/src/erec.c b/src/erec.c
index b5964465..f62bc78c 100644
--- a/src/erec.c
+++ b/src/erec.c
@@ -118,7 +118,7 @@ void erec_print(FILE *f, const struct error_record *erec,
const struct location *loc = erec->locations, *iloc;
const struct input_descriptor *indesc = loc->indesc, *tmp;
const char *line = NULL; /* silence gcc */
- char buf[1024];
+ char buf[1024] = {};
char *pbuf = NULL;
unsigned int i, end;
int l, ret;
@@ -131,14 +131,13 @@ void erec_print(FILE *f, const struct error_record *erec,
*strchrnul(line, '\n') = '\0';
- memset(buf, 0, sizeof(buf));
- orig_offset = lseek(indesc->fd, 0, SEEK_CUR);
- lseek(indesc->fd, loc->line_offset, SEEK_SET);
- ret = read(indesc->fd, buf, sizeof(buf) - 1);
+ orig_offset = ftell(indesc->fp);
+ fseek(indesc->fp, loc->line_offset, SEEK_SET);
+ ret = fread(buf, 1, sizeof(buf) - 1, indesc->fp);
if (ret > 0)
*strchrnul(buf, '\n') = '\0';
line = buf;
- lseek(indesc->fd, orig_offset, SEEK_SET);
+ fseek(indesc->fp, orig_offset, SEEK_SET);