When reading a printf width/precision argument, the value isn't checked for overflow if it happens to be the last argument:
$ INT_MAX=$(getconf INT_MAX) $ printf '[%*s]' "$((INT_MAX+1))" [] $ printf '[%*s]' "$((INT_MAX+1))" X -bash: printf: X: Result too large [] ..and the following argument is used in the error message if it exists. --- builtins/printf.def | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/builtins/printf.def b/builtins/printf.def index 6d3fd9a4..5030b788 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -1343,13 +1343,27 @@ static int getint (void) { intmax_t ret; - - ret = getintmax (); + char *ep; if (garglist == 0) - return ret; + return (0); + + if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') + return asciicode (); - if (ret > INT_MAX) + errno = 0; + ret = strtoimax (garglist->word->word, &ep, 0); + + if (*ep) + { + sh_invalidnum (garglist->word->word); + conversion_error = 1; + } + else if (errno == ERANGE) + { + printf_erange (garglist->word->word); + } + else if (ret > INT_MAX) { printf_erange (garglist->word->word); ret = INT_MAX; @@ -1360,6 +1374,7 @@ getint (void) ret = INT_MIN; } + garglist = garglist->next; return ((int)ret); } -- 2.42.0