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 : 73 : deb_version_parse(struct deb_version *version, const char *str) 48 : : { 49 : : const char *str_minor, *end; 50 : 73 : unsigned int major = 0; 51 : 73 : unsigned int minor = 0; 52 : 73 : unsigned int divlimit = INT_MAX / 10; 53 : 73 : int modlimit = INT_MAX % 10; 54 : : 55 [ + + + + ]: 167 : for (end = str; *end && c_isdigit(*end); end++) { 56 : 95 : int ord = *end - '0'; 57 : : 58 [ + - + + : 95 : if (major > divlimit || (major == divlimit && ord > modlimit)) + + ] 59 : 1 : return _("format version with too big major component"); 60 : : 61 : 94 : major = major * 10 + ord; 62 : : } 63 : : 64 [ + + ]: 72 : if (end == str) 65 : 5 : return _("format version with empty major component"); 66 [ + + ]: 67 : if (*end != '.') 67 : 2 : return _("format version has no dot"); 68 : : 69 [ + + + + ]: 194 : for (end = str_minor = end + 1; *end && c_isdigit(*end); end++) { 70 : 129 : int ord = *end - '0'; 71 : : 72 [ + - - + : 129 : if (minor > divlimit || (minor == divlimit && ord > modlimit)) - - ] 73 : 0 : return _("format version with too big minor component"); 74 : : 75 : 129 : minor = minor * 10 + ord; 76 : : } 77 : : 78 [ + + ]: 65 : if (end == str_minor) 79 : 1 : return _("format version with empty minor component"); 80 [ + + + + ]: 64 : if (*end != '\n' && *end != '\0') 81 : 1 : return _("format version followed by junk"); 82 : : 83 : 63 : version->major = major; 84 : 63 : version->minor = minor; 85 : : 86 : 63 : return NULL; 87 : : }