summaryrefslogtreecommitdiff
path: root/memory
diff options
context:
space:
mode:
authorSander Striker <striker@apache.org>2002-07-13 21:34:36 +0000
committerSander Striker <striker@apache.org>2002-07-13 21:34:36 +0000
commit52348ddd93a09e17e2c08ae5f7f150683de1ab1f (patch)
tree85049fefb07f326c707cb7c2f5125639982d8ecb /memory
parentd4ccdc3eace25a0414c9b3c36a77b3b1440ed79c (diff)
downloadapr-52348ddd93a09e17e2c08ae5f7f150683de1ab1f.tar.gz
Remove a bogus fixup from apr_vformatter, which made sure a NUL byte could
fit in by flushing if the final character was at the exact end of the buffer it was using. Take care of the case that the fixup was handling in apr_psprintf, by ensuring we can fit a NUL byte from the beginning. Implement this by calling flush if we start with a 0 byte buffer (in which nothing can fit anyway). Secondly make sure that the flush function never tries to use a block that has less than APR_PSPRINTF_MIN_STRINGSIZE bytes to spare. Thanks to Nuutti Kotivuori <naked@iki.fi> for pointing out the problem, digging around for answers and providing patches. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@63654 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'memory')
-rw-r--r--memory/unix/apr_pools.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c
index 82a9f7b2e..91edc046e 100644
--- a/memory/unix/apr_pools.c
+++ b/memory/unix/apr_pools.c
@@ -903,6 +903,8 @@ struct psprintf_data {
apr_memnode_t *free;
};
+#define APR_PSPRINTF_MIN_STRINGSIZE 32
+
static int psprintf_flush(apr_vformatter_buff_t *vbuff)
{
struct psprintf_data *ps = (struct psprintf_data *)vbuff;
@@ -918,6 +920,14 @@ static int psprintf_flush(apr_vformatter_buff_t *vbuff)
cur_len = strp - active->first_avail;
size = cur_len << 1;
+ /* Make sure that we don't try to use a block that has less
+ * than APR_PSPRINTF_MIN_STRINGSIZE bytes left in it. This
+ * also catches the case where size == 0, which would result
+ * in reusing a block that can't even hold the NUL byte.
+ */
+ if (size < APR_PSPRINTF_MIN_STRINGSIZE)
+ size = APR_PSPRINTF_MIN_STRINGSIZE;
+
node = active->next;
if (!ps->got_a_new_node && node->first_avail + size < node->endp) {
*node->ref = node->next;
@@ -992,6 +1002,19 @@ APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap)
ps.got_a_new_node = 0;
ps.free = NULL;
+ /* Make sure that the first node passed to apr_vformatter has at least
+ * room to hold the NUL terminator.
+ */
+ if (ps.node->first_avail == ps.node->endp) {
+ if (psprintf_flush(&ps.vbuff) == -1) {
+ if (pool->abort_fn) {
+ pool->abort_fn(APR_ENOMEM);
+ }
+
+ return NULL;
+ }
+ }
+
if (apr_vformatter(psprintf_flush, &ps.vbuff, fmt, ap) == -1) {
if (pool->abort_fn)
pool->abort_fn(APR_ENOMEM);