summaryrefslogtreecommitdiffstats
path: root/Src
diff options
context:
space:
mode:
authordana <dana@dana.is>2026-05-18 04:06:17 -0500
committerdana <dana@dana.is>2026-05-21 14:25:56 -0500
commita04c944804642aa083d46ce5dae2356d3c8fcc0c (patch)
tree9db2bfc6603b6d02d22738c29f46a35b7d427f56 /Src
parent54579: docs: clarify zformat -F ternary behaviour (diff)
downloadzsh-a04c944804642aa083d46ce5dae2356d3c8fcc0c.tar
zsh-a04c944804642aa083d46ce5dae2356d3c8fcc0c.tar.gz
zsh-a04c944804642aa083d46ce5dae2356d3c8fcc0c.tar.bz2
zsh-a04c944804642aa083d46ce5dae2356d3c8fcc0c.tar.lz
zsh-a04c944804642aa083d46ce5dae2356d3c8fcc0c.tar.xz
zsh-a04c944804642aa083d46ce5dae2356d3c8fcc0c.tar.zst
zsh-a04c944804642aa083d46ce5dae2356d3c8fcc0c.zip
54580: zformat: better handle literal % in format string
Diffstat (limited to 'Src')
-rw-r--r--Src/Modules/zutil.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index e50f68ece..53b3abe72 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -844,6 +844,14 @@ static char *zformat_substring(char* instr, char **specs, char **outp,
} else if (*s == '.' || testit)
s++;
+ // next char isn't a legal spec char -- unwind, treat the sequence
+ // literally
+ if (!testit && (!*s || *s == '%' || *s == ')' || *s == '-' || *s == '.')) {
+ // but swallow the % if this is %% or %)
+ start += (s - start == 1 && (*s == '%' || *s == ')'));
+ s = start;
+ }
+
if (testit && (unsigned char) *s) {
int actval, testval, endcharl;
@@ -972,15 +980,12 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
char **ap, *specs[256] = {0}, *out;
int olen, oused = 0;
- specs['%'] = "%";
- specs[')'] = ")";
-
/* Parse the specs in argv. */
for (ap = args + 2; *ap; ap++) {
if (!ap[0][0] || ap[0][0] == '-' || ap[0][0] == '.' ||
ap[0][0] == '%' || ap[0][0] == ')' ||
idigit(ap[0][0]) || ap[0][1] != ':') {
- zwarnnam(nam, "invalid argument: %s", *ap);
+ zwarnnam(nam, "invalid spec: %s", *ap);
return 1;
}
specs[(unsigned char) ap[0][0]] = ap[0] + 2;
@@ -989,7 +994,7 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
if (!zformat_substring(args[1], specs, &out, &oused, &olen, '\0',
presence, 0)) {
- zwarnnam(nam, "malformed format string");
+ zwarnnam(nam, "malformed format string: %s", args[1]);
return 1;
}
out[oused] = '\0';