Commit cb7bc0d8 authored by Guillem Jover's avatar Guillem Jover

Add file buffer pool support to fgetln()

This avoids buffer overwrites during concurrent or intermixed calls to
fgetln() when using more than one different stream (currently 32), which
the original interface supports natively by using an internal buffer
from the FILE structure. Although this workaround is rudimentary, it
should cover most of the theoretically problematic cases.
parent 1be0bdb2
......@@ -66,7 +66,7 @@ for man/arc4random.3, man/tree.3 and man/getprogname.3.
The rest of the licenses apply to code and/or man pages.
Copyright © 2004-2006, 2008-2011 Guillem Jover <guillem@hadrons.org>
Copyright © 2004-2006, 2008-2012 Guillem Jover <guillem@hadrons.org>
Copyright © 2005 Hector Garcia Alvarez
Copyright © 2005 Aurelien Jarno
Copyright © 2006 Robert Millan
......
/*
* Copyright © 2005 Hector Garcia Alvarez
* Copyright © 2005, 2008, 2009, 2011 Guillem Jover <guillem@hadrons.org>
* Copyright © 2005, 2008-2012 Guillem Jover <guillem@hadrons.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -31,21 +31,41 @@
#include <string.h>
#ifdef HAVE_GETLINE
struct filebuf {
FILE *fp;
char *buf;
size_t len;
};
#define FILEBUF_POOL_ITEMS 32
static struct filebuf fb_pool[FILEBUF_POOL_ITEMS];
static int fb_pool_cur;
char *
fgetln(FILE *stream, size_t *len)
{
static char *line = NULL;
static size_t line_len = 0;
struct filebuf *fb;
ssize_t nread;
nread = getline(&line, &line_len, stream);
/* Try to diminish the possibility of several fgetln() calls being
* used on different streams, by using a pool of buffers per file. */
fb = &fb_pool[fb_pool_cur];
if (fb->fp != stream && fb->fp != NULL) {
fb_pool_cur++;
fb_pool_cur %= FILEBUF_POOL_ITEMS;
fb = &fb_pool[fb_pool_cur];
}
fb->fp = stream;
nread = getline(&fb->buf, &fb->len, stream);
/* Note: the getdelim/getline API ensures nread != 0. */
if (nread == -1) {
*len = 0;
return NULL;
} else {
*len = (size_t)nread;
return line;
return fb->buf;
}
}
#else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment