summaryrefslogtreecommitdiff
path: root/src/shared/specifier.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-03-28 10:15:44 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-03-28 10:38:45 +0200
commite2093454a248ff7d879077a77f4e9a086439d353 (patch)
treea79dd8e551da243f8d37a32ac5f0f50426406729 /src/shared/specifier.c
parent27fe58b77b5ed322971c7d2ea17ead1518652919 (diff)
downloadsystemd-e2093454a248ff7d879077a77f4e9a086439d353.tar.gz
shared/specifier: be less extravagant with memory allocations
ubsan times out because we do too many allocations: $ valgrind build/fuzz-unit-file test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-full ... test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-full... ok ==1757== ==1757== HEAP SUMMARY: ==1757== in use at exit: 0 bytes in 0 blocks ==1757== total heap usage: 199,997 allocs, 199,997 frees, 90,045,318,585 bytes allocated ... ==3256== total heap usage: 100,120 allocs, 100,120 frees, 13,097,140 bytes allocated https://oss-fuzz.com/v2/issue/4651449704251392/6977 should now be really fixed. e3c3d6761b3e7d was the first attempt, but even with this change, e3c3d6761b3e7d still makes sense.
Diffstat (limited to 'src/shared/specifier.c')
-rw-r--r--src/shared/specifier.c20
1 files changed, 5 insertions, 15 deletions
diff --git a/src/shared/specifier.c b/src/shared/specifier.c
index 98d95eef8e..c4a3ffd18c 100644
--- a/src/shared/specifier.c
+++ b/src/shared/specifier.c
@@ -46,7 +46,7 @@
#define POSSIBLE_SPECIFIERS ALPHANUMERICAL "%"
int specifier_printf(const char *text, const Specifier table[], void *userdata, char **_ret) {
- size_t l;
+ size_t l, allocated = 0;
_cleanup_free_ char *ret = NULL;
char *t;
const char *f;
@@ -57,14 +57,11 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
assert(table);
l = strlen(text);
- ret = new(char, l+1);
- if (!ret)
+ if (!GREEDY_REALLOC(ret, allocated, l + 1))
return -ENOMEM;
-
t = ret;
- for (f = text; *f; f++, l--) {
-
+ for (f = text; *f; f++, l--)
if (percent) {
if (*f == '%')
*(t++) = '%';
@@ -77,7 +74,6 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
if (i->lookup) {
_cleanup_free_ char *w = NULL;
- char *n;
size_t k, j;
r = i->lookup(i->specifier, i->data, userdata, &w);
@@ -87,14 +83,9 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
j = t - ret;
k = strlen(w);
- n = new(char, j + k + l + 1);
- if (!n)
+ if (!GREEDY_REALLOC(ret, allocated, j + k + l + 1))
return -ENOMEM;
-
- memcpy(n, ret, j);
- memcpy(n + j, w, k);
-
- free_and_replace(ret, n);
+ memcpy(ret + j, w, k);
t = ret + j + k;
} else if (strchr(POSSIBLE_SPECIFIERS, *f))
/* Oops, an unknown specifier. */
@@ -110,7 +101,6 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
percent = true;
else
*(t++) = *f;
- }
/* if string ended with a stray %, also end with % */
if (percent)