Bug 9913 - libc's function strverscmp() has a bug
Summary: libc's function strverscmp() has a bug
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-02-27 20:01 UTC by Jingyu Liu
Modified: 2016-08-29 20:15 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jingyu Liu 2009-02-27 20:01:13 UTC
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.]
Comment 1 Ulrich Drepper 2009-03-14 20:15:29 UTC
I applied the patch.
Comment 2 Jakub Jelinek 2009-04-07 06:08:13 UTC
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.
Comment 3 Ulrich Drepper 2009-04-07 06:52:09 UTC
Fixed in cvs.