This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/11352] New: crash while internal padding numeric 0
- From: "david dot asher at cavium dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 27 Jun 2003 13:48:30 -0000
- Subject: [Bug libstdc++/11352] New: crash while internal padding numeric 0
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11352
Summary: crash while internal padding numeric 0
Product: gcc
Version: 3.2.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: david dot asher at cavium dot com
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i686-pc-linux
GCC host triplet: i686-pc-linux
GCC target triplet: i686-pc-linux
When padding a numeric 0 in _S_pad, the code in locale_facets.tcc checks to see
if the old string starts with a "0x". Unfortunately, the code which produces
the unpadded string DOES NOT zero terminate: the code is relying upon passing
the length around with the string
Later, the code in _S_pad which determines whether the leading "0X" or "0x" is
present DOES NOT check whether the "x" is beyond the end of the string. In my
case I was outputting a 0 AFTER a non-zero value w/showbase on, so the __olds
string had a "x" lying around on the stack -- fooling the code into thinking it
needs to place the pad after a non-existant "0x". Because of the
inconsistancies in the length fields after this decision it caused the final
copy to use a length of -1.
In my case it was internal padding a 0 to a width of 5. __oldlen=1,
__newlen=5. Therefore __plen=4. __testhex is incorrectly evaluated to true
because an "x" just happens to be at __olds[1] -- even though __oldlen=1. This
causes:
__mod = 2
__beglen = __plen = 4
__newlen = 5
So the end copy length is calculated: 5 - 4 - 2 = -1 !! Horrible death ensues.
The following patch fixes the problem (I checked out the gcc/libstdc++-v3
sources 27-Jun-2003 9pm-ish EDT to create the patch, hopefully linewrap won't
screw this up too bad):
*** locale_facets.tcc.old Tue May 27 17:14:49 2003
--- locale_facets.tcc Thu Jun 26 20:48:07 2003
*************** namespace std
*** 2188,2195 ****
|| _Traits::eq(__olds[0], __plus);
bool __testhex = _Traits::eq(__ctype.widen('0'), __olds[0])
! && (_Traits::eq(__ctype.widen('x'), __olds[1])
! || _Traits::eq(__ctype.widen('X'), __olds[1]));
if (__testhex)
{
__news[0] = __olds[0];
--- 2188,2195 ----
|| _Traits::eq(__olds[0], __plus);
bool __testhex = _Traits::eq(__ctype.widen('0'), __olds[0])
! && ((__oldlen > 1) && (_Traits::eq(__ctype.widen
('x'), __olds[1])
! || _Traits::eq(__ctype.widen
('X'), __olds[1])));
if (__testhex)
{
__news[0] = __olds[0];