-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
+/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
/***
#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
+#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n)))
+
#define malloc0(n) (calloc(1, (n)))
static inline void *mfree(void *memory) {
return NULL;
}
+#define free_and_replace(a, b) \
+ ({ \
+ free(a); \
+ (a) = (b); \
+ (b) = NULL; \
+ 0; \
+ })
+
void* memdup(const void *p, size_t l) _alloc_(2);
+void* memdup_suffix0(const void*p, size_t l) _alloc_(2);
static inline void freep(void *p) {
free(*(void**) p);
#define _cleanup_free_ _cleanup_(freep)
-_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
- if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+static inline bool size_multiply_overflow(size_t size, size_t need) {
+ return _unlikely_(need != 0 && size > (SIZE_MAX / need));
+}
+
+_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) {
+ if (size_multiply_overflow(size, need))
+ return NULL;
+
+ return malloc(size * need);
+}
+
+_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t size, size_t need) {
+ if (size_multiply_overflow(size, need))
return NULL;
- return malloc(a * b);
+ return realloc(p, size * need);
}
-_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
- if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) {
+ if (size_multiply_overflow(size, need))
return NULL;
- return realloc(p, a * b);
+ return memdup(p, size * need);
}
-_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
- if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+_alloc_(2, 3) static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) {
+ if (size_multiply_overflow(size, need))
return NULL;
- return memdup(p, a * b);
+ return memdup_suffix0(p, size * need);
}
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);