summaryrefslogtreecommitdiffhomepage
path: root/lib/struct.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-06-04 20:55:53 +0200
committerJo-Philipp Wich <jo@mein.io>2022-06-04 20:55:53 +0200
commit44b0a3b3938333a4f2b00d159fab258a9acd31c1 (patch)
treea466ad089f3ff0bcbd143d5767c7b222881b4dd6 /lib/struct.c
parentb211ca0e420d8086d3fa0358413a6f8b44df1115 (diff)
struct: fix packing `*` format after other repeated formats
When packing a format such as `!6C*`, the `*` format was not included into the result buffer due to improper tracking of the function argument offset. Solve this issue by taking field repetitions into account when tracking the argument offset while calculating the size of dynamic arguments. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'lib/struct.c')
-rw-r--r--lib/struct.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/struct.c b/lib/struct.c
index 5d301db..bd418b2 100644
--- a/lib/struct.c
+++ b/lib/struct.c
@@ -2182,17 +2182,17 @@ overflow:
static uc_value_t *
uc_pack_common(uc_vm_t *vm, size_t nargs, formatstate_t *state, size_t argoff)
{
+ size_t ncode, arg, off;
formatcode_t *code;
- size_t ncode, off;
uc_string_t *buf;
ssize_t size, n;
const void *p;
- for (ncode = 0, code = &state->codes[0], off = 0;
+ for (ncode = 0, code = &state->codes[0], arg = argoff, off = 0;
ncode < state->ncodes;
code = &state->codes[++ncode]) {
if (code->fmtdef->format == '*') {
- uc_value_t *v = uc_fn_arg(argoff + ncode);
+ uc_value_t *v = uc_fn_arg(arg++);
if (ucv_type(v) != UC_STRING)
continue;
@@ -2204,6 +2204,9 @@ uc_pack_common(uc_vm_t *vm, size_t nargs, formatstate_t *state, size_t argoff)
else
off += code->size;
}
+ else {
+ arg += code->repeat;
+ }
}
buf = xalloc(sizeof(*buf) + state->size + off + 1);