Created attachment 14838 [details] proposed fix In the functions strtol/strtoul/strtoll/strtoull, support for binary constants (such as 0b100111), as specified in ISO C 2x, was added in glibc commit 64924422a99690d147a166b4de3103f3bf3eaf6c, on 2023-02-17. But it is incomplete: The special input string "0b" with no binary digits is not handled. Here's a test case: ==================== tst-strtol-binary-no-digits.c ==================== #include <assert.h> #include <errno.h> #include <stdlib.h> int main () { { const char input[] = "0b"; char *ptr; long result; errno = 0; result = strtol (input, &ptr, 2); assert (result == 0L); assert (ptr == input + 1); assert (errno == 0); } { const char input[] = "0b"; char *ptr; long result; errno = 0; result = strtol (input, &ptr, 0); assert (result == 0L); assert (ptr == input + 1); assert (errno == 0); } } ======================================================================= Find attached a correction for this. I have tested it in Gnulib (which has very similar source code as glibc for this functionality), not in Glibc directly. I previously reported this to libc-alpha at https://sourceware.org/pipermail/libc-alpha/2023-March/146367.html but I now realize that this was not the proper reporting channel. Sorry about that.
Note that C2X has not yet decided what to do about strto*l parsing with a binary prefix. Consider: strtoul("0b1", &end, 2); In C17, this is required to return 0 and set end to "b1"; if C2X adds binary parsing, it would be required to return 1 and set end to "". This is a SILENT change in runtime behavior, based on which version of the standard you build against. https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3072.htm#there-are-semantic-changes-and-inconsistencies-for-strtol-scanf-and-similar-functions The final version of C2X may state something different than in the draft, and glibc may have to course-correct yet again.
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3108.doc merely says: FR-228 7.24.1, 7.31.4.1, K.3.5.3 and K.3.9.1 te There are semantic changes and inconsistencies for strtol, scanf and similar functions see accompanying document Rejected (no consensus to make this change) with comment: several vendor solutions were discussed. so as recently as Feb 2023, the C working group still hasn't made up their mind.
(In reply to Eric Blake from comment #1) > Note that C2X has not yet decided what to do about strto*l parsing with a > binary prefix. ... This is a > SILENT change in runtime behavior, based on which version of the standard > you build against. Yes, but the fact that it's a change in runtime behaviour is handled by the introduction of __isoc23_strto*, __isoc23_wcsto* in Joseph Myers' patch https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=64924422a99690d147a166b4de3103f3bf3eaf6c . If "Rejected" (as in comment #2) means that the final ISO C 23 will have the same wording as https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3088.pdf (the latest draft from 2023-01-24), then the wording there (ยง 7.24.1.7, page 358 = 377/757) means that when parsing the input string "0b", only one character shall be consumed, like for the input string "0x". That is what this BZ and its proposed patch are about. > The final version of C2X may state something different than in the draft, > and glibc may have to course-correct yet again. True. But it's very unlikely that the final version of C2X will specify that in when parsing "0b" two characters shall be consumed, while when parsing "0x" only one character shall be consumed.
I installed the following patch to Gnulib: https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=3ad52f3e21db96096105256ff66ebf480703a09f This should work around this glibc bug in applications that use Gnulib. However, these applications will compile their own substitutes for strtol etc. It'd be better to fix this in glibc.