This bug exists in all versions of glibc. Given 3 strings, string_A: "B0075022800016.gbp.corp.com" string_B: "B007502280067.gbp.corp.com" string_C: "B007502357019.GBP.CORP.COM", Using strverscmp() on these 3 strings, get the following result: string_A < string_B < string_C < string_A where string_C < string_A is wrong because .0075022800016 < .007502357019 (the leading . is for fractionnal number because from man page a '.' should be added before leading 0's). I have a fix for this: Index: string/strverscmp.c =================================================================== RCS file: /cvs/glibc/libc/string/strverscmp.c,v retrieving revision 1.6 diff -u -r1.6 strverscmp.c --- string/strverscmp.c 4 Aug 2002 09:14:35 -0000 1.6 +++ string/strverscmp.c 27 Feb 2009 19:58:55 -0000 @@ -69,7 +69,7 @@ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, /* S_I */ CMP, -1, -1, CMP, +1, LEN, LEN, CMP, +1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, - /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, + /* S_F */ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, /* S_Z */ CMP, +1, +1, CMP, -1, CMP, CMP, CMP, -1, CMP, CMP, CMP [The reason is that after entring state S_F, CMP should be the only option to compare strings.]
I applied the patch.
Unfortunately this broke something more important: #include <string.h> #include <stdio.h> int main () { int rc = strverscmp ("2.6.21", "2.6.20"); printf ("2.6.21 %s 2.6.20\n", (rc < 0 ? "<" : rc == 0 ? "=" : ">")); rc = strverscmp ("2.6.20", "2.6.21"); printf ("2.6.20 %s 2.6.21\n", (rc < 0 ? "<" : rc == 0 ? "=" : ">")); } now prints: 2.6.21 < 2.6.20 2.6.20 < 2.6.21 while it used to correctly print: 2.6.21 > 2.6.20 2.6.20 < 2.6.21 Seems it wasn't the change in proposed in the original comment, but the follow-up cleanups.
Fixed in cvs.