From adb5eabda368cdd05e9ed02cf91ce5e02bc26e0b Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Wed, 25 May 2016 13:35:28 +0200 Subject: [PATCH] koops: do not assume version has 3 levels Correct commit 9023d77ad5539433146b59e5ac80e3cefcb20cf7 Some ancient kernel versions have 4 levels. This commit allows version string to have any level equal or greater than 3. The first 3 levels must be numbers and the rest can be almost anything - it just must follow the logical structure of levels (i.e. dot something dot something) - this should allow a git hash in the version string. In order to eliminate possible false positives introduced by the flexibility of version levels the commit adds checks for the prefixes ' ', '(' or 'kernel-' and the suffix ' #' or ') #'. Resolves #1378469 Signed-off-by: Jakub Filak --- src/lib/kernel.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/lib/kernel.c b/src/lib/kernel.c index 4e27d05..1a9d327 100644 --- a/src/lib/kernel.c +++ b/src/lib/kernel.c @@ -534,7 +534,10 @@ char *koops_extract_version(const char *linepointer) || strstr(linepointer, "REGS") || strstr(linepointer, "EFLAGS") ) { - const char *regexp = "([0-9]+\\.[0-9]+\\.[0-9]+-[^ \\)]+)[ \\)]"; + /* "(4.7.0-2.x86_64.fc25) #" */ + /* " 4.7.0-2.x86_64.fc25 #" */ + /* " 2.6.3.4.5-2.x86_64.fc22 #" */ + const char *regexp = "([ \\(]|kernel-)([0-9]+\\.[0-9]+\\.[0-9]+(\\.[^.-]+)*-[^ \\)]+)\\)? #"; regex_t re; int r = regcomp(&re, regexp, REG_EXTENDED); if (r != 0) @@ -545,8 +548,8 @@ char *koops_extract_version(const char *linepointer) return NULL; } - regmatch_t matchptr[2]; - r = regexec(&re, linepointer, 2, matchptr, 0); + regmatch_t matchptr[3]; + r = regexec(&re, linepointer, sizeof(matchptr)/sizeof(matchptr[0]), matchptr, 0); if (r != 0) { if (r != REG_NOMATCH) @@ -565,7 +568,11 @@ char *koops_extract_version(const char *linepointer) return NULL; } - char *ret = xstrndup(linepointer + matchptr[1].rm_so, matchptr[1].rm_eo - matchptr[1].rm_so); + /* 0: entire string */ + /* 1: version prefix */ + /* 2: version string */ + const regmatch_t *const ver = matchptr + 2; + char *ret = xstrndup(linepointer + ver->rm_so, ver->rm_eo - ver->rm_so); regfree(&re); return ret; -- 1.8.3.1