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

Sean Anderson seanga2 at gmail.com
Thu Jul 1 08:16:06 CEST 2021


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 at 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



More information about the U-Boot mailing list