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]

Re: [v3] Fix stringbuf handling of NUL characters


At 10:54 PM 11/07/2001 -0400, Phil Edwards wrote:
>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.
[snip]
>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:

Just looking at this patch at face value, I would have thought that
__str.data() would be better to use in this situation. Without referring
to the exact wording of the standard, I would argue that the results of
c_str() are undefined if the string contains NUL characters -- it does,
after all, return a C-style string which is NUL-terminated (and thus
one could argue nothing after that NUL is valid). On the other hand,
data() specifically returns the string data as-is, and doesn't bother
to NUL-terminate it.

Only a minor nit-pick.

Regards,

  - Andrew Snare



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