
hm_put allocates memory, and this can fail. Instead of failing silently, return an error code. This also fixes up callers to handle this error.
Signed-off-by: Sean Anderson seanga2@gmail.com ---
common/cli_lil.c | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-)
diff --git a/common/cli_lil.c b/common/cli_lil.c index 2ed96ebc2d..7ec73675f3 100644 --- a/common/cli_lil.c +++ b/common/cli_lil.c @@ -326,22 +326,30 @@ static void hm_destroy(struct hashmap *hm) } }
-static void hm_put(struct hashmap *hm, const char *key, void *value) +static enum lil_error hm_put(struct hashmap *hm, const char *key, void *value) { struct hashcell *cell = hm->cell + (hm_hash(key) & HASHMAP_CELLMASK); + struct hashentry *newe; size_t i;
for (i = 0; i < cell->c; i++) { if (!strcmp(key, cell->e[i].k)) { cell->e[i].v = value; - return; + return LIL_ERR_NONE; } }
- cell->e = realloc(cell->e, sizeof(struct hashentry) * (cell->c + 1)); - cell->e[cell->c].k = strdup(key); - cell->e[cell->c].v = value; + newe = realloc(cell->e, sizeof(struct hashentry) * (cell->c + 1)); + if (!newe) + return LIL_ERR_OOM; + cell->e = newe; + + newe[cell->c].k = strdup(key); + if (!newe[cell->c].k) + return LIL_ERR_OOM; + newe[cell->c].v = value; cell->c++; + return LIL_ERR_NONE; }
static void *hm_get(struct hashmap *hm, const char *key) @@ -738,19 +746,24 @@ static struct lil_func *add_func(struct lil *lil, const char *name)
cmd = calloc(1, sizeof(struct lil_func)); if (!cmd) - return NULL; + goto oom; cmd->name = strdup(name);
ncmd = realloc(lil->cmd, sizeof(struct lil_func *) * (lil->cmds + 1)); - if (!ncmd) { - free(cmd); - return NULL; - } - + if (!ncmd) + goto oom; lil->cmd = ncmd; + ncmd[lil->cmds++] = cmd; - hm_put(&lil->cmdmap, name, cmd); + if (hm_put(&lil->cmdmap, name, cmd)) + goto oom; + return cmd; + +oom: + free(cmd); + lil_set_error_oom(lil); + return NULL; }
static void del_func(struct lil *lil, struct lil_func *cmd) @@ -766,7 +779,11 @@ static void del_func(struct lil *lil, struct lil_func *cmd) if (index == lil->cmds) return;
- hm_put(&lil->cmdmap, cmd->name, 0); + /* + * The only way this fails is if we don't find the command; this + * means our caller wants to delete a command which doesn't exist + */ + assert(!hm_put(&lil->cmdmap, cmd->name, NULL)); if (cmd->argnames) lil_free_list(cmd->argnames);
@@ -783,9 +800,9 @@ int lil_register(struct lil *lil, const char *name, lil_func_proc_t proc) struct lil_func *cmd = add_func(lil, name);
if (!cmd) - return 0; + return LIL_ERR_OOM; cmd->proc = proc; - return 1; + return LIL_ERR_NONE; }
struct lil_var *lil_set_var(struct lil *lil, const char *name,