incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <se...@roguewave.com>
Subject Re: rw_match() bug
Date Tue, 27 Jun 2006 21:26:08 GMT
Martin Sebor wrote:
> Anton Pevtsov wrote:
> 
>> Hmm, I've tried with several tests and your changes to char.cpp and I
>> passed the tdata.reslen_ (the length of the expanded result string) as
>> the third argument. But I'll verify this more deeply.
> 
> 
> Well, yes, passing in the length of the expanded string will
> work.

Actually, I take it back. It might work but it wouldn't be safe.
We really need to pass the lengths of both strings to rw_match()
to make it safe. Passing in the length just one of them might
cause the function to access characters past the end of the other.

For example, given s1 = "abc\0def" and s2 = "abc", passing in
(sizeof(s1) - 1) will try to read s2[4] (i.e., the character
immediately past the terminating NUL, whatever it might be).

The only way to make rw_match() safe w/o changing the interface
of the function is to pass in the actual length of one of the
strings as the third argument and encode the length of the other
in the string itself. Since the first string (s1) is typically
the hardcoded one and the second one the result of the tested
basic_string function, we could encode the length of s1 in it and
pass the length of s2 as the third argument. A good way to encode
the length of s1 in the string itself is to rely on the terminating
NUL. Using the NUL as the terminator means that we cannot embed
any other NULs in the string but since we need to test strings
with embedded NULs in them we need the directive to represent them.
Unfortunately, though, this approach means a lot of changes to each
string test, one for each test case with an embedded NUL in it :(

The other possible approach is to change the signature of rw_match()
to take an additional size_t argument with the size of the other
string, either like this:

     size_t rw_match(const char *s1, size_t s1_len,
                     const char *s2, size_t s2_len);

or like this:

     size_t rw_match(const char *s1, const char *s2,
                     size_t s1_len, size_t s2_len);

This approach would require fewer changes to the tests but seems
less elegant (for lack of a better word). What's your opinion?

Martin

Mime
View raw message