From 912c7da7bf696f7f4b983b140ebc0945bd7023f7 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 8 May 2025 00:52:54 +0800 Subject: [PATCH] Fix `num_get::do_get` for `bool` on bad grouping --- stl/inc/xlocnum | 12 +- .../GH_001277_num_get_bad_grouping/test.cpp | 172 ++++++++++++++++++ 2 files changed, 176 insertions(+), 8 deletions(-) diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index 5cf765bec5d..ac526dbb0c7 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -373,15 +373,11 @@ protected: char* _Ep; int _Errno; const long _Ans = _CSTD _Stolx(_Ac, &_Ep, _Parse_result._Base, &_Errno); // convert - if (_Ep == _Ac || _Errno != 0 // N4950 [facet.num.get.virtuals]/3 - || _Parse_result._Bad_grouping) { // N4950 [facet.num.get.virtuals]/4 - _Val = true; + _Val = _Ans != 0; + if (_Ep == _Ac || _Errno != 0 // N5008 [facet.num.get.virtuals]/3 + || _Parse_result._Bad_grouping // N5008 [facet.num.get.virtuals]/4 + || (_Ans != 0 && _Ans != 1)) { // N5008 [facet.num.get.virtuals]/6 _State = ios_base::failbit; - } else { - _Val = _Ans != 0; - if (_Ans != 0 && _Ans != 1) { - _State = ios_base::failbit; - } } } } diff --git a/tests/std/tests/GH_001277_num_get_bad_grouping/test.cpp b/tests/std/tests/GH_001277_num_get_bad_grouping/test.cpp index 8d5e72294e1..62a01b4fbdf 100644 --- a/tests/std/tests/GH_001277_num_get_bad_grouping/test.cpp +++ b/tests/std/tests/GH_001277_num_get_bad_grouping/test.cpp @@ -325,6 +325,177 @@ void test_good_and_bad_grouping_pointer() { } } +// Also test GH-5470 ": num_get::do_get for bool stores true in the result when the input has bad grouping, +// even if the input is zero" +void test_good_and_bad_grouping_bool() { + const my_facet f(1); + ios instr(nullptr); + instr.imbue(locale(locale(), new special_numpunct)); + + instr.setf(ios_base::fmtflags{}, ios_base::basefield); + + { + bool v = true; + const char sep_str[] = "0"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.goodbit); + assert(!v); + } + { + bool v = true; + const char sep_str[] = "-0"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.goodbit); + assert(!v); + } + { + bool v = true; + const char sep_str[] = "1"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.goodbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "1,72,9"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.failbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "0,17,7"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.failbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "0,00,1"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.goodbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "0,00,0"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.goodbit); + assert(!v); + } + { + bool v = true; + const char sep_str[] = "01,77"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.failbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "00,01"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.failbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "00,00"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.failbit); + assert(!v); + } + { + bool v = true; + const char sep_str[] = "0x1,72,9"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.failbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "0x0,00,1"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.goodbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "0x0,00,0"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.goodbit); + assert(!v); + } + { + bool v = true; + const char sep_str[] = "0x1,729"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.failbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "0x0,001"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.failbit); + assert(v); + } + { + bool v = true; + const char sep_str[] = "0x0,000"; + const size_t len = sizeof(sep_str) - 1; + ios_base::iostate err = instr.goodbit; + const char* iter = f.get(sep_str, sep_str + len + 1, instr, err, v); + assert(iter == sep_str + len); + assert(err == instr.failbit); + assert(!v); + } +} + class mid_zero_numpunct : public numpunct { public: mid_zero_numpunct() : numpunct() {} @@ -449,6 +620,7 @@ int main() { test_good_and_bad_grouping(); test_good_and_bad_grouping(); test_good_and_bad_grouping_pointer(); + test_good_and_bad_grouping_bool(); test_nonending_unlimited_grouping(); test_nonending_unlimited_grouping();