Branch data Line data Source code
1 : : /*
2 : : * libdpkg - Debian packaging suite library routines
3 : : * deb-version.c - deb format version handling routines
4 : : *
5 : : * Copyright © 2012-2013 Guillem Jover <guillem@debian.org>
6 : : *
7 : : * This is free software; you can redistribute it and/or modify
8 : : * it under the terms of the GNU General Public License as published by
9 : : * the Free Software Foundation; either version 2 of the License, or
10 : : * (at your option) any later version.
11 : : *
12 : : * This is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : : * GNU General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU General Public License
18 : : * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 : : */
20 : :
21 : : #include <config.h>
22 : : #include <compat.h>
23 : :
24 : : #include <limits.h>
25 : : #include <string.h>
26 : : #include <stdlib.h>
27 : :
28 : : #include <dpkg/i18n.h>
29 : : #include <dpkg/c-ctype.h>
30 : : #include <dpkg/dpkg.h>
31 : : #include <dpkg/deb-version.h>
32 : :
33 : : /**
34 : : * Parse a .deb format version.
35 : : *
36 : : * It takes a string and parses a .deb archive format version in the form
37 : : * of "X.Y", without any leading whitespace, and ending in either a newline
38 : : * or a NUL. If there is any syntax error a descriptive error string is
39 : : * returned.
40 : : *
41 : : * @param version The version to return.
42 : : * @param str The string to parse.
43 : : *
44 : : * @return An error string, or NULL if there was no error.
45 : : */
46 : : const char *
47 : 84 : deb_version_parse(struct deb_version *version, const char *str)
48 : : {
49 : : const char *str_minor, *end;
50 : 84 : unsigned int major = 0;
51 : 84 : unsigned int minor = 0;
52 : 84 : unsigned int divlimit = INT_MAX / 10;
53 : 84 : int modlimit = INT_MAX % 10;
54 : :
55 [ + + + + ]: 189 : for (end = str; *end && c_isdigit(*end); end++) {
56 : 106 : int ord = *end - '0';
57 : :
58 [ + - + + : 106 : if (major > divlimit || (major == divlimit && ord > modlimit))
+ + ]
59 : 1 : return _("format version with too big major component");
60 : :
61 : 105 : major = major * 10 + ord;
62 : : }
63 : :
64 [ + + ]: 83 : if (end == str)
65 : 5 : return _("format version with empty major component");
66 [ + + ]: 78 : if (*end != '.')
67 : 2 : return _("format version has no dot");
68 : :
69 [ + + + + ]: 221 : for (end = str_minor = end + 1; *end && c_isdigit(*end); end++) {
70 : 145 : int ord = *end - '0';
71 : :
72 [ + - - + : 145 : if (minor > divlimit || (minor == divlimit && ord > modlimit))
- - ]
73 : 0 : return _("format version with too big minor component");
74 : :
75 : 145 : minor = minor * 10 + ord;
76 : : }
77 : :
78 [ + + ]: 76 : if (end == str_minor)
79 : 1 : return _("format version with empty minor component");
80 [ + + + + ]: 75 : if (*end != '\n' && *end != '\0')
81 : 1 : return _("format version followed by junk");
82 : :
83 : 74 : version->major = major;
84 : 74 : version->minor = minor;
85 : :
86 : 74 : return NULL;
87 : : }
|