diff options
| -rw-r--r-- | vmemalloc.c | 44 | ||||
| -rw-r--r-- | vxexecl.c | 2 |
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; @@ -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); } |
