Skip to content

Commit 8f2904f

Browse files
committed
Improved containers handling of autofree items
* zhash duplicates item value if container has autofree set * zlist duplicates item if container has autofree set This is to get around anti-pattern where caller is responsible for strdup, and forgetting it causes a double-free. It's easier to detect a dangling allocation than a double-free.
1 parent 8f8528a commit 8f2904f

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/zhash.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ zhash_insert (zhash_t *self, const char *key, void *value)
246246
self->items = new_items;
247247
self->limit = new_limit;
248248
}
249+
// If necessary, take duplicate of item (string) value
250+
if (self->autofree)
251+
value = strdup ((char *) value);
252+
249253
return s_item_insert (self, key, value)? 0: -1;
250254
}
251255

@@ -268,6 +272,10 @@ zhash_update (zhash_t *self, const char *key, void *value)
268272
else
269273
if (self->autofree)
270274
free (item->value);
275+
276+
// If necessary, take duplicate of item (string) value
277+
if (self->autofree)
278+
value = strdup ((char *) value);
271279
item->value = value;
272280
}
273281
else
@@ -389,7 +397,7 @@ zhash_dup (zhash_t *self)
389397
for (index = 0; index != self->limit; index++) {
390398
item_t *item = self->items [index];
391399
while (item) {
392-
zhash_insert (copy, item->key, strdup (item->value));
400+
zhash_insert (copy, item->key, item->value);
393401
item = item->next;
394402
}
395403
}
@@ -412,7 +420,7 @@ zhash_keys (zhash_t *self)
412420
for (index = 0; index != self->limit; index++) {
413421
item_t *item = self->items [index];
414422
while (item) {
415-
zlist_append (keys, strdup (item->key));
423+
zlist_append (keys, item->key);
416424
item = item->next;
417425
}
418426
}
@@ -498,7 +506,7 @@ zhash_load (zhash_t *self, char *filename)
498506
if (!equals)
499507
break; // Some error, stop parsing it
500508
*equals++ = 0;
501-
zhash_update (self, buffer, strdup (equals));
509+
zhash_update (self, buffer, equals);
502510
}
503511
fclose (handle);
504512
return 0;

src/zlist.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ zlist_append (zlist_t *self, void *item)
177177
if (!node)
178178
return -1;
179179

180+
// If necessary, take duplicate of (string) item
181+
if (self->autofree)
182+
item = strdup ((char *) item);
183+
180184
node->item = item;
181185
if (self->tail)
182186
self->tail->next = node;
@@ -202,6 +206,10 @@ zlist_push (zlist_t *self, void *item)
202206
if (!node)
203207
return -1;
204208

209+
// If necessary, take duplicate of (string) item
210+
if (self->autofree)
211+
item = strdup ((char *) item);
212+
205213
node->item = item;
206214
node->next = self->head;
207215
self->head = node;

0 commit comments

Comments
 (0)