summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-02-06 21:19:50 -0800
committerKaz Kylheku <kaz@kylheku.com>2020-02-06 21:19:50 -0800
commit52c1aef14849e0f3f4ecb4f6177c48af3b352631 (patch)
tree1bca87f87a14d49531adeec27749c99a81a04172
parenta7881343e163ba29c31f946e9f943685bb977d6d (diff)
downloadtxr-52c1aef14849e0f3f4ecb4f6177c48af3b352631.tar.gz
txr-52c1aef14849e0f3f4ecb4f6177c48af3b352631.tar.bz2
txr-52c1aef14849e0f3f4ecb4f6177c48af3b352631.zip
buf: bugfix: buf-set-length not setting bytes.
* buf.c (buf_grow): Function removed; logic merged into buf_do_set_len. The bug fixed is that buf_grow was initializing just the newly allocated bytes to init_val. The bytes that must actually be initialized are those which lie between the old and new length, not in the allocated area. (make_buf): In make_buf, we don't have to initialize the entire buffer, but only bytes 0 through len - 1. Now calloc is only used when the initializing value is zero, and the buffer's allocation size is the same as the length. When the length is increase to protrude into the allocated uninitialized area, buf_do_set_len will now properly initialize that to the value given at that time. * txr.1: Update make-buf documentation not to say that all the bytes of the buffer are initialized.
-rw-r--r--buf.c64
-rw-r--r--txr.15
2 files changed, 35 insertions, 34 deletions
diff --git a/buf.c b/buf.c
index b034e266..09bdd0ee 100644
--- a/buf.c
+++ b/buf.c
@@ -78,11 +78,11 @@ static cnum buf_check_index(struct buf *b, val index, val self)
val make_buf(val len, val init_val, val alloc_size)
{
val self = lit("make-buf");
- cnum l = buf_check_len(len, self);
+ cnum blen = buf_check_len(len, self);
val alloc = if3(null_or_missing_p(alloc_size), len, alloc_size);
- cnum size = buf_check_alloc_size(alloc, l, self);
+ cnum size = buf_check_alloc_size(alloc, blen, self);
cnum iv = c_u8(default_arg(init_val, zero), self);
- mem_t *data = if3(iv == 0,
+ mem_t *data = if3(iv == 0 && size == blen,
chk_calloc(size, 1),
chk_malloc(size));
val obj = make_obj();
@@ -92,8 +92,8 @@ val make_buf(val len, val init_val, val alloc_size)
obj->b.len = len;
obj->b.size = num(size);
- if (iv != 0)
- memset(data, convert(unsigned char, iv), c_num(len));
+ if (iv != 0 || size != blen)
+ memset(data, convert(unsigned char, iv), blen);
return obj;
}
@@ -153,29 +153,6 @@ val copy_buf(val buf)
make_borrowed_buf(b->len, b->data));
}
-static void buf_grow(struct buf *b, val init_val, val self)
-{
- cnum len = c_num(b->len);
- cnum oldsize = c_num(b->size), size = oldsize;
- cnum iv = c_u8(default_arg(init_val, zero), self);
-
- 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) {
- b->data = chk_realloc(b->data, size);
- b->size = num(size);
- memset(b->data + oldsize, convert(unsigned char, iv), size - oldsize);
- }
-}
-
static void buf_shrink(struct buf *b)
{
val len = b->len;
@@ -201,16 +178,39 @@ val buf_trim(val buf)
return oldsize;
}
-static val buf_do_set_len(val buf, struct buf *b, val len,
+static val buf_do_set_len(val buf, struct buf *b, val newlen,
val init_val, val self)
{
val oldlen = b->len;
+ cnum olen = c_num(oldlen), len = c_num(newlen);
+ cnum oldsize = c_num(b->size), size = oldsize;
+ cnum iv = c_u8(default_arg(init_val, zero), self);
+
if (!b->size)
uw_throwf(error_s, lit("~a: ~s is a fixed buffer"),
self, buf, nao);
- (void) buf_check_len(len, self);
- b->len = len;
- buf_grow(b, init_val, self);
+ (void) buf_check_len(newlen, self);
+
+ b->len = newlen;
+
+ 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) {
+ b->data = chk_realloc(b->data, size);
+ b->size = num(size);
+ }
+
+ if (len > olen)
+ memset(b->data + olen, convert(unsigned char, iv), len - olen);
+
return oldlen;
}
diff --git a/txr.1 b/txr.1
index 25ce4255..04d68357 100644
--- a/txr.1
+++ b/txr.1
@@ -24065,8 +24065,9 @@ bytes. This argument may be zero.
If
.meta init-val
-is present, it specifies the value with which every
-byte of the buffer is initialized. If omitted, it
+is present, it specifies the value with which the first
+.meta len
+byte of the buffer are initialized. If omitted, it
defaults to zero.
bytes. The value of
.meta init-val