Skip to content

<xlocale>: boolalpha extraction should be case-sensitive #1541

@StephanTLavavej

Description

@StephanTLavavej

Reported by @b7f7 in ea1aaf7#commitcomment-45101146 . Also tracked by Microsoft-internal VSO-1259300 / AB#1259300 .

This is a regression in VS 2019 16.8 caused by GH-1168. I developed a complete test case:

C:\Temp>type meow.cpp
#include <cassert>
#include <ios>
#include <sstream>
using namespace std;

enum class Parse { Success, Failure };

struct TestCase {
    const char* str;
    ios_base::fmtflags flags;
    Parse expected;
    bool result;
};

// clang-format off
constexpr TestCase test_cases[] = {
    {"0",     ios_base::fmtflags{}, Parse::Success, false},
    {"1",     ios_base::fmtflags{}, Parse::Success, true },
    {"2",     ios_base::fmtflags{}, Parse::Failure, true }, // N4868 [facet.num.get.virtuals]/6
    {"WOOF",  ios_base::fmtflags{}, Parse::Failure, false}, // N4868 [facet.num.get.virtuals]/3.6
    {"false", ios_base::boolalpha,  Parse::Success, false},
    {"true",  ios_base::boolalpha,  Parse::Success, true },
    {"WOOF",  ios_base::boolalpha,  Parse::Failure, false}, // N4868 [facet.num.get.virtuals]/7
    {"FALSE", ios_base::boolalpha,  Parse::Failure, false}, // regressed by GH-1168
    {"TRUE",  ios_base::boolalpha,  Parse::Failure, false}, // regressed by GH-1168
};
// clang-format on

int main() {
    for (const auto& test : test_cases) {
        bool val = !test.result;
        istringstream iss(test.str);
        iss.setf(test.flags);
        iss >> val;
        assert(iss.fail() == (test.expected == Parse::Failure));
        assert(val == test.result);
    }
}
C:\Temp>cl /EHsc /nologo /W4 meow.cpp && meow
meow.cpp
Assertion failed: iss.fail() == (test.expected == Parse::Failure), file meow.cpp, line 35

The "FALSE" and "TRUE" cases are asserting because the Standard says that the extraction should fail, but the extraction is succeeding after GH-1168 modified _Getloctxt() to perform case-insensitive comparisons:

} else if (_First == _Last || _CType.tolower(_Ptr[_Off]) != _CType.tolower(static_cast<_Elem>(*_First))) {

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!high priorityImportant!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions