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.e3c3d6761b
was the first attempt, but even with this change,e3c3d6761b
still makes sense.
This commit is contained in:
parent
27fe58b77b
commit
e2093454a2
|
@ -46,7 +46,7 @@
|
||||||
#define POSSIBLE_SPECIFIERS ALPHANUMERICAL "%"
|
#define POSSIBLE_SPECIFIERS ALPHANUMERICAL "%"
|
||||||
|
|
||||||
int specifier_printf(const char *text, const Specifier table[], void *userdata, char **_ret) {
|
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;
|
_cleanup_free_ char *ret = NULL;
|
||||||
char *t;
|
char *t;
|
||||||
const char *f;
|
const char *f;
|
||||||
|
@ -57,14 +57,11 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
|
||||||
assert(table);
|
assert(table);
|
||||||
|
|
||||||
l = strlen(text);
|
l = strlen(text);
|
||||||
ret = new(char, l+1);
|
if (!GREEDY_REALLOC(ret, allocated, l + 1))
|
||||||
if (!ret)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
t = ret;
|
t = ret;
|
||||||
|
|
||||||
for (f = text; *f; f++, l--) {
|
for (f = text; *f; f++, l--)
|
||||||
|
|
||||||
if (percent) {
|
if (percent) {
|
||||||
if (*f == '%')
|
if (*f == '%')
|
||||||
*(t++) = '%';
|
*(t++) = '%';
|
||||||
|
@ -77,7 +74,6 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
|
||||||
|
|
||||||
if (i->lookup) {
|
if (i->lookup) {
|
||||||
_cleanup_free_ char *w = NULL;
|
_cleanup_free_ char *w = NULL;
|
||||||
char *n;
|
|
||||||
size_t k, j;
|
size_t k, j;
|
||||||
|
|
||||||
r = i->lookup(i->specifier, i->data, userdata, &w);
|
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;
|
j = t - ret;
|
||||||
k = strlen(w);
|
k = strlen(w);
|
||||||
|
|
||||||
n = new(char, j + k + l + 1);
|
if (!GREEDY_REALLOC(ret, allocated, j + k + l + 1))
|
||||||
if (!n)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
memcpy(ret + j, w, k);
|
||||||
memcpy(n, ret, j);
|
|
||||||
memcpy(n + j, w, k);
|
|
||||||
|
|
||||||
free_and_replace(ret, n);
|
|
||||||
t = ret + j + k;
|
t = ret + j + k;
|
||||||
} else if (strchr(POSSIBLE_SPECIFIERS, *f))
|
} else if (strchr(POSSIBLE_SPECIFIERS, *f))
|
||||||
/* Oops, an unknown specifier. */
|
/* Oops, an unknown specifier. */
|
||||||
|
@ -110,7 +101,6 @@ int specifier_printf(const char *text, const Specifier table[], void *userdata,
|
||||||
percent = true;
|
percent = true;
|
||||||
else
|
else
|
||||||
*(t++) = *f;
|
*(t++) = *f;
|
||||||
}
|
|
||||||
|
|
||||||
/* if string ended with a stray %, also end with % */
|
/* if string ended with a stray %, also end with % */
|
||||||
if (percent)
|
if (percent)
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue