]> mj.ucw.cz Git - libucw.git/commitdiff
conf: clearing a dynamic array allocates a zero-length array
authorRobert Spalek <robert@ucw.cz>
Sun, 30 Apr 2006 11:30:48 +0000 (13:30 +0200)
committerRobert Spalek <robert@ucw.cz>
Sun, 30 Apr 2006 11:30:48 +0000 (13:30 +0200)
lib/conf-internal.h
lib/conf-intr.c
lib/conf-section.c
lib/getopt.h

index 3760d0e5be2265b52efe4a4059b0a7dd3eee2468..b31fc8c15dedf8ffec256ae9c6a19a11adc7d570 100644 (file)
@@ -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);
index 934d0d71c8b8c71f05933f1b744cb79d2513c2f4..0b84707eaff2932576849666b946ece41b3aaa62 100644 (file)
@@ -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:
index 4908ca6e4e77912358b30e5837a84ea29a0c7a29..b3d16ed203fe34489325f8d5da0cb6f79d84a19f 100644 (file)
@@ -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
index 7aaa99fabdb320ad60391a7cd10f52fabe775b09..a6f277863e3cbde0c0f569cbf99b3c479ff726c6 100644 (file)
@@ -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 */