This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[libstdc++ 3.0] alternative 3.0-branch patch for PR 3720
- From: Joe Buck <jbuck at synopsys dot COM>
- To: mark at codesourcery dot com (Mark Mitchell), gcc-patches at gcc dot gnu dot org
- Cc: bkoz at redhat dot com
- Date: Mon, 10 Dec 2001 16:47:49 -0800 (PST)
- Subject: [libstdc++ 3.0] alternative 3.0-branch patch for PR 3720
I foolishly wrote:
> > In any case, I'll get you something today.
Mark:
> Thanks!
This is the one where the following program crashes:
#include <iostream>
int main() {
int i;
std::cin >> i;
}
if the user just types a whole lot of digits.
OK, here's the problem. Backporting Ben's patch would break the ABI. This
begs the question, is there something else we can do?
In any case, what I notice is that in locale_facets.tcc, every single
call to _M_extract passes a 32-char array as the argument that accumulates
characters. There are no other calls to this _M_extract. So, why not
move the limit down into _M_extract?
Here is my suggested extremely bad hack. Before anyone objects to the
magic number "31", take a look at locale_facets.tcc and all the uses of
"32". Don't we have a rule about such things?
At least in the case of cin >> intvar it blocks the crash. However, I
freely admit that it is a kludge. All I can say in its defense is that
I can promise that it doesn't change the ABI, and it even improves
things for programs already built with 3.0 through 3.0.2 (if the
new libstdc++ is installed).
The other advantage of this patch is that you can accept it without
papers, because of its small size: 5 code lines, two of which contain
only a curly.
My standard at this late date is
1) is it safe?
2) does it make things better?
so I think that this makes it, even if it's far from perfect.
So, without further ado:
------------------------------------------------------------------
2001-12-10 Joe Buck <jbuck@synopsys.com>
PR libstdc++/3720 (different from fix on trunk, to preserve the ABI)
* src/locale.cc (_M_extract): Avoid buffer overrun.
Index: locale.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/src/locale.cc,v
retrieving revision 1.28.2.4
diff -c -r1.28.2.4 locale.cc
*** locale.cc 2001/07/20 00:14:10 1.28.2.4
--- locale.cc 2001/12/11 00:27:20
***************
*** 774,779 ****
--- 774,791 ----
bool __testunits = __testzero;
while (__beg != __end)
{
+
+ // very bad hack: __xtrc is always a 32-char array, and nothing
+ // checks for overruns. Do it this way to fail if someone types
+ // 32 or more digits. This is a temporary fix to avoid breaking
+ // the 3.0.x library ABI. The stream may not be left in the
+ // right position, but at least we don't crash.
+ if (__pos >= 31)
+ {
+ __err |= ios_base::failbit;
+ return;
+ }
+
const char* __p = strchr(__lits, __c);
// NB: strchr returns true for __c == 0x0