aboutsummaryrefslogtreecommitdiff
path: root/stdio-common
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@redhat.com>2025-03-28 12:35:53 +0000
committerMaciej W. Rozycki <macro@redhat.com>2025-03-28 12:35:53 +0000
commita26638424ffea604f7ef94d0c6f3940304698442 (patch)
tree15227c00e317926271b1b00a8a2e9e14a262317e /stdio-common
parent47076b3163ce645f791d5c8f80080e9811733347 (diff)
downloadglibc-a26638424ffea604f7ef94d0c6f3940304698442.tar.xz
glibc-a26638424ffea604f7ef94d0c6f3940304698442.zip
stdio-common: Also reject exp char w/o significand in i18n scanf [BZ #13988]
Fix the handling of real 'scanf' input such as "+.e" as per BZ #13988 for the i18n case as well, complementing commit 6ecec3b616ae ("Don't accept exp char without preceding digits in scanf float parsing"), where the 'e' character is incorrectly consumed from input. Add a test case matching stdio-common/bug26.c, with bits from localedata/tst-sscanf.c. Reviewed-by: Joseph Myers <josmyers@redhat.com>
Diffstat (limited to 'stdio-common')
-rw-r--r--stdio-common/vfscanf-internal.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c
index 87f23b5845..6817fc1542 100644
--- a/stdio-common/vfscanf-internal.c
+++ b/stdio-common/vfscanf-internal.c
@@ -2409,7 +2409,7 @@ digits_extended_fail:
if (got_e && charbuf.current[-1] == exp_char
&& (c == L_('-') || c == L_('+')))
char_buffer_add (&charbuf, c);
- else if (char_buffer_size (&charbuf) > got_sign && !got_e
+ else if (got_digit && !got_e
&& (CHAR_T) TOLOWER (c) == exp_char)
{
char_buffer_add (&charbuf, exp_char);
@@ -2426,7 +2426,10 @@ digits_extended_fail:
if (c == wcdigits[n])
{
if (n < 10)
- char_buffer_add (&charbuf, L_('0') + n);
+ {
+ char_buffer_add (&charbuf, L_('0') + n);
+ got_digit = 1;
+ }
else if (n == 11 && !got_dot)
{
char_buffer_add (&charbuf, decimal);
@@ -2461,7 +2464,10 @@ digits_extended_fail:
width = avail;
if (n < 10)
- char_buffer_add (&charbuf, L_('0') + n);
+ {
+ char_buffer_add (&charbuf, L_('0') + n);
+ got_digit = 1;
+ }
else if (n == 11 && !got_dot)
{
/* Add all the characters. */