~ubuntu-branches/ubuntu/maverick/gnutls26/maverick-updates

« back to all changes in this revision

Viewing changes to lib/gl/strverscmp.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Metzler
  • Date: 2009-08-14 19:14:29 UTC
  • mfrom: (1.1.7 upstream) (12.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090814191429-6hovzz3oaqq101rm
Tags: 2.8.3-1
* New upstream version.
  + Stops hardcoding a hard dependency on the versions of gcrypt and tasn it
    was built against. Closes: #540449
  + Fixes CVE-2009-2730, a vulnerability related to NUL bytes in X.509
    certificate name fields. Closes: #541439        GNUTLS-SA-2009-4
    http://lists.gnu.org/archive/html/help-gnutls/2009-08/msg00011.html
* Drop 15_chainverify_expiredcert.diff, included upstream.
* Urgency high, since 541439 applies to testing, too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Compare strings while treating digits characters numerically.
 
2
   Copyright (C) 1997, 2000, 2002, 2004, 2006 Free Software Foundation, Inc.
 
3
   This file is part of the GNU C Library.
 
4
   Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
 
5
 
 
6
   This program is free software; you can redistribute it and/or modify
 
7
   it under the terms of the GNU Lesser General Public License as published by
 
8
   the Free Software Foundation; either version 2.1, or (at your option)
 
9
   any later version.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU Lesser General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU Lesser General Public License along
 
17
   with this program; if not, write to the Free Software Foundation,
 
18
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
19
 
 
20
#if !_LIBC
 
21
# include <config.h>
 
22
#endif
 
23
 
 
24
#include <string.h>
 
25
#include <ctype.h>
 
26
 
 
27
/* states: S_N: normal, S_I: comparing integral part, S_F: comparing
 
28
           fractional parts, S_Z: idem but with leading Zeroes only */
 
29
#define S_N    0x0
 
30
#define S_I    0x4
 
31
#define S_F    0x8
 
32
#define S_Z    0xC
 
33
 
 
34
/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
 
35
#define CMP    2
 
36
#define LEN    3
 
37
 
 
38
 
 
39
/* ISDIGIT differs from isdigit, as follows:
 
40
   - Its arg may be any int or unsigned int; it need not be an unsigned char
 
41
     or EOF.
 
42
   - It's typically faster.
 
43
   POSIX says that only '0' through '9' are digits.  Prefer ISDIGIT to
 
44
   isdigit unless it's important to use the locale's definition
 
45
   of `digit' even when the host does not conform to POSIX.  */
 
46
#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
 
47
 
 
48
#undef __strverscmp
 
49
#undef strverscmp
 
50
 
 
51
#ifndef weak_alias
 
52
# define __strverscmp strverscmp
 
53
#endif
 
54
 
 
55
/* Compare S1 and S2 as strings holding indices/version numbers,
 
56
   returning less than, equal to or greater than zero if S1 is less than,
 
57
   equal to or greater than S2 (for more info, see the texinfo doc).
 
58
*/
 
59
 
 
60
int
 
61
__strverscmp (const char *s1, const char *s2)
 
62
{
 
63
  const unsigned char *p1 = (const unsigned char *) s1;
 
64
  const unsigned char *p2 = (const unsigned char *) s2;
 
65
  unsigned char c1, c2;
 
66
  int state;
 
67
  int diff;
 
68
 
 
69
  /* Symbol(s)    0       [1-9]   others  (padding)
 
70
     Transition   (10) 0  (01) d  (00) x  (11) -   */
 
71
  static const unsigned int next_state[] =
 
72
  {
 
73
      /* state    x    d    0    - */
 
74
      /* S_N */  S_N, S_I, S_Z, S_N,
 
75
      /* S_I */  S_N, S_I, S_I, S_I,
 
76
      /* S_F */  S_N, S_F, S_F, S_F,
 
77
      /* S_Z */  S_N, S_F, S_Z, S_Z
 
78
  };
 
79
 
 
80
  static const int result_type[] =
 
81
  {
 
82
      /* state   x/x  x/d  x/0  x/-  d/x  d/d  d/0  d/-
 
83
                 0/x  0/d  0/0  0/-  -/x  -/d  -/0  -/- */
 
84
 
 
85
      /* S_N */  CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
 
86
                 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
 
87
      /* S_I */  CMP, -1,  -1,  CMP,  1,  LEN, LEN, CMP,
 
88
                  1,  LEN, LEN, CMP, CMP, CMP, CMP, CMP,
 
89
      /* S_F */  CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
 
90
                 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
 
91
      /* S_Z */  CMP,  1,   1,  CMP, -1,  CMP, CMP, CMP,
 
92
                 -1,  CMP, CMP, CMP
 
93
  };
 
94
 
 
95
  if (p1 == p2)
 
96
    return 0;
 
97
 
 
98
  c1 = *p1++;
 
99
  c2 = *p2++;
 
100
  /* Hint: '0' is a digit too.  */
 
101
  state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0));
 
102
 
 
103
  while ((diff = c1 - c2) == 0 && c1 != '\0')
 
104
    {
 
105
      state = next_state[state];
 
106
      c1 = *p1++;
 
107
      c2 = *p2++;
 
108
      state |= (c1 == '0') + (ISDIGIT (c1) != 0);
 
109
    }
 
110
 
 
111
  state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))];
 
112
 
 
113
  switch (state)
 
114
    {
 
115
    case CMP:
 
116
      return diff;
 
117
 
 
118
    case LEN:
 
119
      while (ISDIGIT (*p1++))
 
120
        if (!ISDIGIT (*p2++))
 
121
          return 1;
 
122
 
 
123
      return ISDIGIT (*p2) ? -1 : diff;
 
124
 
 
125
    default:
 
126
      return state;
 
127
    }
 
128
}
 
129
#ifdef weak_alias
 
130
weak_alias (__strverscmp, strverscmp)
 
131
#endif