You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2005/11/17 00:33:03 UTC

svn commit: r345148 - /incubator/stdcxx/trunk/include/istream.cc

Author: sebor
Date: Wed Nov 16 15:32:58 2005
New Revision: 345148

URL: http://svn.apache.org/viewcvs?rev=345148&view=rev
Log:
2005-11-16  Martin Sebor  <se...@roguewave.com>

	STDCXX-59
	STDCXX-67
	* istream.cc (getline): Renamed function formal arguments for clarity.
	Prevented the function from writing past the end of a zero-size buffer
	(thus reverting a partial regression introduced in revision 328966).

Modified:
    incubator/stdcxx/trunk/include/istream.cc

Modified: incubator/stdcxx/trunk/include/istream.cc
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/include/istream.cc?rev=345148&r1=345147&r2=345148&view=diff
==============================================================================
--- incubator/stdcxx/trunk/include/istream.cc (original)
+++ incubator/stdcxx/trunk/include/istream.cc Wed Nov 16 15:32:58 2005
@@ -664,16 +664,25 @@
 template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::
-getline (char_type *__s, streamsize __n, char_type __delim)
+getline (char_type *__line, streamsize __size, char_type __delim)
 {
-    _RWSTD_ASSERT (__n >= 0);
-    _RWSTD_ASSERT (!__n || __s);
+    _RWSTD_ASSERT (__size >= 0);
+    _RWSTD_ASSERT (!__size || __line);
     _RWSTD_ASSERT (0 != this->rdbuf ());
 
-    if (0 < __n) {
+    char_type __dummy;
+
+    if (0 < __size) {
         // lwg issue 243: store the NUL character before
         // constructing the sentry object in case it throws
-        traits_type::assign (__s [0], char_type ());
+        traits_type::assign (__line [0], char_type ());
+    }
+    else {
+        // use a dummy buffer to avoid having to check size
+        // again below, and prevent undefined behavior when
+        // size is negative
+        __line = &__dummy;
+        __size = 0;
     }
 
     const sentry __ipfx (*this, true /* noskipws */);
@@ -695,8 +704,8 @@
                 // compute the lesser of the number of characters in the
                 // stream buffer and the size of the destination buffer
                 streamsize __navail = __egptr - __gptr;
-                if (__n < __navail)
-                    __navail = __n;
+                if (__size < __navail)
+                    __navail = __size;
 
                 if (__navail) {
 
@@ -706,16 +715,16 @@
 
                     if (__pdel) {
                         __navail = __pdel - __gptr + 1;
-                        __n     -= __navail - 1;
+                        __size  -= __navail - 1;
                     }
-                    else if (__n == __navail)
-                        __n -= --__navail;
+                    else if (__size == __navail)
+                        __size -= --__navail;
                     else
-                        __n -= __navail;
+                        __size -= __navail;
 
                     // copy including delimiter, if any
                     // (delimiter will be overwritten below)
-                    traits_type::copy (__s + _C_gcount, __gptr, __navail);
+                    traits_type::copy (__line + _C_gcount, __gptr, __navail);
 
                     _C_gcount += __navail;
 
@@ -723,13 +732,14 @@
                     __rdbuf->gbump (__navail);
 
                     if (__pdel) {
-                        __n = _C_gcount - 1;
+                        traits_type::assign (__line [_C_gcount - 1],
+                                             char_type ());
                         break;
                     }
 
-                    if (2 > __n && __egptr - __gptr != __navail) {
+                    if (2 > __size && __egptr - __gptr != __navail) {
+                        traits_type::assign (__line [_C_gcount], char_type ());
                         __err = ios_base::failbit;
-                        __n   = _C_gcount;
                         break;
                     }
                 }
@@ -740,26 +750,27 @@
                     const int_type __c = __rdbuf->sgetc ();
 
                     if (traits_type::eq_int_type (__c, traits_type::eof ())) {
+                        traits_type::assign (__line [_C_gcount], char_type ());
                         __err = ios_base::eofbit;
-                        __n   = _C_gcount;
                         break;
                     }
 
                     const char_type __ch = traits_type::to_char_type (__c);
                     if (traits_type::eq (__ch, __delim)) {
+                        traits_type::assign (__line [_C_gcount], char_type ());
                         __rdbuf->sbumpc ();
-                        __n = _C_gcount++;
+                        _C_gcount++;
                         break;
                     }
 
-                    if (2 > __n) {
+                    if (2 > __size) {
+                        traits_type::assign (__line [_C_gcount], char_type ());
                         __err = ios_base::failbit;
-                        __n   = _C_gcount;
                         break;
                     }
 
-                    traits_type::assign (__s [_C_gcount], __ch);
-                    --__n;
+                    traits_type::assign (__line [_C_gcount], __ch);
+                    --__size;
 
                     __rdbuf->sbumpc ();
 
@@ -776,9 +787,7 @@
         }
     }
 
-    if (0 < _C_gcount)
-        traits_type::assign (__s [_C_gcount + 1], char_type ());
-    else
+    if (0 == _C_gcount)
         __err |= ios_base::failbit;
 
     if (__err)