git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v6 08/18] reftable/basics: stop using `st_mult()` in array allocators

From
Patrick Steinhardt <ps@pks.im>
Date
Feb 18, 2025, 09:20 UTC
Message-ID
<20250218-pks-reftable-drop-git-compat-util-v6-8-8c1f39fb4c02@pks.im>
In-Reply-To
<20250218-pks-reftable-drop-git-compat-util-v6-0-8c1f39fb4c02@pks.im>

We're using `st_mult()` as part of our macro helpers that allocate arrays. This is bad due two two reasons:

  - `st_mult()` causes us to die in case the multiplication overflows.
  - `st_mult()` ties us to the Git codebase.

Refactor the code to instead detect overflows manually and return an error in such cases.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 reftable/basics.h | 36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/reftable/basics.h b/reftable/basics.h
index a2a010a0e19..646f8d67f2d 100644
--- a/reftable/basics.h
+++ b/reftable/basics.h
@@ -117,18 +117,46 @@ void reftable_free(void *p);
 void *reftable_calloc(size_t nelem, size_t elsize);
 char *reftable_strdup(const char *str);
 
-#define REFTABLE_ALLOC_ARRAY(x, alloc) (x) = reftable_malloc(st_mult(sizeof(*(x)), (alloc)))
+static inline int reftable_alloc_size(size_t nelem, size_t elsize, size_t *out)
+{
+	if (nelem && elsize > SIZE_MAX / nelem)
+		return -1;
+	*out = nelem * elsize;
+	return 0;
+}
+
+#define REFTABLE_ALLOC_ARRAY(x, alloc) do { \
+		size_t alloc_size; \
+		if (reftable_alloc_size(sizeof(*(x)), (alloc), &alloc_size) < 0) { \
+			errno = ENOMEM; \
+			(x) = NULL; \
+		} else { \
+			(x) = reftable_malloc(alloc_size); \
+		} \
+	} while (0)
 #define REFTABLE_CALLOC_ARRAY(x, alloc) (x) = reftable_calloc((alloc), sizeof(*(x)))
-#define REFTABLE_REALLOC_ARRAY(x, alloc) (x) = reftable_realloc((x), st_mult(sizeof(*(x)), (alloc)))
+#define REFTABLE_REALLOC_ARRAY(x, alloc) do { \
+		size_t alloc_size; \
+		if (reftable_alloc_size(sizeof(*(x)), (alloc), &alloc_size) < 0) { \
+			errno = ENOMEM; \
+			(x) = NULL; \
+		} else { \
+			(x) = reftable_realloc((x), alloc_size); \
+		} \
+	} while (0)
 
 static inline void *reftable_alloc_grow(void *p, size_t nelem, size_t elsize,
 					size_t *allocp)
 {
 	void *new_p;
-	size_t alloc = *allocp * 2 + 1;
+	size_t alloc = *allocp * 2 + 1, alloc_bytes;
 	if (alloc < nelem)
 		alloc = nelem;
-	new_p = reftable_realloc(p, st_mult(elsize, alloc));
+	if (reftable_alloc_size(elsize, alloc, &alloc_bytes) < 0) {
+		errno = ENOMEM;
+		return p;
+	}
+	new_p = reftable_realloc(p, alloc_bytes);
 	if (!new_p)
 		return p;
 	*allocp = alloc;
-- 
2.48.1.666.gff9fcf71b7.dirty
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 8 of 23 in “reftable: stop using "git-compat-util.h"”
  1. 00/18 reftable: stop using "git-compat-util.h"Patrick Steinhardt, Feb 18, 2025
  2. 01/18 reftable/stack: stop using `read_in_full()`Patrick Steinhardt, Feb 18, 2025
  3. 02/18 reftable/stack: stop using `write_in_full()`Patrick Steinhardt, Feb 18, 2025
  4. 03/18 reftable/blocksource: stop using `xmmap()`Patrick Steinhardt, Feb 18, 2025
  5. 04/18 reftable/record: stop using `COPY_ARRAY()`Patrick Steinhardt, Feb 18, 2025
  6. 05/18 reftable/record: stop using `BUG()` in `reftable_record_init()`Patrick Steinhardt, Feb 18, 2025
  7. 06/18 reftable/record: don't `BUG()` in `reftable_record_cmp()`Patrick Steinhardt, Feb 18, 2025
  8. 08/18 reftable/basics: stop using `st_mult()` in array allocatorsPatrick Steinhardt, Feb 18, 2025
  9. 07/18 reftable: stop using `BUG()` in trivial casesPatrick Steinhardt, Feb 18, 2025
  10. 10/18 reftable/reader: stop using `ARRAY_SIZE()` macroPatrick Steinhardt, Feb 18, 2025
  11. 09/18 reftable/basics: provide wrappers for big endian conversionPatrick Steinhardt, Feb 18, 2025
  12. 11/18 reftable/system: introduce `reftable_rand()`Patrick Steinhardt, Feb 18, 2025
  13. 12/18 reftable/stack: stop using `sleep_millisec()`Patrick Steinhardt, Feb 18, 2025
  14. 13/18 reftable/basics: stop using `SWAP()` macroPatrick Steinhardt, Feb 18, 2025
  15. 14/18 reftable/basics: introduce `REFTABLE_UNUSED` annotationPatrick Steinhardt, Feb 18, 2025
  16. 15/18 compat/mingw: split out POSIX-related bitsPatrick Steinhardt, Feb 18, 2025
  17. 16/18 git-compat-util.h: split out POSIX-emulating bitsPatrick Steinhardt, Feb 18, 2025
  18. 17/18 reftable: decouple from Git codebase by pulling in "compat/posix.h"Patrick Steinhardt, Feb 18, 2025
  19. 18/18 Makefile: skip reftable library for CoccinellePatrick Steinhardt, Feb 18, 2025
  20. Junio C HamanoFeb 18, 2025
  21. Junio C HamanoMar 11, 2025
  22. Patrick SteinhardtMar 12, 2025
  23. Patrick SteinhardtMar 20, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.