From 14fc4a06a6c5e986ea630911d7bea553e104b037 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 18 Jun 2026 11:54:37 +0000 Subject: [PATCH] Unescape arguments before passing to format_expand1 so that escaping :s etc actually works. --- format.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/format.c b/format.c index 8972d7d2..0bd8f58c 100644 --- a/format.c +++ b/format.c @@ -4240,22 +4240,24 @@ format_check_time(struct format_expand_state *es, u_int *check) /* Unescape escaped characters. */ static char * -format_unescape(struct format_expand_state *es, const char *s) +format_unescape(struct format_expand_state *es, const char *s, size_t n) { - char *out, *cp; - int brackets = 0; - u_int check = 0; + const char *end = s + n; + char *out, *cp; + int brackets = 0; + u_int check = 0; - cp = out = xmalloc(strlen(s) + 1); - for (; *s != '\0'; s++) { + cp = out = xmalloc(n + 1); + for (; s != end; s++) { if (!format_check_time(es, &check)) { free(out); return (xstrdup("")); } - if (*s == '#' && s[1] == '{') + if (*s == '#' && s + 1 != end && s[1] == '{') brackets++; if (brackets == 0 && *s == '#' && + s + 1 != end && strchr(",#{}:", s[1]) != NULL) { *cp++ = *++s; continue; @@ -4476,7 +4478,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s, break; argv = xcalloc(1, sizeof *argv); - value = xstrndup(cp + 1, end - (cp + 1)); + value = format_unescape(es, cp + 1, end - (cp + 1)); argv[0] = format_expand1(es, value); free(value); argc = 1; @@ -4500,7 +4502,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s, cp++; argv = xreallocarray(argv, argc + 1, sizeof *argv); - value = xstrndup(cp, end - cp); + value = format_unescape(es, cp, end - cp); argv[argc++] = format_expand1(es, value); free(value); @@ -5368,7 +5370,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen, /* Is this a literal string? */ if (modifiers & FORMAT_LITERAL) { format_log(es, "literal string is '%s'", copy); - value = format_unescape(es, copy); + value = format_unescape(es, copy, strlen(copy)); goto done; }