Hello community,

here is the log from the commit of package libsolv for openSUSE:Factory checked 
in at 2019-12-23 22:37:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libsolv (Old)
 and      /work/SRC/openSUSE:Factory/.libsolv.new.6675 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libsolv"

Mon Dec 23 22:37:00 2019 rev:76 rq:758493 version:0.7.10

Changes:
--------
--- /work/SRC/openSUSE:Factory/libsolv/libsolv.changes  2019-12-07 
15:22:13.587738459 +0100
+++ /work/SRC/openSUSE:Factory/.libsolv.new.6675/libsolv.changes        
2019-12-23 22:39:38.433877490 +0100
@@ -1,0 +2,19 @@
+Thu Dec 19 16:29:52 CET 2019 - [email protected]
+
+- fix solv_zchunk decoding error if large chunks are used
+  [bnc#1159314]
+
+-------------------------------------------------------------------
+Tue Dec 10 21:02:31 CET 2019 - [email protected]
+
+- build with -DENABLE_RPMDB_LIBRPM=1 on SUSE to support
+  multiple rpm database backends
+
+-------------------------------------------------------------------
+Tue Dec 10 14:18:36 CET 2019 - [email protected]
+
+- added two new function to make libzypp independent of the rpm
+  database format
+- bump version to 0.7.10
+
+-------------------------------------------------------------------

Old:
----
  libsolv-0.7.9.tar.bz2

New:
----
  libsolv-0.7.10.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libsolv.spec ++++++
--- /var/tmp/diff_new_pack.cxiYdj/_old  2019-12-23 22:39:39.077877769 +0100
+++ /var/tmp/diff_new_pack.cxiYdj/_new  2019-12-23 22:39:39.081877771 +0100
@@ -52,7 +52,7 @@
 %bcond_with zypp
 
 Name:           libsolv
-Version:        0.7.9
+Version:        0.7.10
 Release:        0
 Summary:        Package dependency solver using a satisfiability algorithm
 License:        BSD-3-Clause

++++++ libsolv-0.7.9.tar.bz2 -> libsolv-0.7.10.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/CMakeLists.txt 
new/libsolv-0.7.10/CMakeLists.txt
--- old/libsolv-0.7.9/CMakeLists.txt    2019-07-01 11:34:26.000000000 +0200
+++ new/libsolv-0.7.10/CMakeLists.txt   2019-12-19 16:34:10.000000000 +0100
@@ -17,6 +17,7 @@
 OPTION (ENABLE_PUBKEY "Build with pubkey support?" OFF)
 OPTION (ENABLE_RPMDB_BYRPMHEADER "Build with rpmdb Header support?" OFF)
 OPTION (ENABLE_RPMDB_LIBRPM "Use librpm to access the rpm database?" OFF)
+OPTION (ENABLE_RPMDB_BDB "Use BerkeleyDB to access the rpm database?" OFF)
 OPTION (ENABLE_RPMPKG_LIBRPM "Use librpm to access rpm header information?" 
OFF)
 OPTION (ENABLE_RPMMD "Build with rpmmd repository support?" OFF)
 OPTION (ENABLE_SUSEREPO "Build with suse repository support?" OFF)
@@ -223,21 +224,30 @@
     ENDIF (RPMMISC_LIBRARY)
   ENDIF (RPM5)
 
-  # check if rpm contains a bundled berkeley db
-  CHECK_INCLUDE_FILE(rpm/db.h HAVE_RPM_DB_H)
-  IF (NOT ENABLE_RPMDB_LIBRPM)
-    IF (NOT HAVE_RPM_DB_H)
-      FIND_LIBRARY (DB_LIBRARY NAMES db)
-      IF (DB_LIBRARY)
-        SET (RPMDB_LIBRARY ${DB_LIBRARY} ${RPMDB_LIBRARY})
-      ENDIF (DB_LIBRARY)
-      IF (DB_INCLUDE_DIR)
-        INCLUDE_DIRECTORIES (${DB_INCLUDE_DIR})
-      ENDIF (DB_INCLUDE_DIR)
-    ENDIF (NOT HAVE_RPM_DB_H)
-  ENDIF (NOT ENABLE_RPMDB_LIBRPM)
+  IF (ENABLE_RPMDB)
+    IF (NOT ENABLE_RPMDB_BDB)
+      SET (ENABLE_RPMDB_LIBRPM ON)
+    ENDIF (NOT ENABLE_RPMDB_BDB)
+
+    # check if rpm contains a bundled berkeley db
+    CHECK_INCLUDE_FILE(rpm/db.h HAVE_RPM_DB_H)
+    IF (NOT ENABLE_RPMDB_LIBRPM)
+      IF (NOT HAVE_RPM_DB_H)
+        FIND_LIBRARY (DB_LIBRARY NAMES db)
+        IF (DB_LIBRARY)
+          SET (RPMDB_LIBRARY ${DB_LIBRARY} ${RPMDB_LIBRARY})
+        ENDIF (DB_LIBRARY)
+        IF (DB_INCLUDE_DIR)
+          INCLUDE_DIRECTORIES (${DB_INCLUDE_DIR})
+        ENDIF (DB_INCLUDE_DIR)
+      ENDIF (NOT HAVE_RPM_DB_H)
+    ENDIF (NOT ENABLE_RPMDB_LIBRPM)
+  ENDIF (ENABLE_RPMDB)
+
   INCLUDE (CheckLibraryExists)
   CHECK_LIBRARY_EXISTS(rpmio pgpDigGetParams "" HAVE_PGPDIGGETPARAMS)
+  CHECK_LIBRARY_EXISTS(rpm rpmdbNextIteratorHeaderBlob "" 
HAVE_RPMDBNEXTITERATORHEADERBLOB)
+  CHECK_LIBRARY_EXISTS(rpm rpmdbFStat "" HAVE_RPMDBFSTAT)
 ENDIF (ENABLE_RPMDB OR ENABLE_RPMPKG_LIBRPM)
 
 IF (ENABLE_PUBKEY)
@@ -270,7 +280,8 @@
 
 # should create config.h with #cmakedefine instead...
 FOREACH (VAR HAVE_STRCHRNUL HAVE_FOPENCOOKIE HAVE_FUNOPEN WORDS_BIGENDIAN
-  HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS WITH_LIBXML2 WITHOUT_COOKIEOPEN)
+  HAVE_RPM_DB_H HAVE_PGPDIGGETPARAMS HAVE_RPMDBNEXTITERATORHEADERBLOB 
HAVE_RPMDBFSTAT
+  WITH_LIBXML2 WITHOUT_COOKIEOPEN)
   IF(${VAR})
     ADD_DEFINITIONS (-D${VAR}=1)
     SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/NEWS new/libsolv-0.7.10/NEWS
--- old/libsolv-0.7.9/NEWS      2019-11-21 16:39:09.000000000 +0100
+++ new/libsolv-0.7.10/NEWS     2019-12-10 14:26:29.000000000 +0100
@@ -2,6 +2,11 @@
 This file contains the major changes between
 libsolv versions:
 
+Version 0.7.10
+- new features:
+  * new rpm_stat_database() function
+  * new rpm_hash_database_state() function
+
 Version 0.7.9
 - new features:
   * support conda constrains dependencies
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/VERSION.cmake 
new/libsolv-0.7.10/VERSION.cmake
--- old/libsolv-0.7.9/VERSION.cmake     2019-11-21 16:39:09.000000000 +0100
+++ new/libsolv-0.7.10/VERSION.cmake    2019-12-10 14:26:29.000000000 +0100
@@ -49,5 +49,5 @@
 
 SET(LIBSOLV_MAJOR "0")
 SET(LIBSOLV_MINOR "7")
-SET(LIBSOLV_PATCH "9")
+SET(LIBSOLV_PATCH "10")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/ext/libsolvext.ver 
new/libsolv-0.7.10/ext/libsolvext.ver
--- old/libsolv-0.7.9/ext/libsolvext.ver        2019-11-08 14:39:59.000000000 
+0100
+++ new/libsolv-0.7.10/ext/libsolvext.ver       2019-12-10 14:19:11.000000000 
+0100
@@ -47,10 +47,12 @@
                rpm_byfp;
                rpm_byrpmdbid;
                rpm_byrpmh;
+               rpm_hash_database_state;
                rpm_installedrpmdbids;
                rpm_iterate_filelist;
                rpm_query;
                rpm_query_num;
+               rpm_stat_database;
                rpm_state_create;
                rpm_state_free;
                solv_verify_sig;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/ext/repo_rpmdb.c 
new/libsolv-0.7.10/ext/repo_rpmdb.c
--- old/libsolv-0.7.9/ext/repo_rpmdb.c  2019-10-21 13:21:14.000000000 +0200
+++ new/libsolv-0.7.10/ext/repo_rpmdb.c 2019-12-19 16:34:10.000000000 +0100
@@ -172,6 +172,15 @@
 } RpmHead;
 
 
+static inline void
+headinit(RpmHead *h, unsigned int cnt, unsigned int dcnt)
+{
+  h->cnt = (int)cnt;
+  h->dcnt = dcnt;
+  h->dp = h->data + 16 * cnt;
+  h->dp[dcnt] = 0;
+}
+
 static inline unsigned char *
 headfindtag(RpmHead *h, int tag)
 {
@@ -1240,7 +1249,7 @@
   char *rootdir;
 
   RpmHead *rpmhead;    /* header storage space */
-  int rpmheadsize;
+  unsigned int rpmheadsize;
 };
 
 #endif
@@ -1248,49 +1257,55 @@
 
 #ifndef ENABLE_RPMPKG_LIBRPM
 
-static int
-headfromfp(struct rpmdbstate *state, const char *name, FILE *fp, unsigned char 
*lead, unsigned int cnt, unsigned int dsize, unsigned int pad, Chksum *chk1, 
Chksum *chk2)
+static inline RpmHead *
+realloc_head(struct rpmdbstate *state, unsigned int len)
 {
-  RpmHead *rpmhead;
-  unsigned int len = 16 * cnt + dsize + pad;
-  if (len + 1 > state->rpmheadsize)
+  if (len > state->rpmheadsize)
     {
       state->rpmheadsize = len + 128;
       state->rpmhead = solv_realloc(state->rpmhead, sizeof(*state->rpmhead) + 
state->rpmheadsize);
     }
-  rpmhead = state->rpmhead;
+  return state->rpmhead;
+}
+
+static int
+headfromfp(struct rpmdbstate *state, const char *name, FILE *fp, unsigned char 
*lead, unsigned int cnt, unsigned int dsize, unsigned int pad, Chksum *chk1, 
Chksum *chk2)
+{
+  unsigned int len = 16 * cnt + dsize + pad;
+  RpmHead *rpmhead = realloc_head(state, len + 1);
   if (fread(rpmhead->data, len, 1, fp) != 1)
     return pool_error(state->pool, 0, "%s: unexpected EOF", name);
   if (chk1)
     solv_chksum_add(chk1, rpmhead->data, len);
   if (chk2)
     solv_chksum_add(chk2, rpmhead->data, len);
-  rpmhead->data[len] = 0;
-  rpmhead->cnt = cnt;
-  rpmhead->dcnt = dsize;
-  rpmhead->dp = rpmhead->data + cnt * 16;
+  headinit(rpmhead, cnt, dsize);
   return 1;
 }
 
-#if defined(ENABLE_RPMDB_BYRPMHEADER)
-static void
-headfromblob(struct rpmdbstate *state, const unsigned char *blob, unsigned int 
cnt, unsigned int dsize)
+# if defined(ENABLE_RPMDB) && (!defined(ENABLE_RPMDB_LIBRPM) || 
defined(HAVE_RPMDBNEXTITERATORHEADERBLOB))
+
+static int
+headfromhdrblob(struct rpmdbstate *state, const unsigned char *data, unsigned 
int size)
 {
+  unsigned int dsize, cnt, len;
   RpmHead *rpmhead;
-  unsigned int len = 16 * cnt + dsize;
-  if (len + 1 > state->rpmheadsize)
-    {
-      state->rpmheadsize = len + 128;
-      state->rpmhead = solv_realloc(state->rpmhead, sizeof(*state->rpmhead) + 
state->rpmheadsize);
-    }
-  rpmhead = state->rpmhead;
-  memcpy(rpmhead->data, blob, len);
-  rpmhead->data[len] = 0;
-  rpmhead->cnt = cnt;
-  rpmhead->dcnt = dsize;
-  rpmhead->dp = rpmhead->data + cnt * 16;
+  if (size < 8)
+    return pool_error(state->pool, 0, "corrupt rpm database (size)");
+  cnt = getu32(data);
+  dsize = getu32(data + 4);
+  if (cnt >= MAX_HDR_CNT || dsize >= MAX_HDR_DSIZE)
+    return pool_error(state->pool, 0, "corrupt rpm database (cnt/dcnt)");
+  if (8 + cnt * 16 + dsize > size)
+    return pool_error(state->pool, 0, "corrupt rpm database (data size)");
+  len = 16 * cnt + dsize;
+  rpmhead = realloc_head(state, len + 1);
+  memcpy(rpmhead->data, data + 8, len);
+  headinit(rpmhead, cnt, dsize);
+  return 1;
 }
-#endif
+
+# endif
 
 #else
 
@@ -1329,8 +1344,6 @@
 {
   /* close down */
 #ifdef ENABLE_RPMDB
-  if (state->pkgdbopened)
-    closepkgdb(state);
   if (state->dbenvopened)
     closedbenv(state);
 #endif
@@ -1624,11 +1637,6 @@
        repo_empty(ref, 1);     /* get it out of the way */
       if ((flags & RPMDB_REPORT_PROGRESS) != 0)
        count = count_headers(&state);
-      if (!openpkgdb(&state))
-       {
-         freestate(&state);
-         return -1;
-       }
       if (pkgdb_cursor_open(&state))
        {
          freestate(&state);
@@ -2394,6 +2402,28 @@
   return nentries;
 }
 
+int
+rpm_hash_database_state(void *rpmstate, Chksum *chk)
+{
+  struct rpmdbstate *state = rpmstate;
+  struct stat stb;
+  if (stat_database(state, &stb))
+    return -1;
+  if (state->dbenvopened != 1 && !opendbenv(state))
+    return -1;
+  solv_chksum_add(chk, &stb.st_mtime, sizeof(stb.st_mtime));
+  solv_chksum_add(chk, &stb.st_size, sizeof(stb.st_size));
+  solv_chksum_add(chk, &stb.st_ino, sizeof(stb.st_ino));
+  hash_name_index(rpmstate, chk);
+  return 0;
+}
+
+int
+rpm_stat_database(void *rpmstate, void *stb)
+{
+  return stat_database((struct rpmdbstate *)rpmstate, (struct stat *)stb) ? -1 
: 0;
+}
+
 void *
 rpm_byrpmdbid(void *rpmstate, Id rpmdbid)
 {
@@ -2482,7 +2512,8 @@
   struct rpmdbstate *state = rpmstate;
 #ifndef ENABLE_RPMPKG_LIBRPM
   const unsigned char *uh;
-  unsigned int dsize, cnt;
+  unsigned int dsize, cnt, len;
+  RpmHead *rpmhead;
 
   if (!h)
     return 0;
@@ -2500,7 +2531,10 @@
       free((void *)uh);
       return 0;
     }
-  headfromblob(state, uh + 8, cnt, dsize);
+  len = 16 * cnt + dsize;
+  rpmhead = realloc_head(state, len + 1);;
+  memcpy(rpmhead->data, uh + 8, len);
+  headinit(rpmhead, cnt, dsize);
   free((void *)uh);
 #else
   if (!h)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/ext/repo_rpmdb.h 
new/libsolv-0.7.10/ext/repo_rpmdb.h
--- old/libsolv-0.7.9/ext/repo_rpmdb.h  2018-10-01 11:09:18.000000000 +0200
+++ new/libsolv-0.7.10/ext/repo_rpmdb.h 2019-12-10 14:19:11.000000000 +0100
@@ -7,6 +7,7 @@
 
 #include "queue.h"
 #include "repo.h"
+#include "chksum.h"
 
 struct headerToken_s;
 
@@ -39,7 +40,11 @@
 extern void *rpm_state_free(void *rpmstate);
 
 /* return all matching rpmdbids */
-extern int  rpm_installedrpmdbids(void *rpmstate, const char *index, const 
char *match, Queue *rpmdbidq);
+extern int rpm_installedrpmdbids(void *rpmstate, const char *index, const char 
*match, Queue *rpmdbidq);
+/* stat the package database */
+extern int rpm_stat_database(void *rpmstate, void *stb);
+/* hash the state of the package database */
+extern int rpm_hash_database_state(void *rpmstate, Chksum *chk);
 
 /* return handles to a rpm header */
 extern void *rpm_byrpmdbid(void *rpmstate, Id rpmdbid);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/ext/repo_rpmdb_bdb.h 
new/libsolv-0.7.10/ext/repo_rpmdb_bdb.h
--- old/libsolv-0.7.9/ext/repo_rpmdb_bdb.h      2019-10-21 13:21:14.000000000 
+0200
+++ new/libsolv-0.7.10/ext/repo_rpmdb_bdb.h     2019-12-19 16:34:10.000000000 
+0100
@@ -43,7 +43,7 @@
   char *rootdir;
 
   RpmHead *rpmhead;    /* header storage space */
-  int rpmheadsize;
+  unsigned int rpmheadsize;
 
   int dbenvopened;     /* database environment opened */
   int pkgdbopened;     /* package database openend */
@@ -56,11 +56,31 @@
 };
 
 
+static inline int
+access_rootdir(struct rpmdbstate *state, const char *dir, int mode)
+{
+  if (state->rootdir)
+    {
+      char *path = solv_dupjoin(state->rootdir, dir, 0);
+      int r = access(path, mode);
+      free(path);
+      return r;
+    }
+  return access(dir, mode);
+}
+
+static void
+detect_ostree(struct rpmdbstate *state)
+{
+  state->is_ostree = access_rootdir(state, "/var/lib/rpm", W_OK) == -1 &&
+                     access_rootdir(state, "/usr/share/rpm/Packages", R_OK) == 
0 ? 1 : -1;
+}
+
 static int
 stat_database_name(struct rpmdbstate *state, char *dbname, struct stat 
*statbuf, int seterror)
 {
   char *dbpath;
-  dbpath = solv_dupjoin(state->rootdir, state->is_ostree ? "/usr/share/rpm/" : 
"/var/lib/rpm/", dbname);
+  dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? 
"/usr/share/rpm/" : "/var/lib/rpm/", dbname);
   if (stat(dbpath, statbuf))
     {
       if (seterror)
@@ -75,6 +95,8 @@
 static int
 stat_database(struct rpmdbstate *state, struct stat *statbuf)
 {
+  if (!state->is_ostree)
+    detect_ostree(state);
   return stat_database_name(state, "Packages", statbuf, 1);
 }
 
@@ -160,6 +182,7 @@
   dbenv->set_thread_count(dbenv, 8);
 #endif
   dbpath = solv_dupjoin(rootdir, "/var/lib/rpm", 0);
+  state->is_ostree = -1;
   if (access(dbpath, W_OK) == -1)
     {
       free(dbpath);
@@ -167,7 +190,7 @@
       if (access(dbpath, R_OK) == 0)
        state->is_ostree = 1;
       free(dbpath);
-      dbpath = solv_dupjoin(rootdir, state->is_ostree ? "/usr/share/rpm" : 
"/var/lib/rpm", 0);
+      dbpath = solv_dupjoin(rootdir, state->is_ostree > 0 ? "/usr/share/rpm" : 
"/var/lib/rpm", 0);
       r = dbenv->open(dbenv, dbpath, DB_CREATE|DB_PRIVATE|DB_INIT_MPOOL, 0);
     }
   else
@@ -209,6 +232,12 @@
   uint32_t eflags = 0;
 #endif
 
+  if (state->db)
+    {
+      state->db->close(state->db, 0);
+      state->db = 0;
+    }
+  state->pkgdbopened = 0;
   if (!state->dbenv)
     return;
 #if defined(FEDORA) || defined(MAGEIA)
@@ -264,16 +293,6 @@
   return 1;
 }
 
-static void
-closepkgdb(struct rpmdbstate *state)
-{
-  if (!state->db)
-    return;
-  state->db->close(state->db, 0);
-  state->db = 0;
-  state->pkgdbopened = 0;
-}
-
 /* get the rpmdbids of all installed packages from the Name index database.
  * This is much faster then querying the big Packages database */
 static struct rpmdbentry *
@@ -368,35 +387,7 @@
   return entries;
 }
 
-/* common code, return dbid on success, -1 on error */
-static int
-getrpm_dbdata(struct rpmdbstate *state, DBT *dbdata, int dbid)
-{
-  unsigned int dsize, cnt, l;
-  RpmHead *rpmhead;
-
-  if (dbdata->size < 8)
-    return pool_error(state->pool, -1, "corrupt rpm database (size)");
-  cnt = getu32((const unsigned char *)dbdata->data);
-  dsize = getu32((const unsigned char *)dbdata->data + 4);
-  if (cnt >= MAX_HDR_CNT || dsize >= MAX_HDR_DSIZE)
-    return pool_error(state->pool, -1, "corrupt rpm database (cnt/dcnt)");
-  l = cnt * 16 + dsize;
-  if (8 + l > dbdata->size)
-    return pool_error(state->pool, -1, "corrupt rpm database (data size)");
-  if (l + 1 > state->rpmheadsize)
-    {
-      state->rpmheadsize = l + 128;
-      state->rpmhead = solv_realloc(state->rpmhead, sizeof(*rpmhead) + 
state->rpmheadsize);
-    }
-  rpmhead = state->rpmhead;
-  rpmhead->cnt = cnt;
-  rpmhead->dcnt = dsize;
-  memcpy(rpmhead->data, (unsigned char *)dbdata->data + 8, l);
-  rpmhead->data[l] = 0;
-  rpmhead->dp = rpmhead->data + cnt * 16;
-  return dbid;
-}
+static int headfromhdrblob(struct rpmdbstate *state, const unsigned char 
*data, unsigned int size);
 
 /* retrive header by rpmdbid, returns 0 if not found, -1 on error */
 static int
@@ -419,7 +410,9 @@
   dbdata.size = 0;
   if (state->db->get(state->db, NULL, &dbkey, &dbdata, 0))
     return 0;
-  return getrpm_dbdata(state, &dbdata, dbid);
+  if (!headfromhdrblob(state, (const unsigned char *)dbdata.data, (unsigned 
int)dbdata.size))
+    return -1;
+  return dbid;
 }
 
 static int
@@ -464,6 +457,8 @@
 static int
 pkgdb_cursor_open(struct rpmdbstate *state)
 {
+  if (state->pkgdbopened != 1 && !openpkgdb(state))
+    return -1;
   if (state->db->cursor(state->db, NULL, &state->dbc, 0))
     return pool_error(state->pool, -1, "db->cursor failed");
   return 0;
@@ -491,9 +486,28 @@
       if (dbkey.size != 4)
        return pool_error(state->pool, -1, "corrupt Packages database (key 
size)");
       dbid = db2rpmdbid(dbkey.data, state->byteswapped);
-      if (dbid)                /* ignore join key */
-        return getrpm_dbdata(state, &dbdata, dbid);
+      if (!dbid)
+       continue;       /* ignore join key */
+      if (!headfromhdrblob(state, (const unsigned char *)dbdata.data, 
(unsigned int)dbdata.size))
+       return -1;
+      return dbid;
     }
   return 0;    /* no more entries */
 }
 
+static int
+hash_name_index(struct rpmdbstate *state, Chksum *chk)
+{
+  char *dbpath;
+  int fd, l;
+  char buf[4096];
+
+  dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? 
"/usr/share/rpm/" : "/var/lib/rpm/", "Name");
+  if ((fd = open(dbpath, O_RDONLY)) < 0)
+    return -1;
+  while ((l = read(fd, buf, sizeof(buf))) > 0)
+    solv_chksum_add(chk, buf, l);
+  close(fd);
+  return 0;
+}
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/ext/repo_rpmdb_librpm.h 
new/libsolv-0.7.10/ext/repo_rpmdb_librpm.h
--- old/libsolv-0.7.9/ext/repo_rpmdb_librpm.h   2019-10-21 14:59:05.000000000 
+0200
+++ new/libsolv-0.7.10/ext/repo_rpmdb_librpm.h  2019-12-19 16:34:10.000000000 
+0100
@@ -20,16 +20,35 @@
   char *rootdir;
 
   RpmHead *rpmhead;    /* header storage space */
-  int rpmheadsize;
+  unsigned int rpmheadsize;
 
   int dbenvopened;     /* database environment opened */
-  int pkgdbopened;     /* package database openend */
   int is_ostree;       /* read-only db that lives in /usr/share/rpm */
 
   rpmts ts;
   rpmdbMatchIterator mi;       /* iterator over packages database */
 };
 
+static inline int
+access_rootdir(struct rpmdbstate *state, const char *dir, int mode)
+{
+  if (state->rootdir)
+    {
+      char *path = solv_dupjoin(state->rootdir, dir, 0);
+      int r = access(path, mode);
+      free(path);
+      return r;
+    }
+  return access(dir, mode);
+}
+
+static void
+detect_ostree(struct rpmdbstate *state)
+{
+  state->is_ostree = access_rootdir(state, "/var/lib/rpm", W_OK) == -1 &&
+                     access_rootdir(state, "/usr/share/rpm/Packages", R_OK) == 
0 ? 1 : -1;
+}
+
 static int
 stat_database(struct rpmdbstate *state, struct stat *statbuf)
 {
@@ -43,9 +62,15 @@
   };
   int i;
 
+#ifdef HAVE_RPMDBFSTAT
+  if (state->dbenvopened == 1)
+    return rpmdbFStat(rpmtsGetRdb(state->ts), statbuf);
+#endif
+  if (!state->is_ostree)
+    detect_ostree(state);
   for (i = 0; ; i++)
     {
-      char *dbpath = solv_dupjoin(state->rootdir, state->is_ostree ? 
"/usr/share/rpm/" : "/var/lib/rpm/", dbname[i]);
+      char *dbpath = solv_dupjoin(state->rootdir, state->is_ostree > 0 ? 
"/usr/share/rpm/" : "/var/lib/rpm/", dbname[i]);
       if (!stat(dbpath, statbuf))
        {
          free(dbpath);
@@ -53,8 +78,10 @@
        }
       if (errno != ENOENT || !dbname[i + 1])
        {
+         int saved_errno = errno;
          pool_error(state->pool, -1, "%s: %s", dbpath, strerror(errno));
          solv_free(dbpath);
+         errno = saved_errno;
          return -1;
        }
       solv_free(dbpath);
@@ -68,16 +95,8 @@
   const char *rootdir = state->rootdir;
   rpmts ts;
   char *dbpath;
-  dbpath = solv_dupjoin("_dbpath ", rootdir, "/var/lib/rpm");
-  if (access(dbpath + 8, W_OK) == -1)
-    {
-      free(dbpath);
-      dbpath = solv_dupjoin(rootdir, "/usr/share/rpm/Packages", 0);
-      if (access(dbpath, R_OK) == 0)
-       state->is_ostree = 1;
-      free(dbpath);
-      dbpath = solv_dupjoin("_dbpath ", rootdir, state->is_ostree ? 
"/usr/share/rpm" : "/var/lib/rpm");
-    }
+  detect_ostree(state);
+  dbpath = solv_dupjoin("_dbpath ", rootdir, state->is_ostree > 0 ? 
"/usr/share/rpm" : "/var/lib/rpm");
   rpmDefineMacro(NULL, dbpath, 0);
   solv_free(dbpath);
   ts = rpmtsCreate();
@@ -98,7 +117,6 @@
   rpmtsSetVSFlags(ts, _RPMVSF_NODIGESTS | _RPMVSF_NOSIGNATURES | 
_RPMVSF_NOHEADER);
   state->ts = ts;
   state->dbenvopened = 1;
-  state->pkgdbopened = 1;
   return 1;
 }
 
@@ -108,22 +126,9 @@
   if (state->ts)
     rpmtsFree(state->ts);
   state->ts = 0;
-  state->pkgdbopened = 0;
   state->dbenvopened = 0;
 }
 
-static int
-openpkgdb(struct rpmdbstate *state)
-{
-  /* already done in opendbenv */
-  return 1;
-}
-
-static void
-closepkgdb(struct rpmdbstate *state)
-{
-}
-
 /* get the rpmdbids of all installed packages from the Name index database.
  * This is much faster then querying the big Packages database */
 static struct rpmdbentry *
@@ -139,7 +144,6 @@
   int nentries = 0;
 
   rpmdbIndexIterator ii;
-  int i;
 
   *nentriesp = 0;
   if (namedatap)
@@ -154,6 +158,7 @@
 
   while (rpmdbIndexIteratorNext(ii, &key, &keylen) == 0)
     {
+      unsigned int i, npkgs;
       if (match)
        {
          if (keylen != matchl || memcmp(key, match, keylen) != 0)
@@ -169,7 +174,8 @@
          namedata[namedatal + keylen] = 0;
          namedatal += keylen + 1;
        }
-      for (i = 0; i < rpmdbIndexIteratorNumPkgs(ii); i++)
+      npkgs = rpmdbIndexIteratorNumPkgs(ii);
+      for (i = 0; i < npkgs; i++)
        {
          entries = solv_extend(entries, nentries, 1, sizeof(*entries), 
ENTRIES_BLOCK);
          entries[nentries].rpmdbid = rpmdbIndexIteratorPkgOffset(ii, i);
@@ -187,17 +193,41 @@
   return entries;
 }
 
+#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM)
+static int headfromhdrblob(struct rpmdbstate *state, const unsigned char 
*data, unsigned int size);
+#endif
+
 /* retrive header by rpmdbid, returns 0 if not found, -1 on error */
 static int
 getrpm_dbid(struct rpmdbstate *state, Id rpmdbid)
 {
+#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM)
+  const unsigned char *uh;
+  unsigned int uhlen;
+#else
   Header h;
+#endif
   rpmdbMatchIterator mi;
   unsigned int offset = rpmdbid;
 
+  if (rpmdbid <= 0)
+    return pool_error(state->pool, -1, "illegal rpmdbid %d", rpmdbid);
   if (state->dbenvopened != 1 && !opendbenv(state))
     return -1;
-  mi = rpmtsInitIterator(state->ts, RPMDBI_PACKAGES, &offset, sizeof(offset));
+  mi = rpmdbInitIterator(rpmtsGetRdb(state->ts), RPMDBI_PACKAGES, &offset, 
sizeof(offset));
+#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM)
+  uh = rpmdbNextIteratorHeaderBlob(mi, &uhlen);
+  if (!uh)
+    {
+      rpmdbFreeIterator(mi);
+      return 0;
+    }
+  if (!headfromhdrblob(state, uh, uhlen))
+    {
+      rpmdbFreeIterator(mi);
+      return -1;
+    }
+#else
   h = rpmdbNextIterator(mi);
   if (!h)
     {
@@ -209,8 +239,9 @@
       rpmdbFreeIterator(mi);
       return -1;
     }
+#endif
   mi = rpmdbFreeIterator(mi);
-  return 1;
+  return rpmdbid;
 }
 
 static int
@@ -221,7 +252,7 @@
 
   if (state->dbenvopened != 1 && !opendbenv(state))
     return 0;
-  mi = rpmtsInitIterator(state->ts, RPMDBI_NAME, NULL, 0);
+  mi = rpmdbInitIterator(rpmtsGetRdb(state->ts), RPMDBI_NAME, NULL, 0);
   count = rpmdbGetIteratorCount(mi);
   rpmdbFreeIterator(mi);
   return count;
@@ -230,7 +261,7 @@
 static int
 pkgdb_cursor_open(struct rpmdbstate *state)
 {
-  state->mi = rpmtsInitIterator(state->ts, RPMDBI_PACKAGES, NULL, 0);
+  state->mi = rpmdbInitIterator(rpmtsGetRdb(state->ts), RPMDBI_PACKAGES, NULL, 
0);
   return 0;
 }
 
@@ -244,6 +275,17 @@
 static Id
 pkgdb_cursor_getrpm(struct rpmdbstate *state)
 {
+#if defined(HAVE_RPMDBNEXTITERATORHEADERBLOB) && !defined(ENABLE_RPMPKG_LIBRPM)
+  const unsigned char *uh;
+  unsigned int uhlen;
+  while ((uh = rpmdbNextIteratorHeaderBlob(state->mi, &uhlen)) != 0)
+    {
+      Id dbid = rpmdbGetIteratorOffset(state->mi);
+      if (!headfromhdrblob(state, uh, uhlen))
+       continue;
+      return dbid;
+    }
+#else
   Header h;
   while ((h = rpmdbNextIterator(state->mi)))
     {
@@ -252,6 +294,33 @@
        continue;
       return dbid;
     }
+#endif
+  return 0;
+}
+
+static int
+hash_name_index(struct rpmdbstate *state, Chksum *chk)
+{
+  rpmdbIndexIterator ii;
+  const void *key;
+  size_t keylen;
+
+  if (state->dbenvopened != 1 && !opendbenv(state))
+    return -1;
+  ii = rpmdbIndexIteratorInit(rpmtsGetRdb(state->ts), RPMDBI_NAME);
+  if (!ii)
+    return -1;
+  while (rpmdbIndexIteratorNext(ii, &key, &keylen) == 0)
+    {
+      unsigned int i, npkgs = rpmdbIndexIteratorNumPkgs(ii);
+      solv_chksum_add(chk, key, (int)keylen);
+      for (i = 0; i < npkgs; i++)
+       {
+         unsigned int offset = rpmdbIndexIteratorPkgOffset(ii, i);
+         solv_chksum_add(chk, &offset, sizeof(offset));
+       }
+    }
+  rpmdbIndexIteratorFree(ii);
   return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/ext/solv_zchunk.c 
new/libsolv-0.7.10/ext/solv_zchunk.c
--- old/libsolv-0.7.9/ext/solv_zchunk.c 2019-01-24 16:32:12.000000000 +0100
+++ new/libsolv-0.7.10/ext/solv_zchunk.c        2019-12-19 16:34:10.000000000 
+0100
@@ -75,12 +75,12 @@
     }
   if (++p < endp && (*p & 0x80) != 0)
     {
-      *dp = p[-3] ^ (p[-2] << 7) ^ (p[1] << 14) ^ ((p[0] ^ 0x80) << 21);
+      *dp = p[-3] ^ (p[-2] << 7) ^ (p[-1] << 14) ^ ((p[0] ^ 0x80) << 21);
       return p + 1;
     }
   if (++p < endp && (*p & 0xf0) == 0x80)
     {
-      *dp = p[-4] ^ (p[-3] << 7) ^ (p[2] << 14) ^ (p[1] << 21) ^ ((p[0] ^ 
0x80) << 28);
+      *dp = p[-4] ^ (p[-3] << 7) ^ (p[-2] << 14) ^ (p[-1] << 21) ^ ((p[0] ^ 
0x80) << 28);
       return p + 1;
     }
   return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsolv-0.7.9/package/libsolv.changes 
new/libsolv-0.7.10/package/libsolv.changes
--- old/libsolv-0.7.9/package/libsolv.changes   2019-11-21 16:39:09.000000000 
+0100
+++ new/libsolv-0.7.10/package/libsolv.changes  2019-12-19 16:34:10.000000000 
+0100
@@ -1,4 +1,23 @@
 -------------------------------------------------------------------
+Thu Dec 19 16:29:52 CET 2019 - [email protected]
+
+- fix solv_zchunk decoding error if large chunks are used
+  [bnc#1159314]
+
+-------------------------------------------------------------------
+Tue Dec 10 21:02:31 CET 2019 - [email protected]
+
+- build with -DENABLE_RPMDB_LIBRPM=1 on SUSE to support
+  multiple rpm database backends
+
+-------------------------------------------------------------------
+Tue Dec 10 14:18:36 CET 2019 - [email protected]
+
+- added two new function to make libzypp independent of the rpm
+  database format
+- bump version to 0.7.10
+
+-------------------------------------------------------------------
 Thu Nov 21 16:34:52 CET 2019 - [email protected]
 
 - support conda constrains dependencies


Reply via email to