[RFC PATCH 23/28] cli: lil: Handle OOM for hm_put

Sean Anderson
2021-07-01T06:20:34Z

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,
--
2.32.0