Article View: gnu.g++.lib.bug
Article #450Re: 2.3: width(x) off by 1 for istreams
From: bothner
Date: Thu, 21 Jan 1993 23:22
Date: Thu, 21 Jan 1993 23:22
186 lines
5645 bytes
5645 bytes
> The width attribute of an istream is supposed to limit the number of
> characters read into a char* variable to prevent overflowing a buffer.
The following patch should fix this. It also should suppress
print of '+' for unsigned values.
--Per Bothner
Cygnus Support bothner@cygnus.com
===================================================================
RCS file: /rel/cvsfiles/devo/libg++/iostream/iostream.C,v
retrieving revision 1.34
diff -c -r1.34 iostream.C
*** 1.34 1993/01/17 02:08:11
--- iostream.C 1993/01/21 22:33:33
***************
*** 157,163 ****
set(ios::eofbit|ios::failbit);
else {
int w = width(0);
! *ptr++ = ch;
for (;;) {
ch = sb->sbumpc();
if (ch == EOF) {
--- 157,163 ----
set(ios::eofbit|ios::failbit);
else {
int w = width(0);
! sb->sputbackc(ch);
for (;;) {
ch = sb->sbumpc();
if (ch == EOF) {
***************
*** 342,348 ****
return *this;
}
! static void write_int(ostream& stream, unsigned LONGEST val, int neg)
{
#define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3)
char buf[WRITE_BUF_SIZE];
--- 342,353 ----
return *this;
}
! /* Write VAL on STREAM.
! If SIGN<0, val is the absolute value of a negative number.
! If SIGN>0, val is a signed non-negative number.
! If SIGN==0, val is unsigned. */
!
! static void write_int(ostream& stream, unsigned LONGEST val, int sign)
{
#define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3)
char buf[WRITE_BUF_SIZE];
***************
*** 349,354 ****
--- 354,360 ----
register char *buf_ptr = buf+WRITE_BUF_SIZE; // End of buf.
char *show_base = "";
int show_base_len = 0;
+ int show_pos = 0; // If 1, print a '+'.
// Now do the actual conversion, placing the result at the *end* of buf.
// Note that we use separate code for decimal, octal, and hex,
***************
*** 374,379 ****
--- 380,387 ----
}
}
else { // Decimal
+ if (val != 0 && sign > 0 && (stream.flags() & ios::showpos))
+ show_pos=1;
#ifdef __GNUC__
// Optimization: Only use long long when we need to.
while (val > UINT_MAX) {
***************
*** 393,404 ****
int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
int w = stream.width(0);
- int show_pos = 0;
// Calculate padding.
! int len = buf_len;
! if (neg) len++;
! else if (val != 0 && (stream.flags() & ios::showpos)) len++, show_pos=1;
len += show_base_len;
int padding = len > w ? 0 : w - len;
--- 401,410 ----
int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
int w = stream.width(0);
// Calculate padding.
! int len = buf_len+show_pos;
! if (sign < 0) len++;
len += show_base_len;
int padding = len > w ? 0 : w - len;
***************
*** 411,417 ****
&& pad_kind != (ios::fmtflags)ios::left
&& pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
sbuf->padn(fill_char, padding);
! if (neg) sbuf->sputc('-');
else if (show_pos) sbuf->sputc('+');
if (show_base_len)
sbuf->sputn(show_base, show_base_len);
--- 417,423 ----
&& pad_kind != (ios::fmtflags)ios::left
&& pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
sbuf->padn(fill_char, padding);
! if (sign < 0) sbuf->sputc('-');
else if (show_pos) sbuf->sputc('+');
if (show_base_len)
sbuf->sputn(show_base, show_base_len);
***************
*** 426,435 ****
ostream& ostream::operator<<(int n)
{
if (opfx()) {
! int neg = 0;
if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
! n = -n, neg = 1;
! write_int(*this, n, neg);
}
return *this;
}
--- 432,441 ----
ostream& ostream::operator<<(int n)
{
if (opfx()) {
! int sign = 1;
if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
! n = -n, sign = -1;
! write_int(*this, n, sign);
}
return *this;
}
***************
*** 445,454 ****
ostream& ostream::operator<<(long n)
{
if (opfx()) {
! int neg = 0;
if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
! n = -n, neg = 1;
! write_int(*this, n, neg);
}
return *this;
}
--- 451,460 ----
ostream& ostream::operator<<(long n)
{
if (opfx()) {
! int sign = 1;
if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
! n = -n, sign = -1;
! write_int(*this, n, sign);
}
return *this;
}
***************
*** 464,473 ****
ostream& ostream::operator<<(long long n)
{
if (opfx()) {
! int neg = 0;
if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
! n = -n, neg = 1;
! write_int(*this, n, neg);
}
return *this;
}
--- 470,479 ----
ostream& ostream::operator<<(long long n)
{
if (opfx()) {
! int sign = 1;
if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
! n = -n, sign = -1;
! write_int(*this, n, sign);
}
return *this;
}
Technical Details
Message-ID:
<9301212244.AA18937@cygnus.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!paladin.american.edu!howland.reston.ans.net!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!cis.ohio-state.edu!cygnus.com!bothnerReferences:
<9301201947.AA01121@cs.rice.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!paladin.american.edu!howland.reston.ans.net!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!cis.ohio-state.edu!cygnus.com!bothner From: bothner@cygnus.com Newsgroups: gnu.g++.lib.bug Subject: Re: 2.3: width(x) off by 1 for istreams Date: 21 Jan 1993 18:22:51 -0500 Organization: GNUs Not Usenet Lines: 187 Sender: daemon@cis.ohio-state.edu Approved: bug-lib-g++@prep.ai.mit.edu Distribution: gnu Message-ID: <9301212244.AA18937@cygnus.com> References: <9301201947.AA01121@cs.rice.edu>