nkzxw / ontl

Automatically exported from code.google.com/p/ontl
0 stars 0 forks source link

std::basic_string compare with c-string bug #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

See an example:
int main()
{
  std::string test("str");
  return test == "str\0somegarbagedata";
}

What is the expected output?
`main` return code must be 1, because `test` compared with plain c string, 
which length must be 3 in this case.

What do you see instead?
`main` return code is 0, because basic_string::compare(const charT*) 
compares character placed after '\0' with '\0' (this is fourth character 
's').

How to fix?
Index: string.hxx
===================================================================
--- string.hxx  (revision 36)
+++ string.hxx  (working copy)
@@ -549,7 +549,7 @@
     {
       const int r = traits_type::compare(begin(), s, size());
       // s may be longer than *this
-      return r != 0 ? r : traits_type::eq(s[size()+1], charT()) ? r : r - 
1; // r == 0 here
+      return r != 0 ? r : traits_type::eq(s[size()], charT()) ? r : r - 
1; // r == 0 here
     }

     int compare(size_type pos1, size_type n1, const charT* s) const;

Original issue reported on code.google.com by icestudent@gmail.com on 15 Dec 2007 at 6:15

GoogleCodeExporter commented 9 years ago
Unfortunatelly the problem is a bit deeper.

Accordind to 21.3.6.8/5 the function shall return this-
>compare(basic_string<charT,traits,Allocator>(s));

Because a constructor call is actually ommited, the comparision may be done 
against 
a C string with embedded '\0's.

Original comment by ntl.supp...@gmail.com on 16 Dec 2007 at 1:47

GoogleCodeExporter commented 9 years ago

Original comment by icestudent@gmail.com on 16 Dec 2007 at 7:36

GoogleCodeExporter commented 9 years ago
The bugfix shall be all right. traits_type::compare uses strncmp which is aware 
of 
embedded '\0' so temporary basic_string constructor is emulated correctly. 
Expected 
behavior should be as defined by the Standard.

However the problem I've mentioned above is really deeper in NTL and may affect 
this 
function clients.
For example one may retrieve std::wstring (with '\0' at the and) from a 
registry key 
value and use operator==. It will give -1 with "reg_sz\0" and "reg_sz".

Original comment by ntl.supp...@gmail.com on 17 Jan 2008 at 4:24

GoogleCodeExporter commented 9 years ago

Original comment by icestudent@gmail.com on 10 Sep 2008 at 7:04