
John Nagle wrote:
Reece Dunn wrote:
John Nagle wrote:
Reece Dunn wrote:
There is currently a static-sized array in the Boost library that allows you to operate on arrays of fixed size. I was wondering if something similar exists for strings, in particular, providing buffer-overflow safe string operations.
I have an nstring< std::size_t n > string class that provides size-safe copying and comparison, allowing for you to do things like:
OK, thanks. First bug reports:
1. Compile problems under VC++ 6: No include brings in "std::size_t".
Fixed.
2. VC++ 6.x complains about references to a zero-sized array for [edit]: copy( const char( & s )[ m ] )
I have disabled these for VC6 since they are causing problems with the compiler, even with Thorsten Ottersen's workaround :(.
3. "copy" function does not place a trailing null in the string. [snip] Note that "strlen" returns a count that does NOT contain the null.
I have added this facility as a template parameter (bool null_terminate). The logic behind this is when you do not specifically need a null-terminated string, e.g.: struct JPEGHeader { // ... boost::string::char_string< 4 > magic; // ... } hdr; if( hdr.magic != "JPEG" ) error( "invalid format" ); but also to allow it if you need that security.
All the operations should guarantee that the string remains null terminated. A constructor should be provided, but all it has to do is put a null in the first character position.
I have already provided such a constructor :).
As for the naming issue, the important thing for retrofit work is that it should be possible to write a "using" statement that makes "strcopy", "sprintf", for char_string etc. valid without prefixes, and doesn't break anything else. You should be able to include something ("safe_strings.hpp"?) that does as much as possible to fix old code.
I have moved the char_string class into char_string.hpp and started work on providing safe versions of ::strXXX. It is not possible to use the same names (strlen, etc.) for the char_string versions :( as can be seen in the example below. #include <iostream> #include <cstring> namespace boost { namespace string { using ::strcpy; inline char * strcpy( char * d, const char * s, size_t n ) { return( ::strncpy( d, s, n )); } }} int main() { char str[ 100 ]; using boost::string::strcpy; ::strcpy( str, "Meine Welt!" ); std::cout << str << '\n'; ::strcpy( str, "1234567890", 5 ); // error std::cout << str << '\n'; return( 0 ); } Because of this, I have decided to use the c prefix (e.g. cstrlen). This seems the best solution, but if the c prefix is problematic, let me know and I'll change it.
This is a good start, and not hard to fix. I look forward to the next round.
I have included this round as attachments, but will place the next version in the boost sandbox. It has the signature: template< size_t n, bool null_terminate = true, typename CharT = char, class StringPolicy = std::char_traits< CharT > > class boost::string::char_string; and is the initial move towards a basic_string-like interface. How about the name fixed_string? Regards, Reece _________________________________________________________________ It's fast, it's easy and it's free. Get MSN Messenger today! http://www.msn.co.uk/messenger