From c861f6492fdab8037caf7aa7167ee5df008d3c06 Mon Sep 17 00:00:00 2001 From: Pavel Charvat Date: Wed, 10 Jan 2018 12:44:05 +0100 Subject: [PATCH] bgets_mp(): Rewritten implementation. --- ucw/fastbuf.h | 1 - ucw/ff-string.c | 38 ++++++++++---------------------------- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/ucw/fastbuf.h b/ucw/fastbuf.h index 77e5ecb0..0a04176a 100644 --- a/ucw/fastbuf.h +++ b/ucw/fastbuf.h @@ -752,7 +752,6 @@ struct bb_t; uint bgets_bb(struct fastbuf *f, struct bb_t *b, uint limit); /** * Read a string, strip the trailing `\n` and store it into buffer allocated from a memory pool. - * CAVEAT: Internally allocates the whole line on stack -> can segfault if too long. **/ char *bgets_mp(struct fastbuf *f, struct mempool *mp); diff --git a/ucw/ff-string.c b/ucw/ff-string.c index d3aff87c..d4dafede 100644 --- a/ucw/ff-string.c +++ b/ucw/ff-string.c @@ -2,7 +2,7 @@ * UCW Library -- Fast Buffered I/O: Strings * * (c) 1997--2006 Martin Mares - * (c) 2006 Pavel Charvat + * (c) 2006--2018 Pavel Charvat * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -135,17 +135,11 @@ bgets_mp(struct fastbuf *f, struct mempool *mp) uint src_len = bdirect_read_prepare(f, &src); if (!src_len) return NULL; -#define BLOCK_SIZE (4096 - sizeof(void *)) - struct block { - struct block *prev; - byte data[BLOCK_SIZE]; - } *blocks = NULL; - uint sum = 0, buf_len = BLOCK_SIZE, cnt; - struct block first_block, *new_block = &first_block; - byte *buf = new_block->data; + byte *buf = mp_start_noalign(mp, 1); + size_t buf_len = mp_avail(mp); do { - cnt = MIN(src_len, buf_len); + uint cnt = MIN(src_len, buf_len); for (uint i = cnt; i--;) { byte v = *src++; @@ -165,29 +159,17 @@ bgets_mp(struct fastbuf *f, struct mempool *mp) src_len -= cnt; if (cnt == buf_len) { - new_block->prev = blocks; - blocks = new_block; - sum += buf_len = BLOCK_SIZE; - new_block = alloca(sizeof(struct block)); - buf = new_block->data; + buf = mp_spread(mp, buf, 1); + buf_len = mp_avail(mp) - (buf - (byte *)mp_ptr(mp)); } else buf_len -= cnt; } while (src_len); -exit: ; - uint len = buf - new_block->data; - byte *result = mp_alloc(mp, sum + len + 1) + sum; - result[len] = 0; - memcpy(result, new_block->data, len); - while (blocks) - { - result -= BLOCK_SIZE; - memcpy(result, blocks->data, BLOCK_SIZE); - blocks = blocks->prev; - } - return result; -#undef BLOCK_SIZE +exit: + buf = mp_spread(mp, buf, 1); + *buf++ = 0; + return mp_end(mp, buf); } char * -- 2.39.2