[Bug libstdc++/51772] New: --enable-clocale=generic makes unsafe assumptions about ctype_base::mask
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Jan 6 00:08:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51772
Bug #: 51772
Summary: --enable-clocale=generic makes unsafe assumptions
about ctype_base::mask
Classification: Unclassified
Product: gcc
Version: 4.7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: redi@gcc.gnu.org
Blocks: 51018
config/locale/generic/ctype_members.cc initializes _M_bit like so:
for (size_t __i = 0; __i <= 15; ++__i)
{
_M_bit[__i] = static_cast<mask>(1 << __i);
_M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]);
}
This assumes that ctype_base::mask is at least 16 bits.
Each element of _M_bit has a single bit set, and is compared to the defined
mask constants in _M_convert_to_wmask:
ctype<wchar_t>::__wmask_type
ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const throw()
{
__wmask_type __ret;
switch (__m)
{
// ...
case xdigit:
__ret = wctype("xdigit");
break;
case alnum:
__ret = wctype("alnum");
break;
case graph:
__ret = wctype("graph");
break;
default:
__ret = __wmask_type();
}
return __ret;
};
If any of the mask constants has more than one bit set it will never be
matched.
e.g. on NetBSD xdigit can never be matched for ctype<wchar_t> because
config/os/bsd/netbsd/ctype_base.h defines the following
typedef unsigned char mask;
static const mask xdigit = _N | _X;
As a result, this valid program aborts:
#include <locale>
#include <assert.h>
class gnu_ctype: public std::ctype<wchar_t> { };
int main()
{
gnu_ctype gctype;
assert(gctype.is(std::ctype_base::xdigit, L'a'));
}
More information about the Gcc-bugs
mailing list