From 2bd378bf061bd9949b0123500df42b5b8a97ad8d Mon Sep 17 00:00:00 2001 From: Robert Spalek Date: Sun, 30 Apr 2006 13:30:48 +0200 Subject: [PATCH] conf: clearing a dynamic array allocates a zero-length array --- lib/conf-internal.h | 1 + lib/conf-intr.c | 15 ++++++++++----- lib/conf-section.c | 21 +++++---------------- lib/getopt.h | 2 +- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/lib/conf-internal.h b/lib/conf-internal.h index 3760d0e5..b31fc8c1 100644 --- a/lib/conf-internal.h +++ b/lib/conf-internal.h @@ -20,6 +20,7 @@ enum cf_operation; extern byte *cf_op_names[]; uns cf_type_size(enum cf_type type, struct cf_user_type *utype); +byte *cf_interpret_clear(struct cf_item *item, void *ptr); byte *cf_interpret_line(byte *name, enum cf_operation op, int number, byte **pars); void cf_init_stack(void); int cf_check_stack(void); diff --git a/lib/conf-intr.c b/lib/conf-intr.c index 934d0d71..0b84707e 100644 --- a/lib/conf-intr.c +++ b/lib/conf-intr.c @@ -264,15 +264,20 @@ interpret_set_item(struct cf_item *item, int number, byte **pars, int *processed } } -static byte * -interpret_clear(struct cf_item *item, void *ptr) +byte * +cf_interpret_clear(struct cf_item *item, void *ptr) { if (item->cls == CC_LIST) { cf_journal_block(ptr, sizeof(clist)); clist_init(ptr); } else if (item->cls == CC_DYNAMIC) { cf_journal_block(ptr, sizeof(void *)); - * (void**) ptr = NULL; + uns size = cf_type_size(item->type, item->u.utype); + static u64 zero = 0; + if (size <= sizeof(zero)) + *(void**)ptr = (&zero) + 1; + else + *(void**)ptr = cf_malloc_zero(size) + size; } else if (item->cls == CC_STATIC && item->type == CT_STRING) { cf_journal_block(ptr, item->number * sizeof(byte*)); bzero(ptr, item->number * sizeof(byte*)); @@ -487,7 +492,7 @@ cf_interpret_line(byte *name, enum cf_operation op, int number, byte **pars) int taken; // process as many parameters as possible if (op == OP_CLEAR) - taken = 0, msg = interpret_clear(item, ptr); + taken = 0, msg = cf_interpret_clear(item, ptr); else if (op == OP_SET) msg = interpret_set_item(item, number, pars, &taken, ptr, 1); else if (item->cls == CC_DYNAMIC) @@ -531,7 +536,7 @@ cf_write_item(struct cf_item *item, enum cf_operation op, int number, byte **par break; case OP_CLEAR: taken = 0; - msg = interpret_clear(item, item->ptr); + msg = cf_interpret_clear(item, item->ptr); break; case OP_APPEND: case OP_PREPEND: diff --git a/lib/conf-section.c b/lib/conf-section.c index 4908ca6e..b3d16ed2 100644 --- a/lib/conf-section.c +++ b/lib/conf-section.c @@ -150,20 +150,6 @@ cf_init_section(byte *name, struct cf_section *sec, void *ptr, uns do_bzero) } } -static void -replace_null_dary(struct cf_item *item, void **ptr) -{ - static u64 zero = 0; - if (*ptr) - return; - uns size = cf_type_size(item->type, item->u.utype); - cf_journal_block(ptr, sizeof(void*)); - if (size <= sizeof(zero)) - *ptr = (&zero) + 1; - else - *ptr = cf_malloc_zero(size) + size; -} - static byte * commit_section(struct cf_section *sec, void *ptr, uns commit_all) { @@ -182,8 +168,11 @@ commit_section(struct cf_section *sec, void *ptr, uns commit_all) log(L_ERROR, "Cannot commit node #%d of list %s: %s", idx, ci->name, err); return "commit of a list failed"; } - } else if (ci->cls == CC_DYNAMIC) - replace_null_dary(ci, ptr + (addr_int_t) ci->ptr); + } else if (ci->cls == CC_DYNAMIC) { + void **dyn = ptr + (addr_int_t) ci->ptr; + if (!*dyn) // replace NULL by an empty array + cf_interpret_clear(ci, dyn); + } if (sec->commit) { /* We have to process the whole tree of sections even if just a few changes * have been made, because there are dependencies between commit-hooks and diff --git a/lib/getopt.h b/lib/getopt.h index 7aaa99fa..a6f27786 100644 --- a/lib/getopt.h +++ b/lib/getopt.h @@ -34,12 +34,12 @@ enum cf_operation { CF_OPERATIONS }; #undef T struct cf_item; -struct fastbuf; byte *cf_find_item(byte *name, struct cf_item *item); byte *cf_write_item(struct cf_item *item, enum cf_operation op, int number, byte **pars); /* Debug dumping: conf-dump.c */ +struct fastbuf; void cf_dump_sections(struct fastbuf *fb); /* Journaling control: conf-journal.c */ -- 2.39.2