|
Message-Id: <56fd8b39c3f13e77682d17b749e6bc50d104e8e0.1685536319.git.Jens.Gustedt@inria.fr> Date: Wed, 31 May 2023 16:05:41 +0200 From: Jens Gustedt <Jens.Gustedt@...ia.fr> To: musl@...ts.openwall.com Subject: [C23 scanf 1/3] C23: Add the b specifier for scanf and allow 0b and 0B prefixes in integers This affects all functions that read integers from strings or streams such as scanf and strtoX. This patch changes the behavior deep down inside, namely the __intscan function. This is a semantic change. Parsing of integers that use base 0 (for the strtoX functions) or the "i" specifier (for scanf) may observe different behavior when linked (statically or dynamically) against this new version. The C committtee did explicitly reject concerns about this incompatibility, judging it as being only a minor risk. --- src/internal/intscan.c | 13 +++++++++++-- src/stdio/vfscanf.c | 5 ++++- src/stdio/vfwscanf.c | 4 ++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/internal/intscan.c b/src/internal/intscan.c index a4a5ae86..57424554 100644 --- a/src/internal/intscan.c +++ b/src/internal/intscan.c @@ -38,9 +38,9 @@ unsigned long long __intscan(FILE *f, unsigned base, int pok, unsigned long long neg = -(c=='-'); c = shgetc(f); } - if ((base == 0 || base == 16) && c=='0') { + if ((base == 0 || base == 2 || base == 16) && c=='0') { c = shgetc(f); - if ((c|32)=='x') { + if ((c|32)=='x' && base != 2) { c = shgetc(f); if (val[c]>=16) { shunget(f); @@ -49,6 +49,15 @@ unsigned long long __intscan(FILE *f, unsigned base, int pok, unsigned long long return 0; } base = 16; + } else if ((c|32)=='b' && base != 16) { + c = shgetc(f); + if (val[c]>=2) { + shunget(f); + if (pok) shunget(f); + else shlim(f, 0); + return 0; + } + base = 2; } else if (base == 0) { base = 8; } diff --git a/src/stdio/vfscanf.c b/src/stdio/vfscanf.c index b78a374d..f72ac9c9 100644 --- a/src/stdio/vfscanf.c +++ b/src/stdio/vfscanf.c @@ -150,7 +150,7 @@ int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap) case 'L': size = SIZE_L; break; - case 'd': case 'i': case 'o': case 'u': case 'x': + case 'b': case 'd': case 'i': case 'o': case 'u': case 'x': case 'a': case 'e': case 'f': case 'g': case 'A': case 'E': case 'F': case 'G': case 'X': case 's': case 'c': case '[': @@ -286,6 +286,9 @@ int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap) case 'o': base = 8; goto int_common; + case 'b': + base = 2; + goto int_common; case 'd': case 'u': base = 10; diff --git a/src/stdio/vfwscanf.c b/src/stdio/vfwscanf.c index 82f48604..17f5a2f9 100644 --- a/src/stdio/vfwscanf.c +++ b/src/stdio/vfwscanf.c @@ -173,7 +173,7 @@ int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap) case 'L': size = SIZE_L; break; - case 'd': case 'i': case 'o': case 'u': case 'x': + case 'b': case 'd': case 'i': case 'o': case 'u': case 'x': case 'a': case 'e': case 'f': case 'g': case 'A': case 'E': case 'F': case 'G': case 'X': case 's': case 'c': case '[': @@ -294,7 +294,7 @@ int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap) } break; - case 'd': case 'i': case 'o': case 'u': case 'x': + case 'b': case 'd': case 'i': case 'o': case 'u': case 'x': case 'a': case 'e': case 'f': case 'g': case 'A': case 'E': case 'F': case 'G': case 'X': case 'p': -- 2.34.1
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.