This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[v3] Fix stringbuf handling of NUL characters
- To: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Subject: [v3] Fix stringbuf handling of NUL characters
- From: Phil Edwards <pedwards at disaster dot jaj dot com>
- Date: Wed, 11 Jul 2001 22:54:04 -0400
- Cc: Mathew Pitchforth <mathew at pandromeda dot com>
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: