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]

[v3] Fix stringbuf handling of NUL characters


Okay, we'd like for the string class, and related classes such as
{i,o,}stringstreams, to be able to handle NUL characters in their stored
data.  While this has historically been a little wacky in practice,
it's supposed to work.  Right now stringstreams (more precisely, a
basic_stringbuf) cannot be used to store arbitrary data; if the data
contains a NUL, the string is terminated.  See

    http://gcc.gnu.org/ml/gcc-bugs/2001-07/msg00155.html

for the latest bug report, and

    http://gcc.gnu.org/ml/gcc-bugs/2001-07/msg00184.html

for my analysis, which turned out to be carefully wrong.

I mistakenly thought the problem was string::size().  Fortunately, size()
is not so stupid that it tries to calculate a length (and thus possibly
trip over a NUL).  What threw me was that I was calling size() on two
different strings.  They /should/ be exact copies, but they aren't:

- If a string (well, basic_string<char>) is constructed from a character
  pointer and an explicit length N, then exactly N characters are copied
  and the size is (blindly, correctly) stored as N by our implementation
  of basic_string.

- If a string is constructed from only a character pointer, then the length
  is determined via strlen(); only that many characters are stored and
  that's what is remembered as the size.

When a stringbuf is constructed with an initial string value, we create
a copy of the incoming string, but to create the copy we use the second
method, not the first.  Thus, the stringbuf's copy will only contain data
up to the first NUL byte.  Whoops.  Obvious in retrospect.


This simple fix gives us correct behavior, both for the original bug
reporter's test case (gcount = 4, dest = 12340078, good = 1, state = 0),
and maintains parity on the libstdc++ testsuite.

I'll check this in tommorow once I have a testcase constructed (probably
just the original bug report test, slightly modified).  Permission to
apply this to the branch as well?

Phil


Index: std_sstream.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/std_sstream.h,v
retrieving revision 1.7
diff -u -3 -r1.7 std_sstream.h
--- std_sstream.h	2001/06/12 22:14:08	1.7
+++ std_sstream.h	2001/07/12 02:52:25
@@ -75,7 +75,7 @@
       explicit 
       basic_stringbuf(const __string_type& __str,
 		      ios_base::openmode __mode = ios_base::in | ios_base::out)
-      : __streambuf_type(), _M_string(__str.c_str())
+      : __streambuf_type(), _M_string(__str.c_str(), __str.size())
       { _M_stringbuf_init(__mode); }
 
       // Get and set:


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