summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-08-22 06:12:39 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-08-22 06:12:39 -0700
commit94bfe477b3b3131b40900d0158ac6629fc1223f2 (patch)
treedaf11992de3e6b21caefdb20ab7ebec8b6270064
parent154ebba2ff0a4847881421a96337c776ee394da3 (diff)
downloadtxr-94bfe477b3b3131b40900d0158ac6629fc1223f2.tar.gz
txr-94bfe477b3b3131b40900d0158ac6629fc1223f2.tar.bz2
txr-94bfe477b3b3131b40900d0158ac6629fc1223f2.zip
buffers: fix infinite loop in buf_grow.
* buf.c (buf_grow): When size is zero and len is nonzero, the loop doesn't terminate. Replace silly loop with straightforward calculation: grow buffer by 25%, capped at INT_PTR_MAX, or grow to the length, whichever is larger.
-rw-r--r--buf.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/buf.c b/buf.c
index b97bef41..b22ff2b2 100644
--- a/buf.c
+++ b/buf.c
@@ -143,12 +143,14 @@ static void buf_grow(struct buf *b, val init_val, val self)
cnum oldsize = c_num(b->size), size = oldsize;
cnum iv = c_u8(default_arg(init_val, zero), self);
- while (size < len) {
- cnum delta = size / 4;
- if (INT_PTR_MAX - delta >= size)
- size += delta;
- else
- size = len;
+ if (size < len) {
+ if (size > INT_PTR_MAX - INT_PTR_MAX / 5) {
+ size = INT_PTR_MAX;
+ } else {
+ size = size + size / 4;
+ if (size < len)
+ size = len;
+ }
}
if (size > oldsize) {