Imported Upstream version 0.7.19 upstream/0.7.19
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 23 Dec 2021 05:47:13 +0000 (14:47 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 23 Dec 2021 05:47:13 +0000 (14:47 +0900)
NEWS
VERSION.cmake
ext/repo_appdata.c
ext/repo_deb.c
ext/repo_helix.c
ext/solv_xfopen.c
ext/testcase.c
package/libsolv.changes
src/repo_write.c
src/solver.c

diff --git a/NEWS b/NEWS
index a627131..1bfc9d0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,13 @@
 This file contains the major changes between
 libsolv versions:
 
+Version 0.7.19
+- selected bug fixes:
+  * fix rare segfault in resolve_jobrules() that could happen
+    if new rules are learnt
+  * fix a couple of memory leaks in error cases
+  * fix error handling in solv_xfopen_fd()
+
 Version 0.7.18
 - selected bug fixes:
   * fixed regex code on win32
index 8a96a14..1cecd64 100644 (file)
@@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "1")
 
 SET(LIBSOLV_MAJOR "0")
 SET(LIBSOLV_MINOR "7")
-SET(LIBSOLV_PATCH "18")
+SET(LIBSOLV_PATCH "19")
 
index b798af4..390b286 100644 (file)
@@ -183,7 +183,7 @@ indent(struct parsedata *pd, int il)
       if (xmlp->lcontent + il + 1 > xmlp->acontent)
        {
          xmlp->acontent = xmlp->lcontent + il + 256;
-         xmlp->content = realloc(xmlp->content, xmlp->acontent);
+         xmlp->content = solv_realloc(xmlp->content, xmlp->acontent);
        }
       memmove(xmlp->content + l + il, xmlp->content + l, xmlp->lcontent - l + 1);
       for (i = 0; i < il; i++)
index 8f63756..34f40fa 100644 (file)
@@ -792,5 +792,6 @@ pool_deb_get_autoinstalled(Pool *pool, FILE *fp, Queue *q, int flags)
          break;
        }
     }
+    solv_free(buf);
 }
 
index 37359bb..f4bea55 100644 (file)
@@ -655,7 +655,7 @@ endElement(struct solv_xmlparser *xmlp, int state, char *content)
       if (xmlp->lcontent + 1 + pd->levrspace > pd->aevrspace)
        {
          pd->aevrspace = xmlp->lcontent + 1 + pd->levrspace + 256;
-         pd->evrspace = (char *)realloc(pd->evrspace, pd->aevrspace);
+         pd->evrspace = (char *)solv_realloc(pd->evrspace, pd->aevrspace);
        }
       memcpy(pd->evrspace + pd->levrspace, xmlp->content, xmlp->lcontent + 1);
       if (state == STATE_EPOCH)
index 7e974a9..369003b 100644 (file)
@@ -165,7 +165,7 @@ static LZFILE *lzopen(const char *path, const char *mode, int fd, int isxz)
   LZFILE *lzfile;
   lzma_ret ret;
 
-  if (!path && fd < 0)
+  if ((!path && fd < 0) || (path && fd >= 0))
     return 0;
   for (; *mode; mode++)
     {
@@ -176,19 +176,7 @@ static LZFILE *lzopen(const char *path, const char *mode, int fd, int isxz)
       else if (*mode >= '1' && *mode <= '9')
        level = *mode - '0';
     }
-  if (fd != -1)
-    fp = fdopen(fd, encoding ? "w" : "r");
-  else
-    fp = fopen(path, encoding ? "w" : "r");
-  if (!fp)
-    return 0;
-  lzfile = calloc(1, sizeof(*lzfile));
-  if (!lzfile)
-    {
-      fclose(fp);
-      return 0;
-    }
-  lzfile->file = fp;
+  lzfile = solv_calloc(1, sizeof(*lzfile));
   lzfile->encoding = encoding;
   lzfile->eof = 0;
   lzfile->strm = stream_init;
@@ -203,10 +191,20 @@ static LZFILE *lzopen(const char *path, const char *mode, int fd, int isxz)
     ret = lzma_auto_decoder(&lzfile->strm, 100 << 20, 0);
   if (ret != LZMA_OK)
     {
-      fclose(fp);
-      free(lzfile);
+      solv_free(lzfile);
       return 0;
     }
+  if (!path)
+    fp = fdopen(fd, encoding ? "w" : "r");
+  else
+    fp = fopen(path, encoding ? "w" : "r");
+  if (!fp)
+    {
+      lzma_end(&lzfile->strm);
+      solv_free(lzfile);
+      return 0;
+    }
+  lzfile->file = fp;
   return lzfile;
 }
 
@@ -237,7 +235,7 @@ static int lzclose(void *cookie)
     }
   lzma_end(&lzfile->strm);
   rc = fclose(lzfile->file);
-  free(lzfile);
+  solv_free(lzfile);
   return rc;
 }
 
@@ -351,7 +349,7 @@ static ZSTDFILE *zstdopen(const char *path, const char *mode, int fd)
   FILE *fp;
   ZSTDFILE *zstdfile;
 
-  if (!path && fd < 0)
+  if ((!path && fd < 0) || (path && fd >= 0))
     return 0;
   for (; *mode; mode++)
     {
@@ -362,12 +360,6 @@ static ZSTDFILE *zstdopen(const char *path, const char *mode, int fd)
       else if (*mode >= '1' && *mode <= '9')
        level = *mode - '0';
     }
-  if (fd != -1)
-    fp = fdopen(fd, encoding ? "w" : "r");
-  else
-    fp = fopen(path, encoding ? "w" : "r");
-  if (!fp)
-    return 0;
   zstdfile = solv_calloc(1, sizeof(*zstdfile));
   zstdfile->encoding = encoding;
   if (encoding)
@@ -377,14 +369,12 @@ static ZSTDFILE *zstdopen(const char *path, const char *mode, int fd)
       if (!zstdfile->cstream)
        {
          solv_free(zstdfile);
-         fclose(fp);
          return 0;
        }
       if (ZSTD_isError(ZSTD_initCStream(zstdfile->cstream, level)))
        {
          ZSTD_freeCStream(zstdfile->cstream);
          solv_free(zstdfile);
-         fclose(fp);
          return 0;
        }
       zstdfile->out.dst = zstdfile->buf;
@@ -398,13 +388,25 @@ static ZSTDFILE *zstdopen(const char *path, const char *mode, int fd)
        {
          ZSTD_freeDStream(zstdfile->dstream);
          solv_free(zstdfile);
-         fclose(fp);
          return 0;
        }
       zstdfile->in.src = zstdfile->buf;
       zstdfile->in.pos = 0;
       zstdfile->in.size = 0;
     }
+  if (!path)
+    fp = fdopen(fd, encoding ? "w" : "r");
+  else
+    fp = fopen(path, encoding ? "w" : "r");
+  if (!fp)
+    {
+      if (encoding)
+       ZSTD_freeCStream(zstdfile->cstream);
+      else
+       ZSTD_freeDStream(zstdfile->dstream);
+      solv_free(zstdfile);
+      return 0;
+    }
   zstdfile->file = fp;
   return zstdfile;
 }
@@ -437,7 +439,7 @@ static int zstdclose(void *cookie)
       ZSTD_freeDStream(zstdfile->dstream);
     }
   rc = fclose(zstdfile->file);
-  free(zstdfile);
+  solv_free(zstdfile);
   return rc;
 }
 
@@ -546,9 +548,9 @@ static void *zchunkopen(const char *path, const char *mode, int fd)
 {
   zckCtx *f;
 
-  if (!path && fd < 0)
+  if ((!path && fd < 0) || (path && fd >= 0))
     return 0;
-  if (fd == -1)
+  if (path)
     {
       if (*mode != 'w')
         fd = open(path, O_RDONLY);
@@ -560,18 +562,29 @@ static void *zchunkopen(const char *path, const char *mode, int fd)
   f = zck_create();
   if (!f)
     {
-      close(fd);
+      if (path)
+       close(fd);
       return 0;
     }
   if (*mode != 'w')
     {
       if(!zck_init_read(f, fd))
-        return 0;
+       {
+         zck_free(&f);
+         if (path)
+           close(fd);
+         return 0;
+       }
     }
    else
     {
       if(!zck_init_write(f, fd))
-        return 0;
+       {
+         zck_free(&f);
+         if (path)
+           close(fd);
+         return 0;
+       }
     }
   return cookieopen(f, mode, cookie_zckread, cookie_zckwrite, cookie_zckclose);
 }
@@ -585,19 +598,34 @@ static void *zchunkopen(const char *path, const char *mode, int fd)
 {
   FILE *fp;
   void *f;
-  if (!path && fd < 0)
+  if ((!path && fd < 0) || (path && fd >= 0))
     return 0;
-  if (fd != -1)
+  if (strcmp(mode, "r") != 0)
+    return 0;
+  if (!path)
     fp = fdopen(fd, mode);
   else
     fp = fopen(path, mode);
   if (!fp)
     return 0;
-  if (strcmp(mode, "r") != 0)
-    return 0;
   f = solv_zchunk_open(fp, 1);
   if (!f)
-    fclose(fp);
+    {
+      if (!path)
+       {
+         /* The fd passed by user must not be closed! */
+         /* Dup (save) the original fd to a temporary variable and then back. */
+         /* It is ugly and thread unsafe hack (non atomical sequence fclose dup2). */
+         int tmpfd = dup(fd);
+         fclose(fp);
+         dup2(tmpfd, fd);
+         close(tmpfd);
+       }
+      else
+       {
+         fclose(fp);
+       }
+    }
   return cookieopen(f, mode, (ssize_t (*)(void *, char *, size_t))solv_zchunk_read, 0, (int (*)(void *))solv_zchunk_close);
 }
 
index 8fb6d79..20b0c48 100644 (file)
@@ -1473,15 +1473,16 @@ testcase_solverresult(Solver *solv, int resultflags)
       SolverRuleinfo rclass;
       Queue q;
       int i;
+      char *prefix;
 
       queue_init(&q);
       for (rid = 1; (rclass = solver_ruleclass(solv, rid)) != SOLVER_RULE_UNKNOWN; rid++)
        {
-         char *prefix = solv_dupjoin("rule ", testcase_rclass2str(rclass), " ");
-         prefix = solv_dupappend(prefix, testcase_ruleid(solv, rid), 0);
          solver_ruleliterals(solv, rid, &q);
          if (rclass == SOLVER_RULE_FEATURE && q.count == 1 && q.elements[0] == -SYSTEMSOLVABLE)
            continue;
+         prefix = solv_dupjoin("rule ", testcase_rclass2str(rclass), " ");
+         prefix = solv_dupappend(prefix, testcase_ruleid(solv, rid), 0);
          for (i = 0; i < q.count; i++)
            {
              Id p = q.elements[i];
index 32ec121..6270b61 100644 (file)
@@ -1,4 +1,13 @@
 -------------------------------------------------------------------
+Wed Apr  7 14:56:16 CEST 2021 - mls@suse.de
+
+- fix rare segfault in resolve_jobrules() that could happen
+  if new rules are learnt
+- fix a couple of memory leaks in error cases
+- fix error handling in solv_xfopen_fd()
+- bump version to 0.7.19
+
+-------------------------------------------------------------------
 Fri Mar 26 14:17:46 CET 2021 - mls@suse.de
 
 - fixed regex code on win32
index 0f9fc4f..af4e759 100644 (file)
@@ -1446,7 +1446,7 @@ for (i = 1; i < target.nkeys; i++)
       reloff += 3 * target.nkeys;
     }
 
-  needid = calloc(reloff + pool->nrels, sizeof(*needid));
+  needid = solv_calloc(reloff + pool->nrels, sizeof(*needid));
   needid[0].map = reloff;      /* remember size in case we need to grow */
 
   cbdata.needid = needid;
index 9c02cc7..89a2ed1 100644 (file)
@@ -1629,6 +1629,7 @@ resolve_jobrules(Solver *solv, int level, int disablerules, Queue *dq)
        }
       olevel = level;
       level = selectandinstall(solv, level, dq, disablerules, i, SOLVER_REASON_RESOLVE_JOB);
+      r = solv->rules + i;    /* selectandinstall may have added more rules */
       if (level <= olevel)
        {
          if (level == olevel)