aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vmemalloc.c44
-rw-r--r--vxexecl.c2
2 files changed, 25 insertions, 21 deletions
diff --git a/vmemalloc.c b/vmemalloc.c
index d725374..e71500f 100644
--- a/vmemalloc.c
+++ b/vmemalloc.c
@@ -18,14 +18,14 @@ struct memalloc_state {
};
static int
-vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va_list ap)
+vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va_list *ap)
{
if (state->have_size++)
goto inval;
state->elem_size = arg;
if (n) {
while (--n) {
- arg = va_arg(ap, size_t);
+ arg = va_arg(*ap, size_t);
if (!state->elem_size)
continue;
if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(arg, state->elem_size, &state->elem_size, SIZE_MAX)) {
@@ -37,7 +37,7 @@ vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va
if (!arg)
goto inval;
for (;;) {
- arg = va_arg(ap, size_t);
+ arg = va_arg(*ap, size_t);
if (!arg)
break;
if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(arg, state->elem_size, &state->elem_size, SIZE_MAX)) {
@@ -46,7 +46,6 @@ vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va
}
}
}
-
return 0;
inval:
errno = EINVAL;
@@ -54,15 +53,15 @@ inval:
}
static int
-vmemalloc_parse_args(struct memalloc_state *state, size_t n, va_list ap)
+vmemalloc_parse_args(struct memalloc_state *state, size_t n, va_list *ap)
{
enum libsimple_memalloc_option opt;
long int page_size;
- va_list *subapp;
+ va_list *subap;
size_t arg;
for (;;) {
- opt = va_arg(ap, enum libsimple_memalloc_option);
+ opt = va_arg(*ap, enum libsimple_memalloc_option);
switch (opt) {
case LIBSIMPLE_MEMALLOC_END:
return 0;
@@ -76,7 +75,7 @@ vmemalloc_parse_args(struct memalloc_state *state, size_t n, va_list ap)
case LIBSIMPLE_MEMALLOC_CONDITIONAL_ZERO_INIT:
if (state->zero_init >= 0)
goto inval;
- state->zero_init = (char)va_arg(ap, int);
+ state->zero_init = (char)va_arg(*ap, int);
state->zero_init = !!state->zero_init;
break;
@@ -90,7 +89,7 @@ vmemalloc_parse_args(struct memalloc_state *state, size_t n, va_list ap)
case LIBSIMPLE_MEMALLOC_ALIGNMENT:
if (state->alignment)
goto inval;
- state->alignment = va_arg(ap, size_t);
+ state->alignment = va_arg(*ap, size_t);
if (!state->alignment)
goto inval;
break;
@@ -122,34 +121,34 @@ vmemalloc_parse_args(struct memalloc_state *state, size_t n, va_list ap)
case LIBSIMPLE_MEMALLOC_ELEMENT_SIZE:
if (state->elem_size)
goto inval;
- state->elem_size = va_arg(ap, size_t);
+ state->elem_size = va_arg(*ap, size_t);
if (!state->elem_size)
goto inval;
break;
case LIBSIMPLE_MEMALLOC_PRODUCT_SIZE:
- arg = va_arg(ap, size_t);
+ arg = va_arg(*ap, size_t);
if (vmemalloc_parse_size_prod(state, n, arg, ap))
return -1;
break;
case LIBSIMPLE_MEMALLOC_VA_PRODUCT_SIZE:
- subapp = va_arg(ap, va_list *);
- arg = va_arg(*subapp, size_t);
- if (vmemalloc_parse_size_prod(state, n, arg, *subapp))
+ subap = va_arg(*ap, va_list *);
+ arg = va_arg(*subap, size_t);
+ if (vmemalloc_parse_size_prod(state, n, arg, subap))
return -1;
break;
case LIBSIMPLE_MEMALLOC_1_VA_PRODUCT_SIZE:
- arg = va_arg(ap, size_t);
- subapp = va_arg(ap, va_list *);
- if (vmemalloc_parse_size_prod(state, n, arg, *subapp))
+ arg = va_arg(*ap, size_t);
+ subap = va_arg(*ap, va_list *);
+ if (vmemalloc_parse_size_prod(state, n, arg, subap))
return -1;
break;
case LIBSIMPLE_MEMALLOC_VA_LIST:
- subapp = va_arg(ap, va_list *);
- if (vmemalloc_parse_args(state, n, *subapp))
+ subap = va_arg(*ap, va_list *);
+ if (vmemalloc_parse_args(state, n, subap))
return -1;
break;
@@ -199,6 +198,9 @@ libsimple_vmemalloc(size_t n, va_list ap) /* TODO test ([v]{mem,array}alloc) */
void *ptr = NULL;
int saved_errno;
long int tmp;
+ va_list ap_copy; /* required because `ap` may be an array (specific single-element array)
+ * that has decayed into a pointer, and so &ap would not be a `va_list *`
+ * and casting to `void *` could just obfuscate this critical error */
state.alignment = 0;
state.elem_size = 0;
@@ -210,8 +212,10 @@ libsimple_vmemalloc(size_t n, va_list ap) /* TODO test ([v]{mem,array}alloc) */
state.cache_align = 0;
state.cache_split = 0;
- if (vmemalloc_parse_args(&state, n, ap))
+ va_copy(ap_copy, ap);
+ if (vmemalloc_parse_args(&state, n, &ap_copy))
return NULL;
+ va_end(ap_copy);
state.elem_size = state.elem_size ? state.elem_size : 1;
state.zero_init = state.zero_init >= 0 ? state.zero_init : 0;
diff --git a/vxexecl.c b/vxexecl.c
index c8282a6..4c804ec 100644
--- a/vxexecl.c
+++ b/vxexecl.c
@@ -17,7 +17,7 @@ libsimple_vxexecl(int dirfd, const char *file, int atflags, const char *path, ch
argv = alloca((argc + 1) * sizeof(*argv));
argc = 0;
do {
- argv[argc] = va_arg(args, char *);
+ argv[argc] = va_arg(argv_null, char *);
} while (argv[argc++]);
return libsimple_xexecv(dirfd, file, atflags, path, envp, argv);
}