This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] Fix libstdc++/9439 and libstdc++/9425


Hi,

so here it is. In fact, these changes _should_ be pretty
safe: basic_filebuf::seekoff is currently the _only_ user
of _M_file.seekoff return value and we always do the same
as before when _M_file.seekoff doesn't fail.

However, it may turn out to be useful elsewhere to start
checking _M_file.seekoff return value...

Tested x86-linux, as usual. Ok for trunk? 3_3 too?

Paolo.

///////////
2003-02-04  Paolo Carlini  <pcarlini@unitus.it>
	
	PR libstdc++/9439, PR libstdc++/9425
	* config/io/basic_file_stdio.cc
	(__basic_file<char>::seekoff, seekpos): Return -1L if
	fseek fails.
	* include/bits/fstream.tcc (basic_filebuf::seekoff):
	Check _M_file.seekoff return value; always return
	pos_type(off_type(-1)) in case of failure.
	(basic_filebuf::pbackfail): Check this->seekoff return
	value and return traits_type::eof() in case of failure.  
	* testsuite/27_io/filebuf_virtuals.cc (test09): Add.

diff -prN libstdc++-v3-orig/config/io/basic_file_stdio.cc libstdc++-v3/config/io/basic_file_stdio.cc
*** libstdc++-v3-orig/config/io/basic_file_stdio.cc	Tue Dec 24 03:48:19 2002
--- libstdc++-v3/config/io/basic_file_stdio.cc	Tue Feb  4 19:32:02 2003
*************** namespace std 
*** 203,217 ****
    __basic_file<char>::seekoff(streamoff __off, ios_base::seekdir __way, 
  			      ios_base::openmode /*__mode*/)
    { 
!     fseek(_M_cfile, __off, __way); 
!     return ftell(_M_cfile); 
    }
  
    streamoff
    __basic_file<char>::seekpos(streamoff __pos, ios_base::openmode /*__mode*/)
    { 
!     fseek(_M_cfile, __pos, ios_base::beg); 
!     return ftell(_M_cfile); 
    }
    
    int 
--- 203,223 ----
    __basic_file<char>::seekoff(streamoff __off, ios_base::seekdir __way, 
  			      ios_base::openmode /*__mode*/)
    { 
!     if (!fseek(_M_cfile, __off, __way))
!       return ftell(_M_cfile); 
!     else
!       // Fseek failed.
!       return -1L;
    }
  
    streamoff
    __basic_file<char>::seekpos(streamoff __pos, ios_base::openmode /*__mode*/)
    { 
!     if (!fseek(_M_cfile, __pos, ios_base::beg))
!       return ftell(_M_cfile);
!     else
!       // Fseek failed.
!       return -1L;
    }
    
    int 
diff -prN libstdc++-v3-orig/include/bits/fstream.tcc libstdc++-v3/include/bits/fstream.tcc
*** libstdc++-v3-orig/include/bits/fstream.tcc	Mon Feb  3 21:20:42 2003
--- libstdc++-v3/include/bits/fstream.tcc	Tue Feb  4 22:33:23 2003
*************** namespace std
*** 215,233 ****
  	    {	 
   	      // At the beginning of the buffer, need to make a
  	      // putback position available.
! 	      this->seekoff(-1, ios_base::cur);
! 	      this->underflow();
!  	      if (!__testeof)
!  		{
! 		  if (!traits_type::eq(__c, *this->_M_in_cur))
  		    {
! 		      _M_pback_create();
! 		      *this->_M_in_cur = __c;
  		    }
!  		  __ret = __i;
!  		}
!  	      else
!  		__ret = traits_type::not_eof(__i);
   	    }
  	}
        _M_last_overflowed = false;	
--- 215,238 ----
  	    {	 
   	      // At the beginning of the buffer, need to make a
  	      // putback position available.
! 	      // But the seek may fail (f.i., at the beginning of
! 	      // a file, see libstdc++/9439) and in that case
! 	      // we return traits_type::eof()
! 	      if (this->seekoff(-1, ios_base::cur) >= 0)
! 		{
! 		  this->underflow();
! 		  if (!__testeof)
  		    {
! 		      if (!traits_type::eq(__c, *this->_M_in_cur))
! 			{
! 			  _M_pback_create();
! 			  *this->_M_in_cur = __c;
! 			}
! 		      __ret = __i;
  		    }
! 		  else
! 		    __ret = traits_type::not_eof(__i);
! 		}
   	    }
  	}
        _M_last_overflowed = false;	
*************** namespace std
*** 439,445 ****
  	      //in
  	      else if (__testget && __way == ios_base::cur)
  		__computed_off += this->_M_in_cur - _M_filepos;
! 	  
  	      __ret = _M_file.seekoff(__computed_off, __way, __mode);
  	      _M_set_indeterminate();
  	    }
--- 444,451 ----
  	      //in
  	      else if (__testget && __way == ios_base::cur)
  		__computed_off += this->_M_in_cur - _M_filepos;
! 
! 	      // Return pos_type(off_type(-1)) in case of failure.
  	      __ret = _M_file.seekoff(__computed_off, __way, __mode);
  	      _M_set_indeterminate();
  	    }
*************** namespace std
*** 447,455 ****
  	  // state, ie _M_file._offset == -1
  	  else
  	    {
! 	      __ret = _M_file.seekoff(__off, ios_base::cur, __mode);
! 	      __ret +=
! 		std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos;
  	    }
  	}
        _M_last_overflowed = false;	
--- 453,464 ----
  	  // state, ie _M_file._offset == -1
  	  else
  	    {
! 	      pos_type __tmp =
! 		_M_file.seekoff(__off, ios_base::cur, __mode);
! 	      if (__tmp >= 0)
! 		// Seek successful.
! 		__ret = __tmp +
! 		  std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos;
  	    }
  	}
        _M_last_overflowed = false;	
diff -prN libstdc++-v3-orig/testsuite/27_io/filebuf_virtuals.cc libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc
*** libstdc++-v3-orig/testsuite/27_io/filebuf_virtuals.cc	Sun Feb  2 20:02:54 2003
--- libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc	Tue Feb  4 21:04:38 2003
*************** void test08()
*** 570,575 ****
--- 570,589 ----
    mb.sputbackc(0);  
  }
  
+ // libstdc++/9439, libstdc++/9425
+ void test09()
+ {
+   using namespace std;
+   bool test = true;
+ 
+   filebuf fbuf;
+   fbuf.open(name_01, ios_base::in);
+   filebuf::int_type r = fbuf.sputbackc('a');
+   fbuf.close();
+ 
+   VERIFY( r == filebuf::traits_type::eof() );
+ }
+ 
  main() 
  {
    test01();
*************** main() 
*** 582,586 ****
--- 596,601 ----
  
    test07();
    test08();
+   test09();
    return 0;
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]