[PATCH v2 5/7] trace2: remove use of xstrfmt()
- From
Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Aug 25, 2026, 18:56 UTC
- Message-ID
- <7f0bb405ad380fd35ae6381961ac667fd7e5dfd9.1787684181.git.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2178.v2.git.1787684181.gitgitgadget@gmail.com>
From: Derrick Stolee <stolee@gmail.com>
We continue removing the possibility of a die() in the trace2 API by banning xstrfmt(), which calls die() during a failure to format. Instead of allowing a die(), perform a soft failure by failing to output the trace2 data when such a failure occurs.
This requires carefully concatenating strings using memcpy() to construct redacted data to avoid copying password information in traced URLs.
Signed-off-by: Derrick Stolee <stolee@gmail.com> --- banned-die.h | 3 +++ trace2.c | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/banned-die.h b/banned-die.h index cb2eed75cd..14aecfdc7a 100644 --- a/banned-die.h +++ b/banned-die.h @@ -17,6 +17,9 @@ #undef xstrdup #define xstrdup(str) BANNED(xstrdup) +#undef xstrfmt +#define xstrfmt(...) BANNED(xstrfmt) + #undef ALLOC_ARRAY #define ALLOC_ARRAY(x, alloc) BANNED(ALLOC_ARRAY) diff --git a/trace2.c b/trace2.c index 7044276435..c37f783fa0 100644 --- a/trace2.c +++ b/trace2.c @@ -260,7 +260,10 @@ int trace2_is_enabled(void) static const char *redact_arg(const char *arg) { const char *p, *colon; + const char *redact = ":<REDACTED>"; + char *redacted; size_t at; + size_t prefix_len, suffix_len, redacted_len, redact_len; if (!trace2_redact || (!skip_prefix(arg, "https://", &p) && @@ -275,7 +278,25 @@ static const char *redact_arg(const char *arg) if (!colon) return arg; - return xstrfmt("%.*s:<REDACTED>%s", (int)(colon - arg), arg, p + at); + redact_len = strlen(redact); + prefix_len = colon - arg; + suffix_len = strlen(p + at); + + if (unsigned_add_overflows(prefix_len, suffix_len) || + unsigned_add_overflows(prefix_len + suffix_len, redact_len)) + return NULL; + + redacted_len = prefix_len + suffix_len + redact_len; + + redacted = malloc(redacted_len); + if (!redacted) + return NULL; + + memcpy(redacted, arg, prefix_len); + memcpy(redacted + prefix_len, redact, redact_len - 1); + memcpy(redacted + prefix_len + redact_len - 1, p + at, + suffix_len + 1); + return redacted; } /* @@ -300,6 +321,8 @@ static const char **redact_argv(const char **argv) if (!argv[i]) return argv; + if (!redacted) + return NULL; for (j = 0; argv[j]; j++) ; /* keep counting */ @@ -316,7 +339,14 @@ static const char **redact_argv(const char **argv) ret[i] = redacted; for (++i; argv[i]; i++) { redacted = redact_arg(argv[i]); - ret[i] = redacted ? redacted : argv[i]; + if (!redacted) { + for (j = 0; j < i; j++) + if (ret[j] != argv[j]) + free((void *)ret[j]); + free(ret); + return NULL; + } + ret[i] = redacted; } return ret;
-- gitgitgadget