diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-05-25 08:14:37 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-05-25 09:28:23 -0300 |
commit | 95c9a6e806226cbf174c92efc021a0d464f170a4 (patch) | |
tree | 0a02ebbc928a183e2328c265494b1915f5b658b8 /stdlib/tst-strtol-binary-main.c | |
parent | e0189b25403f8b67e7a5513d6c33fb09cb2e5e20 (diff) | |
download | glibc-95c9a6e806226cbf174c92efc021a0d464f170a4.tar.gz glibc-95c9a6e806226cbf174c92efc021a0d464f170a4.tar.xz glibc-95c9a6e806226cbf174c92efc021a0d464f170a4.zip |
Fix special case for C2x strtol binary constant handling (BZ# 30371)
When the base is 0 or 2 and the first two characters are '0' and 'b', but the rest are no binary digits. In this case this is no error, and strtol must return 0 and ENDPTR points to the 'x' or 'b'. Checked on x86_64-linux-gnu and i686-linux-gnu. Reviewed-by: Florian Weimer <fweimer@redhat.com>
Diffstat (limited to 'stdlib/tst-strtol-binary-main.c')
-rw-r--r-- | stdlib/tst-strtol-binary-main.c | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/stdlib/tst-strtol-binary-main.c b/stdlib/tst-strtol-binary-main.c index ece3100298..54cda5cd03 100644 --- a/stdlib/tst-strtol-binary-main.c +++ b/stdlib/tst-strtol-binary-main.c @@ -21,6 +21,7 @@ #include <locale.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <wchar.h> #include <support/check.h> @@ -32,13 +33,19 @@ #define CONCAT(X, Y) CONCAT_ (X, Y) #define FNX(FN) CONCAT (FNPFX, FN) -#define CHECK_RES(ARG, RES, EP, EXPECTED) \ +#if WIDE +# define STRCHR wcschr +#else +# define STRCHR strchr +#endif + +#define CHECK_RES(ARG, RES, EP, EXPECTED, EXPECTED_EP) \ do \ { \ if (TEST_C2X) \ { \ TEST_COMPARE ((RES), EXPECTED); \ - TEST_COMPARE (*(EP), 0); \ + TEST_VERIFY ((EP) == EXPECTED_EP); \ } \ else \ { \ @@ -51,95 +58,102 @@ while (0) static void -one_check (const CHAR *s, long int expected_l, unsigned long int expected_ul, - long long int expected_ll, unsigned long long int expected_ull) +one_check (const CHAR *s, const CHAR *expected_p, long int expected_l, + unsigned long int expected_ul, long long int expected_ll, + unsigned long long int expected_ull) { + expected_p = expected_p == NULL ? STRCHR (s, '\0') : expected_p; + CHAR *ep; long int ret_l; unsigned long int ret_ul; long long int ret_ll; unsigned long long int ret_ull; ret_l = FNX (l) (s, &ep, 0); - CHECK_RES (s, ret_l, ep, expected_l); + CHECK_RES (s, ret_l, ep, expected_l, expected_p); ret_l = FNX (l) (s, &ep, 2); - CHECK_RES (s, ret_l, ep, expected_l); + CHECK_RES (s, ret_l, ep, expected_l, expected_p); ret_ul = FNX (ul) (s, &ep, 0); - CHECK_RES (s, ret_ul, ep, expected_ul); + CHECK_RES (s, ret_ul, ep, expected_ul, expected_p); ret_ul = FNX (ul) (s, &ep, 2); - CHECK_RES (s, ret_ul, ep, expected_ul); + CHECK_RES (s, ret_ul, ep, expected_ul, expected_p); ret_ll = FNX (ll) (s, &ep, 0); - CHECK_RES (s, ret_ll, ep, expected_ll); + CHECK_RES (s, ret_ll, ep, expected_ll, expected_p); ret_ll = FNX (ll) (s, &ep, 2); - CHECK_RES (s, ret_ll, ep, expected_ll); + CHECK_RES (s, ret_ll, ep, expected_ll, expected_p); ret_ull = FNX (ull) (s, &ep, 0); - CHECK_RES (s, ret_ull, ep, expected_ull); + CHECK_RES (s, ret_ull, ep, expected_ull, expected_p); ret_ull = FNX (ull) (s, &ep, 2); - CHECK_RES (s, ret_ull, ep, expected_ull); + CHECK_RES (s, ret_ull, ep, expected_ull, expected_p); ret_ll = FNX (imax) (s, &ep, 0); - CHECK_RES (s, ret_ll, ep, expected_ll); + CHECK_RES (s, ret_ll, ep, expected_ll, expected_p); ret_ll = FNX (imax) (s, &ep, 2); - CHECK_RES (s, ret_ll, ep, expected_ll); + CHECK_RES (s, ret_ll, ep, expected_ll, expected_p); ret_ull = FNX (umax) (s, &ep, 0); - CHECK_RES (s, ret_ull, ep, expected_ull); + CHECK_RES (s, ret_ull, ep, expected_ull, expected_p); ret_ull = FNX (umax) (s, &ep, 2); - CHECK_RES (s, ret_ull, ep, expected_ull); + CHECK_RES (s, ret_ull, ep, expected_ull, expected_p); #if TEST_Q ret_ll = FNX (q) (s, &ep, 0); - CHECK_RES (s, ret_ll, ep, expected_ll); + CHECK_RES (s, ret_ll, ep, expected_ll, expected_p); ret_ll = FNX (q) (s, &ep, 2); - CHECK_RES (s, ret_ll, ep, expected_ll); + CHECK_RES (s, ret_ll, ep, expected_ll, expected_p); ret_ull = FNX (uq) (s, &ep, 0); - CHECK_RES (s, ret_ull, ep, expected_ull); + CHECK_RES (s, ret_ull, ep, expected_ull, expected_p); ret_ull = FNX (uq) (s, &ep, 2); - CHECK_RES (s, ret_ull, ep, expected_ull); + CHECK_RES (s, ret_ull, ep, expected_ull, expected_p); #endif #if TEST_LOCALE locale_t loc = xnewlocale (LC_NUMERIC_MASK, "C", (locale_t) 0); ret_l = FNX (l_l) (s, &ep, 0, loc); - CHECK_RES (s, ret_l, ep, expected_l); + CHECK_RES (s, ret_l, ep, expected_l, expected_p); ret_l = FNX (l_l) (s, &ep, 2, loc); - CHECK_RES (s, ret_l, ep, expected_l); + CHECK_RES (s, ret_l, ep, expected_l, expected_p); ret_ul = FNX (ul_l) (s, &ep, 0, loc); - CHECK_RES (s, ret_ul, ep, expected_ul); + CHECK_RES (s, ret_ul, ep, expected_ul, expected_p); ret_ul = FNX (ul_l) (s, &ep, 2, loc); - CHECK_RES (s, ret_ul, ep, expected_ul); + CHECK_RES (s, ret_ul, ep, expected_ul, expected_p); ret_ll = FNX (ll_l) (s, &ep, 0, loc); - CHECK_RES (s, ret_ll, ep, expected_ll); + CHECK_RES (s, ret_ll, ep, expected_ll, expected_p); ret_ll = FNX (ll_l) (s, &ep, 2, loc); - CHECK_RES (s, ret_ll, ep, expected_ll); + CHECK_RES (s, ret_ll, ep, expected_ll, expected_p); ret_ull = FNX (ull_l) (s, &ep, 0, loc); - CHECK_RES (s, ret_ull, ep, expected_ull); + CHECK_RES (s, ret_ull, ep, expected_ull, expected_p); ret_ull = FNX (ull_l) (s, &ep, 2, loc); - CHECK_RES (s, ret_ull, ep, expected_ull); + CHECK_RES (s, ret_ull, ep, expected_ull, expected_p); #endif } static int do_test (void) { - one_check (L_("0b101"), 5, 5, 5, 5); - one_check (L_("0B101"), 5, 5, 5, 5); - one_check (L_("-0b11111"), -31, -31, -31, -31); - one_check (L_("-0B11111"), -31, -31, -31, -31); - one_check (L_("0b111111111111111111111111111111111"), + { + const CHAR *input = L_("0b"); + one_check (input, input + 1, 0L, 0UL, 0LL, 0ULL); + } + one_check (L_("0b101"), NULL, 5, 5, 5, 5); + one_check (L_("0B101"), NULL, 5, 5, 5, 5); + one_check (L_("-0b11111"), NULL, -31, -31, -31, -31); + one_check (L_("-0B11111"), NULL, -31, -31, -31, -31); + one_check (L_("0b111111111111111111111111111111111"), NULL, LONG_MAX >= 0x1ffffffffLL ? (long int) 0x1ffffffffLL : LONG_MAX, (ULONG_MAX >= 0x1ffffffffULL ? (unsigned long int) 0x1ffffffffULL : ULONG_MAX), 0x1ffffffffLL, 0x1ffffffffULL); - one_check (L_("0B111111111111111111111111111111111"), + one_check (L_("0B111111111111111111111111111111111"), NULL, LONG_MAX >= 0x1ffffffffLL ? (long int) 0x1ffffffffLL : LONG_MAX, (ULONG_MAX >= 0x1ffffffffULL ? (unsigned long int) 0x1ffffffffULL : ULONG_MAX), 0x1ffffffffLL, 0x1ffffffffULL); - one_check (L_("-0b111111111111111111111111111111111"), + one_check (L_("-0b111111111111111111111111111111111"), NULL, LONG_MIN <= -0x1ffffffffLL ? (long int) -0x1ffffffffLL : LONG_MIN, (ULONG_MAX >= 0x1ffffffffULL ? (unsigned long int) -0x1ffffffffULL : ULONG_MAX), -0x1ffffffffLL, -0x1ffffffffULL); - one_check (L_("-0B111111111111111111111111111111111"), + one_check (L_("-0B111111111111111111111111111111111"), NULL, LONG_MIN <= -0x1ffffffffLL ? (long int) -0x1ffffffffLL : LONG_MIN, (ULONG_MAX >= 0x1ffffffffULL ? (unsigned long int) -0x1ffffffffULL |