Commit 680aa496 authored by Rusty Russell's avatar Rusty Russell

tal: add tal_expand().

Helper to reallocate and append to an array.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 5582b011
......@@ -712,6 +712,37 @@ bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
return true;
}
bool tal_expand_(tal_t **ctxp, const void *src, size_t size, size_t count)
{
struct length *l;
bool ret = false;
l = find_property(debug_tal(to_tal_hdr(*ctxp)), LENGTH);
/* Check for additive overflow */
if (l->count + count < count) {
call_error("dup size overflow");
goto out;
}
/* Don't point src inside thing we're expanding! */
assert(src < *ctxp
|| (char *)src >= (char *)(*ctxp) + (size * l->count));
/* Note: updates l->count. */
if (!tal_resize_(ctxp, size, l->count + count))
goto out;
memcpy((char *)*ctxp + size * (l->count - count),
src, count * size);
ret = true;
out:
if (taken(src))
tal_free(src);
return ret;
}
void *tal_dup_(const tal_t *ctx, const void *p, size_t size,
size_t n, size_t extra, bool add_count,
const char *label)
......
......@@ -305,6 +305,28 @@ void tal_set_backend(void *(*alloc_fn)(size_t size),
void (*free_fn)(void *),
void (*error_fn)(const char *msg));
/**
* tal_expand - expand a tal array with contents.
* @a1p: a pointer to the tal array to expand.
* @a2: the second array (can be take()).
* @num2: the number of elements in the second array.
*
* Note that *@a1 and @a2 should be the same type. tal_count(@a1) will
* be increased by @num2.
*
* Example:
* int *arr1 = tal_arrz(NULL, int, 2);
* int arr2[2] = { 1, 3 };
*
* tal_expand(&arr1, arr2, 2);
* assert(tal_count(arr1) == 4);
* assert(arr1[2] == 1);
* assert(arr1[3] == 3);
*/
#define tal_expand(a1p, a2, num2) \
tal_expand_((void **)(a1p), (a2), sizeof**(a1p), \
(num2) + 0*sizeof(*(a1p) == (a2)))
/**
* tal_check - set the allocation or error functions to use
......@@ -374,6 +396,7 @@ void *tal_dup_(const tal_t *ctx, const void *p, size_t size,
tal_t *tal_steal_(const tal_t *new_parent, const tal_t *t);
bool tal_resize_(tal_t **ctxp, size_t size, size_t count);
bool tal_expand_(tal_t **ctxp, const void *src, size_t size, size_t count);
bool tal_add_destructor_(const tal_t *ctx, void (*destroy)(void *me));
bool tal_del_destructor_(const tal_t *ctx, void (*destroy)(void *me));
......
#include <ccan/tal/tal.h>
#include <ccan/tal/tal.c>
#include <ccan/tap/tap.h>
int main(void)
{
int *a;
const int arr[] = { 1, 2 };
plan_tests(13);
a = tal_arrz(NULL, int, 1);
ok1(a);
ok1(tal_expand(&a, arr, 2));
ok1(tal_count(a) == 3);
ok1(a[0] == 0);
ok1(a[1] == 1);
ok1(a[2] == 2);
ok1(tal_expand(&a, take(tal_arrz(NULL, int, 1)), 1));
ok1(tal_count(a) == 4);
ok1(a[0] == 0);
ok1(a[1] == 1);
ok1(a[2] == 2);
ok1(a[3] == 0);
ok1(tal_first(NULL) == a && !tal_next(NULL, a));
tal_free(a);
return exit_status();
}
......@@ -13,8 +13,9 @@ int main(void)
{
void *p;
int *pi, *origpi;
char *cp;
plan_tests(26);
plan_tests(30);
tal_set_backend(NULL, NULL, NULL, my_error);
......@@ -81,5 +82,17 @@ int main(void)
ok1(error_count == 1);
ok1(!tal_first(NULL));
/* Overflow on expand addition. */
cp = tal_arr(p, char, 100);
ok1(!tal_expand(&cp, NULL, (size_t)-99UL));
ok1(error_count == 2);
tal_free(cp);
/* Overflow when multiplied by size */
origpi = tal_arr(NULL, int, 100);
ok1(!tal_expand(&origpi, NULL, (size_t)-1UL / sizeof(int)));
ok1(error_count == 3);
tal_free(origpi);
return exit_status();
}
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