[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] printf width/precision argument overflow
From: |
Grisha Levit |
Subject: |
[PATCH] printf width/precision argument overflow |
Date: |
Thu, 19 Oct 2023 23:45:31 -0400 |
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
- [PATCH] printf width/precision argument overflow,
Grisha Levit <=