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 <sean...@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,
-- 
2.32.0

Reply via email to