public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* libstdc++/3720: Problems with num_get
@ 2001-07-17 15:06 Peter Schmid
0 siblings, 0 replies; 25+ messages in thread
From: Peter Schmid @ 2001-07-17 15:06 UTC (permalink / raw)
To: gcc-gnats
>Number: 3720
>Category: libstdc++
>Synopsis: Problems with num_get
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jul 17 15:06:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Peter Schmid
>Release: 3.1 20010716 (experimental)
>Organization:
TU Darmstadt
>Environment:
System: Linux kiste 2.4.6 #6 Wed Jul 11 02:21:23 CEST 2001 i686 unknown
Architecture: i686
SuSE 7.1
GNU ld version 2.11.90.0.23 (with BFD 2.11.90.0.23)
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc/configure --enable-shared --disable-nls --enable-threads=posix --enable-clocale=gnu --enable-languages=c,c++,f77,objc
>Description:
According to the book "The C++ Standard Library" by Josuttis on page
707 the facet num_get is used to parse the textual representation of
numbers. This works, unless I enter more than 56 decimals. Somehow a
segmentation fault occurs. I believe libstdc++ should handle this gracefully.
>How-To-Repeat:
Source code n1.C
#include <locale>
#include <iostream>
#include <iterator>
int main()
{
std::locale loc;
typedef std::istreambuf_iterator<char> ist_it;
ist_it beg = ist_it(std::cin);
ist_it end = ist_it();
std::ios_base& fmt = std::cin;
std::ios_base::iostate err = std::ios_base::goodbit;
double value;
std::num_get<char, ist_it> const& ng
= std::use_facet<std::num_get<char, ist_it> >(loc);
ng.get(beg, end, fmt, err, value);
std::cout << "value: " << value << std::endl;
}
Compiling n1.C
g++ -v -o n1 n1.C -W -Wall -g
Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1/specs
Configured with: ../gcc/configure --enable-shared --disable-nls --enable-threads=posix --enable-clocale=gnu --enable-languages=c,c++,f77,objc
Thread model: posix
gcc version 3.1 20010716 (experimental)
/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1/cc1plus -v -D__GNUC__=3 -D__GNUC_MINOR__=1 -D__GNUC_PATCHLEVEL__=0 -D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -W -Wall -D_GNU_SOURCE -Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -D__tune_i686__ -D__tune_pentiumpro__ n1.C -D__GNUG__=3 -D__DEPRECATED -D__EXCEPTIONS -D__GXX_ABI_VERSION=100 -quiet -dumpbase n1.C -g -W -Wall -version -o /tmp/ccUe5GLI.s
GNU CPP version 3.1 20010716 (experimental) (cpplib) (i386 Linux/ELF)
GNU C++ version 3.1 20010716 (experimental) (i686-pc-linux-gnu)
compiled by GNU C version 3.1 20010716 (experimental).
ignoring nonexistent directory "/usr/local/i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include/g++-v3
/usr/local/include/g++-v3/i686-pc-linux-gnu
/usr/local/include/g++-v3/backward
/usr/local/include
/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1/include
/usr/include
End of search list.
/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1/../../../../i686-pc-linux-gnu/bin/as -V -Qy -o /tmp/ccp9xNWy.o /tmp/ccUe5GLI.s
GNU assembler version 2.11.90.0.23 (i686-pc-linux-gnu) using BFD version 2.11.90.0.23
/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o n1 /usr/lib/crt1.o /usr/lib/crti.o /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1/crtbegin.o -L/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1 -L/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1/../../../../i686-pc-linux-gnu/lib -L/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1/../../.. /tmp/ccp9xNWy.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.1/crtend.o /usr/lib/crtn.o
Running n1
./n1
1.2345678901234567890123456789012345678901234567890123456
Segmentation fault (core dumped)
Debugging n1
GNU gdb 5.0
Copyright 2001 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) r
Starting program: /home/peter/trans/vergleich/mein_stlport/i18n/n1
1.2345678901234567890123456789012345678901234567890123456
Program received signal SIGSEGV, Segmentation fault.
0x0804a861 in std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, double&) const (this=0x0, __in=
{<iterator<std::input_iterator_tag,char,long int,char*,char&>> = {<No data fields>}, _M_sbuf = 0x0, _M_c = 0}, __end=
{<iterator<std::input_iterator_tag,char,long int,char*,char&>> = {<No data fields>}, _M_sbuf = 0x0, _M_c = 0}, __io=@0x0, __err=@0x0, __v=@0x0)
at /usr/local/include/g++-v3/bits/locale_facets.h:637
(gdb) l
632 { return do_get(__in, __end, __io, __err, __v); }
633
634 iter_type
635 get(iter_type __in, iter_type __end, ios_base& __io,
636 ios_base::iostate& __err, double& __v) const
637 { return do_get(__in, __end, __io, __err, __v); }
638
639 iter_type
640 get(iter_type __in, iter_type __end, ios_base& __io,
641 ios_base::iostate& __err, long double& __v) const
(gdb) bt
#0 0x0804a861 in std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, double&) const (this=0x0, __in=
{<iterator<std::input_iterator_tag,char,long int,char*,char&>> = {<No data fields>}, _M_sbuf = 0x0, _M_c = 0}, __end=
{<iterator<std::input_iterator_tag,char,long int,char*,char&>> = {<No data fields>}, _M_sbuf = 0x0, _M_c = 0}, __io=@0x0, __err=@0x0, __v=@0x0)
at /usr/local/include/g++-v3/bits/locale_facets.h:637
(gdb)
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-11 0:06 Mark Mitchell
0 siblings, 0 replies; 25+ messages in thread
From: Mark Mitchell @ 2001-12-11 0:06 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Mark Mitchell <mark@codesourcery.com>
To: Joe Buck <jbuck@synopsys.COM>
Cc: Philip Martin <philip@codematters.co.uk>,
Benjamin Kosnik <bkoz@redhat.com>,
Peter Schmid <schmid@snake.iap.physik.tu-darmstadt.de>,
"gcc-bugs@gcc.gnu.org" <gcc-bugs@gcc.gnu.org>,
"gcc-gnats@gcc.gnu.org" <gcc-gnats@gcc.gnu.org>,
"gcc-prs@gcc.gnu.org" <gcc-prs@gcc.gnu.org>,
"philip_martin@ntlworld.com" <philip_martin@ntlworld.com>
Subject: Re: libstdc++/3720: Problems with num_get
Date: Mon, 10 Dec 2001 23:57:38 -0800
--On Monday, December 10, 2001 05:52:32 PM -0800 Joe Buck
<jbuck@synopsys.COM> wrote:
>
>> Would you point me at the URL for Philip's patch?
>>
>> Thank you,
>
> http://gcc.gnu.org/ml/gcc-bugs/2001-12/msg00421.html
>
> (I know, should be gcc-patches)
>
> Ben's approval is in
>
> http://gcc.gnu.org/ml/gcc-bugs/2001-12/msg00424.html
Thanks; I've installed this patch on the branch.
I will make prerelease tarballs tomorrow.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 17:56 Mark Mitchell
0 siblings, 0 replies; 25+ messages in thread
From: Mark Mitchell @ 2001-12-10 17:56 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Mark Mitchell <mark@codesourcery.com>
To: Joe Buck <jbuck@synopsys.COM>, Philip Martin <philip@codematters.co.uk>
Cc: Benjamin Kosnik <bkoz@redhat.com>,
Peter Schmid <schmid@snake.iap.physik.tu-darmstadt.de>,
"gcc-bugs@gcc.gnu.org" <gcc-bugs@gcc.gnu.org>,
"gcc-gnats@gcc.gnu.org" <gcc-gnats@gcc.gnu.org>,
"gcc-prs@gcc.gnu.org" <gcc-prs@gcc.gnu.org>,
"philip_martin@ntlworld.com" <philip_martin@ntlworld.com>
Subject: Re: libstdc++/3720: Problems with num_get
Date: Mon, 10 Dec 2001 17:36:55 -0800
--On Monday, December 10, 2001 05:11:27 PM -0800 Joe Buck
<jbuck@synopsys.COM> wrote:
> Philip Martin writes:
>
>> Here's a simple patch (with no ABI change I believe) that avoids the
>> buffer overflow, it sets failbit intead.
>
> OK, I sent something very similar to gcc-patches, but it doesn't handle
> all the cases; your patch is better.
Would you point me at the URL for Philip's patch?
Thank you,
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 17:56 Joe Buck
0 siblings, 0 replies; 25+ messages in thread
From: Joe Buck @ 2001-12-10 17:56 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Joe Buck <jbuck@synopsys.COM>
To: mark@codesourcery.com (Mark Mitchell)
Cc: jbuck@synopsys.COM (Joe Buck),
philip@codematters.co.uk (Philip Martin),
bkoz@redhat.com (Benjamin Kosnik),
schmid@snake.iap.physik.tu-darmstadt.de (Peter Schmid),
gcc-bugs@gcc.gnu.org (gcc-bugs@gcc.gnu.org),
gcc-gnats@gcc.gnu.org (gcc-gnats@gcc.gnu.org),
gcc-prs@gcc.gnu.org (gcc-prs@gcc.gnu.org),
philip_martin@ntlworld.com (philip_martin@ntlworld.com)
Subject: Re: libstdc++/3720: Problems with num_get
Date: Mon, 10 Dec 2001 17:52:32 -0800 (PST)
> Would you point me at the URL for Philip's patch?
>
> Thank you,
http://gcc.gnu.org/ml/gcc-bugs/2001-12/msg00421.html
(I know, should be gcc-patches)
Ben's approval is in
http://gcc.gnu.org/ml/gcc-bugs/2001-12/msg00424.html
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 17:16 Joe Buck
0 siblings, 0 replies; 25+ messages in thread
From: Joe Buck @ 2001-12-10 17:16 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Joe Buck <jbuck@synopsys.COM>
To: philip@codematters.co.uk (Philip Martin)
Cc: bkoz@redhat.com (Benjamin Kosnik),
schmid@snake.iap.physik.tu-darmstadt.de (Peter Schmid),
gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
philip_martin@ntlworld.com, mark@codesourcery.com
Subject: Re: libstdc++/3720: Problems with num_get
Date: Mon, 10 Dec 2001 17:11:27 -0800 (PST)
Philip Martin writes:
> Here's a simple patch (with no ABI change I believe) that avoids the
> buffer overflow, it sets failbit intead.
OK, I sent something very similar to gcc-patches, but it doesn't handle
all the cases; your patch is better.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 17:16 Benjamin Kosnik
0 siblings, 0 replies; 25+ messages in thread
From: Benjamin Kosnik @ 2001-12-10 17:16 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Benjamin Kosnik <bkoz@redhat.com>
To: Philip Martin <philip@codematters.co.uk>
Cc: Peter Schmid <schmid@snake.iap.physik.tu-darmstadt.de>,
gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
philip_martin@ntlworld.com, jbuck@synopsys.com
Subject: Re: libstdc++/3720: Problems with num_get
Date: Mon, 10 Dec 2001 17:06:08 -0800 (PST)
This is fine Philip.
thanks,
benjamin
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 17:06 Philip Martin
0 siblings, 0 replies; 25+ messages in thread
From: Philip Martin @ 2001-12-10 17:06 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Philip Martin <philip@codematters.co.uk>
To: Benjamin Kosnik <bkoz@redhat.com>
Cc: Peter Schmid <schmid@snake.iap.physik.tu-darmstadt.de>,
gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
philip_martin@ntlworld.com, jbuck@synopsys.com
Subject: Re: libstdc++/3720: Problems with num_get
Date: 11 Dec 2001 00:54:35 +0000
Benjamin Kosnik <bkoz@redhat.com> writes:
> Peter, I'd like this to be fixed on the branch, but I am unable to work
> on this right now due to pending deadlines elsewhere.
>
> Porting the patch to gcc-3.0 might be possible, but for gcc-3.03 you'd
> have to be binary-compatibile with gcc-3.02, and it's solved in mainline
> without this additional constraint.
Here's a simple patch (with no ABI change I believe) that avoids the
buffer overflow, it sets failbit intead. It's not strictly ISO
compliant, as some valid input longer than the buffer sets failbit
instead of being read successfully, but that might be better than
dumping core. All integer input should be handled correctly. Only
floating-point input more than 31 characters, after discarding leading
zeros, can exceed the buffer.
Philip
libstdc++/3720: Designed for the 3.0 branch. This in strictly
non-compliant but it's probably better than dumping core.
* include/bits/locale_facets.h
(_M_extract_buffer_length): Add this constant.
* include/bits/locale_facet.tcc
(do_get): Use _M_extract_buffer_length.
* src/locale.cc
(_M_extract): Set failbit if buffer gets filled while
extracting characters.
* testsuite/27_io/istream_extractor_arith.cc
(tes12_aux, test12, test13): Add, ported from trunk.
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.12.2.2
diff -c -3 -p -r1.12.2.2 locale_facets.h
*** locale_facets.h 2001/06/04 19:30:55 1.12.2.2
--- locale_facets.h 2001/12/11 00:37:28
*************** namespace std
*** 561,566 ****
--- 561,569 ----
_M_get_digits(iter_type __in, iter_type __end) const;
};
+ // This is the size of the buffer passed to _M_extract
+ const int _M_extract_buffer_length = 32;
+
template<typename _CharT, typename _InIter>
class num_get : public locale::facet
{
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.8.2.4
diff -c -3 -p -r1.8.2.4 locale_facets.tcc
*** locale_facets.tcc 2001/06/10 23:41:55 1.8.2.4
--- locale_facets.tcc 2001/12/11 00:37:28
*************** namespace std
*** 282,288 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32] = {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 282,288 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length] = {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
*************** namespace std
*** 347,353 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 347,353 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
*************** namespace std
*** 374,380 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32] = {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 374,380 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length] = {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
*************** namespace std
*** 402,408 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 402,408 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
*************** namespace std
*** 429,435 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 429,435 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
*************** namespace std
*** 456,462 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 456,462 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
*************** namespace std
*** 483,489 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 483,489 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
*************** namespace std
*** 510,516 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32] = {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 510,516 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length] = {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
*************** namespace std
*** 537,543 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 537,543 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
*************** namespace std
*** 564,570 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
--- 564,570 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
*************** namespace std
*** 594,600 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
--- 594,600 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
*************** namespace std
*** 621,627 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
--- 621,627 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
*************** namespace std
*** 645,651 ****
ios_base::iostate& __err, long double& __v) const
{
// Stage 1: extract
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
--- 645,651 ----
ios_base::iostate& __err, long double& __v) const
{
// Stage 1: extract
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
*************** namespace std
*** 691,697 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
--- 691,697 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[_M_extract_buffer_length]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
Index: src/locale.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/locale.cc,v
retrieving revision 1.28.2.4
diff -c -3 -p -r1.28.2.4 locale.cc
*** locale.cc 2001/07/20 00:14:10 1.28.2.4
--- locale.cc 2001/12/11 00:37:29
*************** namespace std
*** 646,651 ****
--- 646,657 ----
}
#endif
+ // This interface passes a fixed size buffer. The function cannot handle
+ // input longer than the buffer and sets failbit in that case. This is
+ // not strictly compliant since the input may be valid, but we are stuck
+ // with this ABI on the 3.0 branch. Since leading zeros are discarded all
+ // valid integer input should be OK, only floating point input can exceed
+ // the buffer.
template<>
void
num_get<char, istreambuf_iterator<char> >::
*************** namespace std
*** 785,790 ****
--- 791,804 ----
{
// Try first for acceptable digit; record it if found.
__xtrc[__pos++] = __c;
+ if (__pos == _M_extract_buffer_length)
+ {
+ // XXX This is non-compliant, but our fixed-size
+ // buffer is full.
+ __xtrc[_M_extract_buffer_length-1] = '\0';
+ __err |= ios_base::failbit;
+ return;
+ }
++__sep_pos;
__testunits = true;
++__beg;
*************** namespace std
*** 865,870 ****
--- 879,892 ----
if (__c == __fmt->_M_decimal_point)
{
__xtrc[__pos++] = '.';
+ if (__pos == _M_extract_buffer_length)
+ {
+ // XXX This is non-compliant, but our fixed-size
+ // buffer is full.
+ __xtrc[_M_extract_buffer_length-1] = '\0';
+ __err |= ios_base::failbit;
+ return;
+ }
++__beg;
__c = *__beg;
*************** namespace std
*** 879,884 ****
--- 901,914 ----
&& __p < &__lits[__cache_type::_S_udigits + __base]))
{
__xtrc[__pos++] = __c;
+ if (__pos == _M_extract_buffer_length)
+ {
+ // XXX This is non-compliant, but our fixed-size
+ // buffer is full.
+ __xtrc[_M_extract_buffer_length-1] = '\0';
+ __err |= ios_base::failbit;
+ return;
+ }
++__beg;
__c = *__beg;
__testdec = true;
*************** namespace std
*** 903,908 ****
--- 933,946 ----
|| (__c == __lits[__cache_type::_S_Ee]))
{
__xtrc[__pos++] = __c;
+ if (__pos == _M_extract_buffer_length)
+ {
+ // XXX This is non-compliant, but our fixed-size
+ // buffer is full.
+ __xtrc[_M_extract_buffer_length-1] = '\0';
+ __err |= ios_base::failbit;
+ return;
+ }
++__beg;
__c = *__beg;
*************** namespace std
*** 913,918 ****
--- 951,964 ----
|| (__c == __lits[__cache_type::_S_plus]))
{
__xtrc[__pos++] = __c;
+ if (__pos == _M_extract_buffer_length)
+ {
+ // XXX This is non-compliant, but our fixed-size
+ // buffer is full.
+ __xtrc[_M_extract_buffer_length-1] = '\0';
+ __err |= ios_base::failbit;
+ return;
+ }
++__beg;
__c = *__beg;
// whitespace may follow a sign
*************** namespace std
*** 939,944 ****
--- 985,998 ----
&& __p < &__lits[__cache_type::_S_udigits + __base]))
{
__xtrc[__pos++] = __c;
+ if (__pos == _M_extract_buffer_length)
+ {
+ // XXX This is non-compliant, but our fixed-size
+ // buffer is full.
+ __xtrc[_M_extract_buffer_length-1] = '\0';
+ __err |= ios_base::failbit;
+ return;
+ }
++__beg;
__c = *__beg;
}
Index: testsuite/27_io/istream_extractor_arith.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/27_io/istream_extractor_arith.cc,v
retrieving revision 1.8.4.2
diff -c -3 -p -r1.8.4.2 istream_extractor_arith.cc
*** istream_extractor_arith.cc 2001/08/28 21:19:09 1.8.4.2
--- istream_extractor_arith.cc 2001/12/11 00:37:29
*************** bool test11()
*** 513,518 ****
--- 513,596 ----
return test;
}
+ // libstdc++/3720
+ // excess input should not cause a core dump
+ template<typename T>
+ bool test12_aux(bool integer_type)
+ {
+ bool test = true;
+
+ int digits_overflow;
+ if (integer_type)
+ // This many digits will overflow integer types in base 10.
+ digits_overflow = std::numeric_limits<T>::digits10 + 1;
+ else
+ // This might do it, unsure.
+ digits_overflow = std::numeric_limits<T>::max_exponent10 + 1;
+
+ std::string st;
+ std::string part = "1234567890123456789012345678901234567890";
+ for (int i = 0; i < digits_overflow / part.size() + 1; ++i)
+ st += part;
+ std::stringbuf sb(st);
+ std::istream is(&sb);
+ T t;
+ is >> t;
+ VERIFY(is.fail());
+ return test;
+ }
+
+ bool test12()
+ {
+ bool test = true;
+ VERIFY(test12_aux<short>(true));
+ VERIFY(test12_aux<int>(true));
+ VERIFY(test12_aux<long>(true));
+ VERIFY(test12_aux<float>(false));
+ VERIFY(test12_aux<double>(false));
+ VERIFY(test12_aux<long double>(false));
+ return test;
+ }
+
+ // libstdc++/3720 part two
+ void test13()
+ {
+ using namespace std;
+ bool test = true;
+ const char* l1 = "12345678901234567890123456789012345678901234567890123456";
+ const char* l2 = "1.2345678901234567890123456789012345678901234567890123456"
+ " "
+ "1246.9";
+
+ // 1
+ // used to core.
+ double d;
+ istringstream iss1(l2);
+ iss1 >> d;
+ // XXX doesn't work on 3.0 branch
+ // iss1 >> d;
+ // VERIFY (d > 1246 && d < 1247);
+
+ // 2
+ // quick test for failbit on maximum length extraction.
+ int i;
+ int max_digits = numeric_limits<int>::digits10;
+ string digits;
+ for (int j = 0; j < max_digits; ++j)
+ digits += '1';
+ istringstream iss2(digits);
+ iss2 >> i;
+ VERIFY( !iss2.fail() );
+
+ digits += '1';
+ i = 0;
+ iss2.str(digits);
+ iss2.clear();
+ iss2 >> i;
+ VERIFY( i == 0 );
+ VERIFY( iss2.fail() );
+ }
+
int main()
{
test01();
*************** int main()
*** 526,531 ****
--- 604,611 ----
test10();
test11();
+ test12();
+ test13();
return 0;
}
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 14:06 Benjamin Kosnik
0 siblings, 0 replies; 25+ messages in thread
From: Benjamin Kosnik @ 2001-12-10 14:06 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Benjamin Kosnik <bkoz@redhat.com>
To: Peter Schmid <schmid@snake.iap.physik.tu-darmstadt.de>
Cc: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
philip_martin@ntlworld.com
Subject: Re: libstdc++/3720: Problems with num_get
Date: Mon, 10 Dec 2001 14:00:48 -0800 (PST)
Peter, I'd like this to be fixed on the branch, but I am unable to work
on this right now due to pending deadlines elsewhere.
Porting the patch to gcc-3.0 might be possible, but for gcc-3.03 you'd
have to be binary-compatibile with gcc-3.02, and it's solved in mainline
without this additional constraint.
-benjamin
On Mon, 10 Dec 2001, Peter Schmid wrote:
> Why is the problem not fixed in the gcc 3.0 branch?
> I believe this severe problem should be fixed before gcc 3.0.3 is
> released.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 12:16 Peter Schmid
0 siblings, 0 replies; 25+ messages in thread
From: Peter Schmid @ 2001-12-10 12:16 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Peter Schmid <schmid@snake.iap.physik.tu-darmstadt.de>
To: bkoz@gcc.gnu.org
Cc: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
philip_martin@ntlworld.com
Subject: Re: libstdc++/3720: Problems with num_get
Date: Mon, 10 Dec 2001 21:10:23 +0100 (CET)
Why is the problem not fixed in the gcc 3.0 branch?
I believe this severe problem should be fixed before gcc 3.0.3 is
released.
Thank you.
Peter Schmid
On 10 Dec 2001 bkoz@gcc.gnu.org wrote:
> Synopsis: Problems with num_get
>
> State-Changed-From-To: feedback->closed
> State-Changed-By: bkoz
> State-Changed-When: Mon Dec 10 11:55:49 2001
> State-Changed-Why:
> By request. Fixed in mainline.
>
> http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 12:06 bkoz
0 siblings, 0 replies; 25+ messages in thread
From: bkoz @ 2001-12-10 12:06 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: bkoz@gcc.gnu.org
To: bkoz@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org,
gcc-prs@gcc.gnu.org, philip_martin@ntlworld.com,
schmid@snake.iap.physik.tu-darmstadt.de
Cc:
Subject: Re: libstdc++/3720: Problems with num_get
Date: 10 Dec 2001 19:55:50 -0000
Synopsis: Problems with num_get
State-Changed-From-To: feedback->closed
State-Changed-By: bkoz
State-Changed-When: Mon Dec 10 11:55:49 2001
State-Changed-Why:
By request. Fixed in mainline.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 11:55 bkoz
0 siblings, 0 replies; 25+ messages in thread
From: bkoz @ 2001-12-10 11:55 UTC (permalink / raw)
To: bkoz, gcc-bugs, gcc-gnats, gcc-prs, philip_martin, schmid
Synopsis: Problems with num_get
State-Changed-From-To: feedback->closed
State-Changed-By: bkoz
State-Changed-When: Mon Dec 10 11:55:49 2001
State-Changed-Why:
By request. Fixed in mainline.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-10 0:16 Benjamin Kosnik
0 siblings, 0 replies; 25+ messages in thread
From: Benjamin Kosnik @ 2001-12-10 0:16 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Benjamin Kosnik <bkoz@redhat.com>
To: Philip Martin <pmartin@uklinux.net>
Cc: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
schmid@snake.iap.physik.tu-darmstadt.de
Subject: Re: libstdc++/3720: Problems with num_get
Date: Mon, 10 Dec 2001 00:07:04 -0800 (PST)
> 1. Looking at the code, there are two calls to log() per integer
> input in _M_extract_int() in locale_facets.tcc
These have been made constant.
> 2. You aren't calling test13() from main() in
> testsuite/27_io/istream_extractor_arith.cc
Fixed.
> 3. Trying the code, input of std::numeric_limits<T>::max() in octal or
> hex doesn't appear to work for integers, e.g. reading 017777777777
> into a long on x86 doesn't work, it appears to accept one character
> too few. Decimal works.
Not quite sure what you mean here, can you provide this problem
statement in C++ please.
thanks.
benjamin
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-09 23:46 Benjamin Kosnik
0 siblings, 0 replies; 25+ messages in thread
From: Benjamin Kosnik @ 2001-12-09 23:46 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Benjamin Kosnik <bkoz@redhat.com>
To: Philip Martin <philip@codematters.co.uk>
Cc: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
schmid@snake.iap.physik.tu-darmstadt.de
Subject: Re: libstdc++/3720: Problems with num_get
Date: Sun, 9 Dec 2001 23:39:04 -0800 (PST)
> would deduce octal from the leading zero, as that's what stdio "%i"
> does. Investigation shows that it is reading decimal, which is then
stdio %i is equiv behavior to basefield == 0 case only. Default is
signed/unsigned int in the case.
> causes the number to be read correctly. I suppose it's table 89 in
> 27.4.4.1 that determines that dec is the default? I didn't expect
> that.
See
22.2.2.1.2 - num_get virtual functions [lib.facet.num.get.virtuals]
p4
on how input is ordered.
For this case, I believe current behavior is correct.
best,
benjamin
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-07 17:36 Philip Martin
0 siblings, 0 replies; 25+ messages in thread
From: Philip Martin @ 2001-12-07 17:36 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Philip Martin <philip@codematters.co.uk>
To: Benjamin Kosnik <bkoz@redhat.com>
Cc: bkoz@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org,
gcc-prs@gcc.gnu.org, schmid@snake.iap.physik.tu-darmstadt.de
Subject: Re: libstdc++/3720: Problems with num_get
Date: 08 Dec 2001 01:25:45 +0000
Benjamin Kosnik <bkoz@redhat.com> writes:
> > 3. Trying the code, input of std::numeric_limits<T>::max() in octal or
> > hex doesn't appear to work for integers, e.g. reading 017777777777
> > into a long on x86 doesn't work, it appears to accept one character
> > too few. Decimal works.
>
> Hmm. I'll look at this, thanks.
I was assuming that
std::istringstream i( "017777777777" );
long x = 0;
i >> x;
would deduce octal from the leading zero, as that's what stdio "%i"
does. Investigation shows that it is reading decimal, which is then
one digit too long. Using an explicit manipulator
i >> std::setbase(0) >> x;
or
i >> std::oct >> x;
causes the number to be read correctly. I suppose it's table 89 in
27.4.4.1 that determines that dec is the default? I didn't expect
that.
Philip
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-07 16:26 Benjamin Kosnik
0 siblings, 0 replies; 25+ messages in thread
From: Benjamin Kosnik @ 2001-12-07 16:26 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Benjamin Kosnik <bkoz@redhat.com>
To: Philip Martin <pmartin@uklinux.net>
Cc: bkoz@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org,
gcc-prs@gcc.gnu.org, schmid@snake.iap.physik.tu-darmstadt.de
Subject: Re: libstdc++/3720: Problems with num_get
Date: Fri, 7 Dec 2001 16:20:02 -0800 (PST)
> 1. Looking at the code, there are two calls to log() per integer
> input in _M_extract_int() in locale_facets.tcc
OK this is bogus, agreed. Can this stuff be moved into __num_base and be
made const?
> 2. You aren't calling test13() from main() in
> testsuite/27_io/istream_extractor_arith.cc
Ugh.
> 3. Trying the code, input of std::numeric_limits<T>::max() in octal or
> hex doesn't appear to work for integers, e.g. reading 017777777777
> into a long on x86 doesn't work, it appears to accept one character
> too few. Decimal works.
Hmm. I'll look at this, thanks.
I'd like to use some kind of limiting factor for _M_extract_float, like
_M_extract_int has now.
Any thoughts on that? I was kind of hoping that part could wait a bit, but
if anybody's feeling up to it, I'd be psyched.
-benjamin
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-07 10:26 Philip Martin
0 siblings, 0 replies; 25+ messages in thread
From: Philip Martin @ 2001-12-07 10:26 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Philip Martin <pmartin@uklinux.net>
To: bkoz@gcc.gnu.org
Cc: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
schmid@snake.iap.physik.tu-darmstadt.de
Subject: Re: libstdc++/3720: Problems with num_get
Date: 07 Dec 2001 18:21:13 +0000
bkoz@gcc.gnu.org writes:
> Synopsis: Problems with num_get
>
> State-Changed-From-To: analyzed->feedback
> State-Changed-By: bkoz
> State-Changed-When: Fri Dec 7 01:11:50 2001
> State-Changed-Why:
> Try this:
>
> 2001-12-06 Benjamin Kosnik <bkoz@redhat.com>
>
> libstdc++/3720
> * include/bits/locale_facets.tcc (num_put): Clean.
> (num_get::_M_extract_float): Change argument to string.
> (num_get::do_get(float)): Fixup.
> (num_get::do_get(double)): Same.
> (num_get::do_get(long double)): Same.
> (num_get::_M_extract_int): Add maximum length parameter, __max.
> (num_get::_M_extract_float): Correct zeros, use string.
> * include/bits/locale_facets.h (num_get::_M_extract_float): Change
> declaration here.
> * src/locale.cc (__num_base::_S_atoms): Remove x, X.
> * testsuite/27_io/istream_extractor_arith.cc (test13): Add.
>
> 2001-12-06 Philip Martin <pmartin@uklinux.net>
>
> * testsuite/27_io/istream_extractor_arith.cc
> (test12): Add
> tests for excess input digits.
>
>
> http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
1. Looking at the code, there are two calls to log() per integer
input in _M_extract_int() in locale_facets.tcc
// Figure out the maximum number of digits that can be extracted
// for the given type, using the determined base.
int __max_digits;
if (__base != 10)
__max_digits = static_cast<int>(ceil(__max * log(10.0)
/log(static_cast<double>(__base))));
else
__max_digits = __max;
All standard input is in base 8, 10, or 16, so how about something
based on
if (__base == 10)
__max_digits = __max;
else if (__base == 8)
__max_digits = 1 + __max * 11073 / 10000; // approx. log(10)/log(8)
else if (__base == 16)
__max_digits = 1 + __max * 8305 / 10000; // approx. log(10)/log(16)
else
???
I haven't fully checked if this is accurate enough, however with
the truncation to an int no great accuracy is required.
2. You aren't calling test13() from main() in
testsuite/27_io/istream_extractor_arith.cc
3. Trying the code, input of std::numeric_limits<T>::max() in octal or
hex doesn't appear to work for integers, e.g. reading 017777777777
into a long on x86 doesn't work, it appears to accept one character
too few. Decimal works.
Philip
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-07 1:16 bkoz
0 siblings, 0 replies; 25+ messages in thread
From: bkoz @ 2001-12-07 1:16 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: bkoz@gcc.gnu.org
To: bkoz@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org,
gcc-prs@gcc.gnu.org, philip_martin@ntlworld.com,
schmid@snake.iap.physik.tu-darmstadt.de
Cc:
Subject: Re: libstdc++/3720: Problems with num_get
Date: 7 Dec 2001 09:11:50 -0000
Synopsis: Problems with num_get
State-Changed-From-To: analyzed->feedback
State-Changed-By: bkoz
State-Changed-When: Fri Dec 7 01:11:50 2001
State-Changed-Why:
Try this:
2001-12-06 Benjamin Kosnik <bkoz@redhat.com>
libstdc++/3720
* include/bits/locale_facets.tcc (num_put): Clean.
(num_get::_M_extract_float): Change argument to string.
(num_get::do_get(float)): Fixup.
(num_get::do_get(double)): Same.
(num_get::do_get(long double)): Same.
(num_get::_M_extract_int): Add maximum length parameter, __max.
(num_get::_M_extract_float): Correct zeros, use string.
* include/bits/locale_facets.h (num_get::_M_extract_float): Change
declaration here.
* src/locale.cc (__num_base::_S_atoms): Remove x, X.
* testsuite/27_io/istream_extractor_arith.cc (test13): Add.
2001-12-06 Philip Martin <pmartin@uklinux.net>
* testsuite/27_io/istream_extractor_arith.cc
(test12): Add
tests for excess input digits.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-07 1:11 bkoz
0 siblings, 0 replies; 25+ messages in thread
From: bkoz @ 2001-12-07 1:11 UTC (permalink / raw)
To: bkoz, gcc-bugs, gcc-gnats, gcc-prs, philip_martin, schmid
Synopsis: Problems with num_get
State-Changed-From-To: analyzed->feedback
State-Changed-By: bkoz
State-Changed-When: Fri Dec 7 01:11:50 2001
State-Changed-Why:
Try this:
2001-12-06 Benjamin Kosnik <bkoz@redhat.com>
libstdc++/3720
* include/bits/locale_facets.tcc (num_put): Clean.
(num_get::_M_extract_float): Change argument to string.
(num_get::do_get(float)): Fixup.
(num_get::do_get(double)): Same.
(num_get::do_get(long double)): Same.
(num_get::_M_extract_int): Add maximum length parameter, __max.
(num_get::_M_extract_float): Correct zeros, use string.
* include/bits/locale_facets.h (num_get::_M_extract_float): Change
declaration here.
* src/locale.cc (__num_base::_S_atoms): Remove x, X.
* testsuite/27_io/istream_extractor_arith.cc (test13): Add.
2001-12-06 Philip Martin <pmartin@uklinux.net>
* testsuite/27_io/istream_extractor_arith.cc
(test12): Add
tests for excess input digits.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-05 15:26 bkoz
0 siblings, 0 replies; 25+ messages in thread
From: bkoz @ 2001-12-05 15:26 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: bkoz@gcc.gnu.org
To: bkoz@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org,
gcc-prs@gcc.gnu.org, philip_martin@ntlworld.com,
schmid@snake.iap.physik.tu-darmstadt.de
Cc:
Subject: Re: libstdc++/3720: Problems with num_get
Date: 5 Dec 2001 23:17:16 -0000
Synopsis: Problems with num_get
State-Changed-From-To: feedback->analyzed
State-Changed-By: bkoz
State-Changed-When: Wed Dec 5 15:17:15 2001
State-Changed-Why:
Porting fix...
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-05 15:17 bkoz
0 siblings, 0 replies; 25+ messages in thread
From: bkoz @ 2001-12-05 15:17 UTC (permalink / raw)
To: bkoz, gcc-bugs, gcc-gnats, gcc-prs, philip_martin, schmid
Synopsis: Problems with num_get
State-Changed-From-To: feedback->analyzed
State-Changed-By: bkoz
State-Changed-When: Wed Dec 5 15:17:15 2001
State-Changed-Why:
Porting fix...
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-01 19:16 Philip Martin
0 siblings, 0 replies; 25+ messages in thread
From: Philip Martin @ 2001-12-01 19:16 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Philip Martin <pmartin@uklinux.net>
To: bkoz@gcc.gnu.org
Cc: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
schmid@snake.iap.physik.tu-darmstadt.de
Subject: Re: libstdc++/3720: Problems with num_get
Date: 02 Dec 2001 03:07:25 +0000
bkoz@gcc.gnu.org writes:
> I've been thinking about this, and its related bug libstdc++/4402.
>
> I agree this should not core.
>
> Looking at <limits> it looks like the largest number of digits for any numeric input is around 33 characters.
33? I don't see why, but I couldn't work out why the current code uses
32 either. Please describe the longest number if you are going to
build a constant into the code.
Are there any platforms with 128-bit integers? Octal representation
could reach 43 non-zero octets, plus a leading zero, a null byte and
an optional sign.
Floating point input doesn't have to use exponential notation. A
sequence of digits of length numeric_limits<long double>::max_exponent10
(which is 4932 on x86) is valid input as far as I am aware, it certainly
works on 2.95. It is possible that after something like digits10+1 digits
one could increment a decimal scaling factor and ignore the precise
digit value.
"Leading" zeros after a decimal point are also a problem
0.00000000000000000000000000000000000000000000000000000000000000000000000001
I want more than the first 33 digits here! As many as -min_exponent10+2 perhaps?
>
> Looking at the relevant part of the standard, I see
>
> 22.2.2.1.2 - num_get virtual functions [lib.facet.num.get.virtuals]
>
> -9- If discard is true then the position of the character is remembered, but the character is otherwise ignored. If it is not discarded, then a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by stage 1. If so it is accumulated.
>
>
> This is sufficiently vague to allow the following plan, which I consider sensible:
>
> numbers are extracted while beg != end and while the number of extracted digits <= numeric_limits<_Type>::digits10().
digits10 is the number of decimal digits that can be represented
without change, i.e. the binary may represent more. Thus in general
digits10+1 digits are needed to be guarantee full binary precision.
However in this case I think octal is the limiting factor. The number
of decimal digits is
digits10 = digits * log10(2) = digits * 0.30103
while the number of octal octets (lets call it digits8) is larger
digits8 = digits / 3 = digits * 0.33333
At 64 bits digits8 and digits10 differ by two.
For octal you need to extract the leading zero plus up to digits/3+1
subsequent octal characters (although if digits%3==0, for 48 or 96
bits say, then digits/3 would suffice).
Hmm, looking at std_limits.h the values appear to be off by one. For
instance __glibcpp_s32_digits10 = 10 but not all 10 digit numbers can
be represented using 32 bits. I think this is a bug in the limits
file.
>
> At that point, we either continue on without setting failbit, or extract one more and set failbit.
>
> The bit of the standard again:
>
> If it is not discarded, then a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by stage 1. If so it is accumulated.
>
> To me, this means that one-past-the type-determined size should be extracted, then not accumulated, and failbit should be set.
>
> Does this sound reasonable?
It needs to be significantly more complicated for exponential notation
-00..........000123456......2345678............xxx.xxxxxxxxxxxE00000000001234
<-------------><-----------------><-------------><----------> <--------><-->
discard these read these count these discard discard read
and
-0.0000..........000123456......2345678............xxxxxxxxxxxE00000000001234
<---------------><-----------------><---------------------> <--------><-->
count these read these discard discard read
What do you do here, given that one can't pass scaling factors around
without changing the ABI?
Extract and store the "significant" part of the mantissa. Calculate a
mantissa scaling factor from the additional digits before the decimal
point or the leading zeros after the decimal point. Extract the
exponent if present. Now it gets ridiculous: convert the exponent to a
number, add the mantissa scaling factor to the exponent, convert the
exponent back to a string! Then pass this whole new string off to the
C library, where it gets parsed again.
That assumes I haven't missed some subtle numerical point regarding
truncating the mantissa and adjusting the exponent. Will that always
produce the right representation? Reading and parsing floating-point
numbers is non-trivial, look at the amount of code that makes up
strtod in glibc.
To get floating point input up to the level available in 2.95 without
changing the ABI is *hard*. At present, for serious, robust floating-
point input with gcc3 I use the C library :-(
> http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
Philip
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-12-01 10:16 Peter Schmid
0 siblings, 0 replies; 25+ messages in thread
From: Peter Schmid @ 2001-12-01 10:16 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Peter Schmid <schmid@snake.iap.physik.tu-darmstadt.de>
To: bkoz@gcc.gnu.org
Cc: gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org,
philip_martin@ntlworld.com
Subject: Re: libstdc++/3720: Problems with num_get
Date: Sat, 1 Dec 2001 19:08:58 +0100 (CET)
Dear Mr Kosnik,
your proposal is reasonable as far as I understand it.
STLport-4.5, the other libstdc++ implementation I have access to,
restricts the input field for integers to ten decimals, as
defined by the digits10 member, and sets the failbit if there are more
than ten digits on input.
Consider the following source code tcin.C
#include <iostream>
using namespace std;
int main()
{
cout<<"rdstate before reading from cin : "
<< cin.rdstate() << endl;
cout<<"good eof fail bad "
<< ios::goodbit << " "
<< ios::eofbit << " "
<< ios::failbit << " "
<< ios::badbit << endl;
int i;
cin >> i;
cout << "cin state: " << cin.rdstate() << endl;
cout << "i: " << i << endl;
}
./tcin
rdstate before reading from cin : 0
good eof fail bad 0 2 4 1
1234567890
cin state: 0
i: 1234567890
peter@kiste:~> !!
./tcin
rdstate before reading from cin : 0
good eof fail bad 0 2 4 1
12345678901
cin state: 4
i: 2147483647
Hope this helps,
Peter Schmid
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-11-23 8:16 bkoz
0 siblings, 0 replies; 25+ messages in thread
From: bkoz @ 2001-11-23 8:16 UTC (permalink / raw)
To: bkoz; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: bkoz@gcc.gnu.org
To: bkoz@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org,
gcc-prs@gcc.gnu.org, philip_martin@ntlworld.com,
schmid@snake.iap.physik.tu-darmstadt.de
Cc:
Subject: Re: libstdc++/3720: Problems with num_get
Date: 1 Dec 2001 05:17:28 -0000
Synopsis: Problems with num_get
State-Changed-From-To: analyzed->feedback
State-Changed-By: bkoz
State-Changed-When: Fri Nov 30 21:17:27 2001
State-Changed-Why:
Hi Peter, Philip.
I've been thinking about this, and its related bug libstdc++/4402.
I agree this should not core.
Looking at <limits> it looks like the largest number of digits for any numeric input is around 33 characters.
Looking at the relevant part of the standard, I see
22.2.2.1.2 - num_get virtual functions [lib.facet.num.get.virtuals]
-9- If discard is true then the position of the character is remembered, but the character is otherwise ignored. If it is not discarded, then a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by stage 1. If so it is accumulated.
This is sufficiently vague to allow the following plan, which I consider sensible:
numbers are extracted while beg != end and while the number of extracted digits <= numeric_limits<_Type>::digits10().
At that point, we either continue on without setting failbit, or extract one more and set failbit.
The bit of the standard again:
If it is not discarded, then a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by stage 1. If so it is accumulated.
To me, this means that one-past-the type-determined size should be extracted, then not accumulated, and failbit should be set.
Does this sound reasonable?
-benjamin
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-11-23 8:16 bkoz
0 siblings, 0 replies; 25+ messages in thread
From: bkoz @ 2001-11-23 8:16 UTC (permalink / raw)
To: bkoz, gcc-bugs, gcc-gnats, gcc-prs, philip_martin, schmid
Synopsis: Problems with num_get
State-Changed-From-To: analyzed->feedback
State-Changed-By: bkoz
State-Changed-When: Fri Nov 30 21:17:27 2001
State-Changed-Why:
Hi Peter, Philip.
I've been thinking about this, and its related bug libstdc++/4402.
I agree this should not core.
Looking at <limits> it looks like the largest number of digits for any numeric input is around 33 characters.
Looking at the relevant part of the standard, I see
22.2.2.1.2 - num_get virtual functions [lib.facet.num.get.virtuals]
-9- If discard is true then the position of the character is remembered, but the character is otherwise ignored. If it is not discarded, then a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by stage 1. If so it is accumulated.
This is sufficiently vague to allow the following plan, which I consider sensible:
numbers are extracted while beg != end and while the number of extracted digits <= numeric_limits<_Type>::digits10().
At that point, we either continue on without setting failbit, or extract one more and set failbit.
The bit of the standard again:
If it is not discarded, then a check is made to determine if c is allowed as the next character of an input field of the conversion specifier returned by stage 1. If so it is accumulated.
To me, this means that one-past-the type-determined size should be extracted, then not accumulated, and failbit should be set.
Does this sound reasonable?
-benjamin
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: libstdc++/3720: Problems with num_get
@ 2001-08-24 17:37 bkoz
0 siblings, 0 replies; 25+ messages in thread
From: bkoz @ 2001-08-24 17:37 UTC (permalink / raw)
To: bkoz, gcc-bugs, gcc-prs, nobody, schmid
Synopsis: Problems with num_get
Responsible-Changed-From-To: unassigned->bkoz
Responsible-Changed-By: bkoz
Responsible-Changed-When: Fri Aug 24 17:37:18 2001
Responsible-Changed-Why:
Mine.
State-Changed-From-To: open->analyzed
State-Changed-By: bkoz
State-Changed-When: Fri Aug 24 17:37:18 2001
State-Changed-Why:
I've reproduced your bug report. I'm working on a fix, one that hopefully doesn't involve changing the ABI and or including vector.
thanks,
benjamin
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=3720&database=gcc
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2001-12-11 8:06 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-07-17 15:06 libstdc++/3720: Problems with num_get Peter Schmid
2001-08-24 17:37 bkoz
2001-11-23 8:16 bkoz
2001-11-23 8:16 bkoz
2001-12-01 10:16 Peter Schmid
2001-12-01 19:16 Philip Martin
2001-12-05 15:17 bkoz
2001-12-05 15:26 bkoz
2001-12-07 1:11 bkoz
2001-12-07 1:16 bkoz
2001-12-07 10:26 Philip Martin
2001-12-07 16:26 Benjamin Kosnik
2001-12-07 17:36 Philip Martin
2001-12-09 23:46 Benjamin Kosnik
2001-12-10 0:16 Benjamin Kosnik
2001-12-10 11:55 bkoz
2001-12-10 12:06 bkoz
2001-12-10 12:16 Peter Schmid
2001-12-10 14:06 Benjamin Kosnik
2001-12-10 17:06 Philip Martin
2001-12-10 17:16 Benjamin Kosnik
2001-12-10 17:16 Joe Buck
2001-12-10 17:56 Joe Buck
2001-12-10 17:56 Mark Mitchell
2001-12-11 0:06 Mark Mitchell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).