pkg_parse: fix segfault when parsing descriptions with leading newlines
[project/opkg-lede.git] / libopkg / pkg_parse.c
index 7f46dc51f8c40f20aeeab01a8df2fb5c23ce9517..d6fe54611cba286f4c495fd4d80d3ec54d216ea8 100644 (file)
@@ -112,15 +112,15 @@ static char *parse_architecture(pkg_t *pkg, const char *str)
        return pkg_set_architecture(pkg, s, e - s);
 }
 
-int pkg_parse_line(void *ptr, const char *line, uint mask)
+int pkg_parse_line(void *ptr, char *line, uint mask)
 {
        pkg_t *pkg = (pkg_t *) ptr;
        abstract_pkg_t *ab_pkg = NULL;
+       conffile_list_t *cl;
 
        /* these flags are a bit hackish... */
        static int reading_conffiles = 0, reading_description = 0;
        static char *description = NULL;
-       char *s;
        int ret = 0;
 
        /* Exclude globally masked fields. */
@@ -146,6 +146,11 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                if ((mask & PFM_CONFFILES) && is_field("Conffiles", line)) {
                        reading_conffiles = 1;
                        reading_description = 0;
+
+                       cl = xcalloc(1, sizeof(*cl));
+                       conffile_list_init(cl);
+                       pkg_set_ptr(pkg, PKG_CONFFILES, cl);
+
                        goto dont_reset_flags;
                } else if ((mask & PFM_CONFLICTS)
                           && is_field("Conflicts", line))
@@ -201,7 +206,7 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
 
                        if (ab_pkg && (ab_pkg->state_flag & SF_NEED_DETAIL)) {
                                if (!(pkg->state_flag & SF_NEED_DETAIL)) {
-                                       opkg_msg(DEPEND, "propagating abpkg flag to pkg %s\n", pkg->name);
+                                       opkg_msg(DEBUG, "propagating abpkg flag to pkg %s\n", pkg->name);
                                        pkg->state_flag |= SF_NEED_DETAIL;
                                }
                        }
@@ -249,18 +254,16 @@ int pkg_parse_line(void *ptr, const 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);