This is the mail archive of the libstdc++@sourceware.cygnus.com 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]

patch -- more fstream.tcc funkiness



It would save time now if we all went insane, don't you think?

Here's the testcase that I keep using:

    #include <fstream>

    int main ()
    {
        std::ifstream  IN ("input_file");
        std::ofstream  OUT ("output_file");

        //OUT << "this is a test\n";
        OUT << IN.rdbuf();// << std::flush;
    }

After the patch I sent last Thursday, this testcase worked.  I now have
current CVS soruces plus my patch...

Today, how's this for fun:  only the first 4 characters of input_file
are copied.  The remaining N-4 characters are in fact allocated and 
written to output_file, but they are NUL's rather than the correct data.

The patch is here.  Explanation follows.  Appended is the testsuite
results (filebuf tests remain pass/pass/fail after this patch).


1999-06-08  Phil Edwards  <pedwards@ball.com>

	* bits/fstream.tcc (basic_filebuf::underflow):  Fix, rename local vars.



Index: bits/fstream.tcc
===================================================================
RCS file: /cvs/libstdc++/libstdc++/bits/fstream.tcc,v
retrieving revision 1.21
diff -c -3 -r1.21 fstream.tcc
*** fstream.tcc	1999/06/03 00:47:35	1.21
--- fstream.tcc	1999/06/08 22:38:02
***************
*** 209,227 ****
  	      
  	      char* __conv_cur = __conv_buf;
  	      _M_state_beg = _M_state_cur;
! 	      __res_type __r = _M_fcvt->in(_M_state_cur, 
  					__conv_buf,
  					__conv_buf + __r,
  					const_cast<const char*&>(__conv_cur), 
  					_M_in_beg, _M_in_end, _M_in_cur);
  	      
! 	      if (__r == codecvt_base::partial)
  		{
  		  // XXX Retry with larger _M_buf size.
  		}
  	      
  	      // Set pointers to internal and external buffers correctly. . .
! 	      if (__r != codecvt_base::error)
  		{
  		  if (_M_mode & ios_base::out)
  		    _M_out_cur = _M_in_cur;
--- 209,227 ----
  	      
  	      char* __conv_cur = __conv_buf;
  	      _M_state_beg = _M_state_cur;
! 	      __res_type __R = _M_fcvt->in(_M_state_cur, 
  					__conv_buf,
  					__conv_buf + __r,
  					const_cast<const char*&>(__conv_cur), 
  					_M_in_beg, _M_in_end, _M_in_cur);
  	      
! 	      if (__R == codecvt_base::partial)
  		{
  		  // XXX Retry with larger _M_buf size.
  		}
  	      
  	      // Set pointers to internal and external buffers correctly. . .
! 	      if (__R != codecvt_base::error)
  		{
  		  if (_M_mode & ios_base::out)
  		    _M_out_cur = _M_in_cur;
===================================================================

At the call to _M_fcvt->in, the __r being passed is the size of the
buffer.  The results of the call are assigned to a new __r of completely
different type (a return status enum).  The new __r /should/ be safe,
since it's a more local scope and /should/ hide the __r declared a few
lines earlier.

It doesn't.  Why it didn't before is beyond me; this code doesn't seem
to have been touched in a while according to cvsweb.  The __r being
passed in is /always/ given the value 4, rather than the variable size,
which means that only 4 bytes of valid data are copied into an array
that is correctly-sized everywhere else.

The patch simply changes the new __r to __R, and the testcase above
works again.  While the shadowing of names whould work, it looks to
be more "cute" than what the compiler could handle, and difficult
as hell to read in later scopes in the same function.


Phil
(If you reply to the list, please don't cc another copy to me.  Thanks!)



host: Linux 2.2.5 #1 Wed Apr 7 10:42:48 EDT 1999 i586
compiler: egcs-2.93.21
compiler flags: -g -O2 -DDEBUG_ASSERT 

time	exec	text	data	total	name	
4	pass	70740	15573	420295	header_ciso646.st-exe

3	fail	0	0	0	headers.st-exe

16	pass	98762	16364	757653	capacity.st-exe

4	pass	91914	16236	615129	char_traits.st-exe

7	pass	94890	16396	651352	compare.st-exe

9	pass	94858	16460	669427	ctor_copy_dtor.st-exe

4	fail	0	0	0	element_access.st-exe

12	pass	97178	16972	692794	insert.st-exe

8	pass	96538	16300	642369	nonmember.st-exe

7	pass	92698	16257	643058	operations.st-exe

6	pass	89802	16012	590563	vector_capacity.st-exe

29	pass	101562	16268	791488	iterator.st-exe

1	pass	70884	15473	428854	modf_float.st-exe

6	pass	86842	15933	561408	valarray.st-exe

31	pass	368966	32428	2599145	boolfmt.st-exe

26	fail	370866	32268	2535315	filebuf.st-exe

19	pass	357190	32268	2487856	ios_members_static.st-exe

1	fail	0	0	0	iostream_objects.st-exe

30	pass	367110	32652	2579170	istringstream_formatted.st-exe

26	pass	365430	32460	2568388	octfmt.st-exe

65	pass	376594	32460	2669004	stringbuf.st-exe

36	pass	366774	32588	2574982	stringstream.st-exe



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