From 623153e744eacd89eb58652b93d1645188496e3f Mon Sep 17 00:00:00 2001
From: Philipp Takacs <philipp@bureaucracy.de>
Date: Sat, 21 Mar 2026 14:33:51 +0100
Subject: [PATCH 3/6] Revert "reuse strings in struct request"

This reverts commit a384b16ca28c351855b6c149c64bae34cf6f7e7c.

This commit had two problems:

1. it removed the \0 termination

This cause read overrun in the ldap implementation.

2. The accual members where shared between the request in the api
and the request owned by the async backend. Which caused a use after
free.
---
 table_api.c | 49 ++++++++++++-------------------------------------
 table_api.h |  3 ---
 2 files changed, 12 insertions(+), 40 deletions(-)

diff --git a/table_api.c b/table_api.c
index 6d0a20c..bf6b8fb 100644
--- a/table_api.c
+++ b/table_api.c
@@ -465,13 +465,7 @@ table_api_parse_line(char *line, size_t linelen, struct request *req)
 		return false;
 	}
 	*t++ = '\0';
-	if (t - tname - 1 > (ptrdiff_t)req->tablesize) {
-		req->table = realloc(req->table, t - tname - 1);
-		req->tablesize = t - tname - 1;
-		if (!req->table)
-			fatal("realloc");
-	}
-	memcpy(req->table, tname, req->tablesize);
+	req->table = strdup(tname);
 
 	type = t;
 	if ((t = strchr(t, '|')) == NULL) {
@@ -481,13 +475,7 @@ table_api_parse_line(char *line, size_t linelen, struct request *req)
 	*t++ = '\0';
 
 	if (!strcmp(type, "update")) {
-		if (line + linelen - t > (ptrdiff_t)req->idsize) {
-			req->id = realloc(req->id, line + linelen - t);
-			req->idsize = line + linelen - t;
-			if (!req->id)
-				fatal("realloc");
-		}
-		memcpy(req->id, t, line + linelen - t);
+		req->id = strdup(t);
 		req->o = O_UPDATE;
 		return true;
 	}
@@ -503,13 +491,7 @@ table_api_parse_line(char *line, size_t linelen, struct request *req)
 	id = t;
 
 	if (!strcmp(type, "fetch")) {
-		if (line + linelen - id > (ptrdiff_t)req->idsize) {
-			req->id = realloc(req->id, line + linelen - id);
-			req->idsize = line + linelen - id;
-			if (!req->id)
-				fatal("realloc");
-		}
-		memcpy(req->id, id, line + linelen - id);
+		req->id = strdup(id);
 		req->o = O_FETCH;
 		req->s = sid;
 		req->key = NULL;
@@ -521,30 +503,19 @@ table_api_parse_line(char *line, size_t linelen, struct request *req)
 		return false;
 	}
 	*t++ = '\0';
-	if (t - id - 1 > (ptrdiff_t)req->idsize) {
-		req->id = realloc(req->id, t - id - 1);
-		req->idsize = t - id - 1;
-		if (!req->id)
-			fatal("realloc");
-	}
-	memcpy(req->id, id, t - id - 1);
-
 	key = t;
-	if (line + linelen - key > (ptrdiff_t)req->keysize) {
-		req->key = realloc(req->key, line + linelen - key);
-		req->keysize = line + linelen - key;
-		if (!req->key)
-			fatal("realloc");
-	}
-	memcpy(req->key, key, line + linelen - key);
 
 	if (!strcmp(type, "check")) {
+		req->id = strdup(id);
 		req->o = O_CHECK;
 		req->s = sid;
+		req->key = strdup(key);
 		return true;
 	} else if (!strcmp(type, "lookup")) {
+		req->id = strdup(id);
 		req->o = O_LOOKUP;
 		req->s = sid;
+		req->key = strdup(key);
 		return true;
 	} else {
 		log_warnx("unknown action %s", type);
@@ -602,6 +573,7 @@ do_callback(struct request *req)
 		return;
 	}
 	*r = *req;
+	*req = (struct request){};
 	handler_async(r);
 }
 
@@ -613,7 +585,7 @@ api_callback(int fd, short revents)
 	size_t		 linelen;
 	int		 serrno, ret;
 	char		*line, *t;
-	struct request	 req = {0};
+	struct request	req;
 
 	if (revents & (POLLERR|POLLNVAL)) {
 		exit(1);
@@ -647,6 +619,9 @@ api_callback(int fd, short revents)
 				errx(1, "can not parse input line: %s", line);
 			}
 			do_callback(&req);
+			free(req.id);
+			free(req.table);
+			free(req.key);
 			free(line);
 			continue;
 		}
diff --git a/table_api.h b/table_api.h
index 8fb94ab..15dcd0b 100644
--- a/table_api.h
+++ b/table_api.h
@@ -45,13 +45,10 @@ enum table_service {
 
 struct request {
 	char	*id;
-	size_t	 idsize;
 	enum	 table_operation o;
 	char	*table;
-	size_t	 tablesize;
 	enum	 table_service s;
 	char	*key;
-	size_t	 keysize;
 };
 
 bool		 table_api_parse_line(char *line, size_t linelen, struct request *req);
-- 
2.52.0

