pkg_parse: fix segfault when parsing descriptions with leading newlines
authorJo-Philipp Wich <jo@mein.io>
Fri, 28 Jul 2017 11:02:08 +0000 (13:02 +0200)
committerJo-Philipp Wich <jo@mein.io>
Fri, 28 Jul 2017 11:16:11 +0000 (13:16 +0200)
During parsing of multi-line descriptions that begin with a newline
character, the description pointer will be NULL when the first
continuation line is encountered, causing the strlen() invocation
on the description pointer to segfault.

This is caused by the fact that the parse_simple() helper used for
parsing the initial description line returns NULL instead of an
empty string when encountering only whitespace after the field name.

Rework the continuation line parsing code to not assume an initialized
pointer by checking before calling strlen() and avoiding realloc()
on a NULL pointer.

Fixes FS#933.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
libopkg/pkg_parse.c

index d35770c879fb00ca136141fd630f473833199f14..0baa4db396569be816386b50568c57e12d1cd98c 100644 (file)
@@ -333,18 +333,16 @@ int pkg_parse_line(void *ptr, char *line, uint mask)
 
        case ' ':
                if ((mask & PFM_DESCRIPTION) && reading_description) {
-                       if (isatty(1)) {
-                               description = xrealloc(description,
-                                                           strlen(description)
-                                                           + 1 + strlen(line) +
-                                                           1);
+                       size_t len = (description ? strlen(description) : 0)
+                               + (isatty(1) ? 1 : 0) + strlen(line) + 1;
+
+                       description = description ? xrealloc(description, len)
+                               : xcalloc(len, 1);
+
+                       if (isatty(1))
                                strcat(description, "\n");
-                       } else {
-                               description = xrealloc(description,
-                                                           strlen(description)
-                                                           + 1 + strlen(line));
-                       }
-                       strcat(description, (line));
+
+                       strcat(description, line);
                        goto dont_reset_flags;
                } else if ((mask & PFM_CONFFILES) && reading_conffiles) {
                        parse_conffiles(pkg, line);