Hello community, here is the log from the commit of package libsolv for openSUSE:Factory checked in at 2019-02-08 12:07:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libsolv (Old) and /work/SRC/openSUSE:Factory/.libsolv.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libsolv" Fri Feb 8 12:07:05 2019 rev:69 rq:670424 version:0.7.3 Changes: -------- --- /work/SRC/openSUSE:Factory/libsolv/libsolv.changes 2018-12-19 13:48:44.639340887 +0100 +++ /work/SRC/openSUSE:Factory/.libsolv.new.28833/libsolv.changes 2019-02-08 12:07:07.905610433 +0100 @@ -1,0 +2,11 @@ +Wed Jan 30 15:51:36 CET 2019 - [email protected] + +- fixed a couple of null pointer derefs + [bnc#1120629] [bnc#1120630] [bnc#1120631] +- do favor evaluation before pruning allowing to (dis)favor + specific package versions +- no longer disable infarch rules when they don't conflict with + the job +- bump version to 0.7.3 + +------------------------------------------------------------------- Old: ---- libsolv-0.7.2.tar.bz2 New: ---- libsolv-0.7.3.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libsolv.spec ++++++ --- /var/tmp/diff_new_pack.BLZPYh/_old 2019-02-08 12:07:08.565610185 +0100 +++ /var/tmp/diff_new_pack.BLZPYh/_new 2019-02-08 12:07:08.573610182 +0100 @@ -1,7 +1,7 @@ # # spec file for package libsolv # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -52,7 +52,7 @@ %bcond_with zypp Name: libsolv -Version: 0.7.2 +Version: 0.7.3 Release: 0 Summary: Package dependency solver using a satisfiability algorithm License: BSD-3-Clause @@ -221,7 +221,7 @@ CMAKE_FLAGS="-DSUSE=1" %endif -cmake $CMAKE_FLAGS \ +cmake . $CMAKE_FLAGS \ -DCMAKE_INSTALL_PREFIX=%{_prefix} \ -DLIB=%{_lib} \ -DCMAKE_VERBOSE_MAKEFILE=TRUE \ ++++++ libsolv-0.7.2.tar.bz2 -> libsolv-0.7.3.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/NEWS new/libsolv-0.7.3/NEWS --- old/libsolv-0.7.2/NEWS 2018-12-07 15:20:15.000000000 +0100 +++ new/libsolv-0.7.3/NEWS 2019-01-30 16:11:58.000000000 +0100 @@ -2,6 +2,18 @@ This file contains the major changes between libsolv versions: +Version 0.7.3 +- selected bug fixes: + * fixed a couple of null pointer derefs and potential memory + leaks + * made disfavoring recommended packages work if strong recommends + is enabled + * no longer disable infarch rules when they don't conflict with + the job +- new features: + * do favor evaluation before pruning allowing to (dis)favor + specific package versions + Version 0.7.2 - bug fixes: * do not autouninstall packages because of forcebest updates diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/VERSION.cmake new/libsolv-0.7.3/VERSION.cmake --- old/libsolv-0.7.2/VERSION.cmake 2018-12-07 15:20:15.000000000 +0100 +++ new/libsolv-0.7.3/VERSION.cmake 2019-01-30 16:11:58.000000000 +0100 @@ -49,5 +49,5 @@ SET(LIBSOLV_MAJOR "0") SET(LIBSOLV_MINOR "7") -SET(LIBSOLV_PATCH "2") +SET(LIBSOLV_PATCH "3") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/bindings/solv.i new/libsolv-0.7.3/bindings/solv.i --- old/libsolv-0.7.2/bindings/solv.i 2018-12-07 15:10:23.000000000 +0100 +++ new/libsolv-0.7.3/bindings/solv.i 2018-12-18 16:44:45.000000000 +0100 @@ -3454,6 +3454,7 @@ static const int SOLVER_FLAG_FOCUS_BEST = SOLVER_FLAG_FOCUS_BEST; static const int SOLVER_FLAG_STRONG_RECOMMENDS = SOLVER_FLAG_STRONG_RECOMMENDS; static const int SOLVER_FLAG_INSTALL_ALSO_UPDATES = SOLVER_FLAG_INSTALL_ALSO_UPDATES; + static const int SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED = SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED; static const int SOLVER_REASON_UNRELATED = SOLVER_REASON_UNRELATED; static const int SOLVER_REASON_UNIT_RULE = SOLVER_REASON_UNIT_RULE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/examples/solv/fastestmirror.c new/libsolv-0.7.3/examples/solv/fastestmirror.c --- old/libsolv-0.7.2/examples/solv/fastestmirror.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/examples/solv/fastestmirror.c 2018-12-11 13:59:34.000000000 +0100 @@ -68,7 +68,11 @@ socks[i] = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (socks[i] >= 0) { - fcntl(socks[i], F_SETFL, O_NONBLOCK); + if (fcntl(socks[i], F_SETFL, O_NONBLOCK) == -1) + { + close(socks[i]); + socks[i] = -1; + } if (connect(socks[i], result->ai_addr, result->ai_addrlen) == -1) { if (errno != EINPROGRESS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/ext/pool_fileconflicts.c new/libsolv-0.7.3/ext/pool_fileconflicts.c --- old/libsolv-0.7.2/ext/pool_fileconflicts.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/ext/pool_fileconflicts.c 2018-12-11 13:59:34.000000000 +0100 @@ -590,7 +590,6 @@ if (!info->dirlen) return; - dp = fn + info->dirlen; if (info->diridx != cbdata->lastdiridx) { cbdata->lastdiridx = info->diridx; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/ext/repo_appdata.c new/libsolv-0.7.3/ext/repo_appdata.c --- old/libsolv-0.7.2/ext/repo_appdata.c 2018-11-22 12:59:31.000000000 +0100 +++ new/libsolv-0.7.3/ext/repo_appdata.c 2018-12-11 13:59:34.000000000 +0100 @@ -103,7 +103,7 @@ { struct parsedata *pd = xmlp->userdata; Pool *pool = pd->pool; - Solvable *s = pd->solvable; + Solvable *s; const char *type; /* ignore all language tags */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/ext/repo_autopattern.c new/libsolv-0.7.3/ext/repo_autopattern.c --- old/libsolv-0.7.2/ext/repo_autopattern.c 2018-10-31 13:56:02.000000000 +0100 +++ new/libsolv-0.7.3/ext/repo_autopattern.c 2019-01-15 14:14:06.000000000 +0100 @@ -131,8 +131,8 @@ if (repo == pool->installed) flags |= ADD_NO_AUTOPRODUCTS; /* no auto products for installed repos */ - pattern_id = pool_str2id(pool, "pattern()", 9); - product_id = pool_str2id(pool, "product()", 9); + pattern_id = pool_str2id(pool, "pattern()", 1); + product_id = pool_str2id(pool, "product()", 1); queue_init(&categorykeys); FOR_REPO_SOLVABLES(repo, p, s) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/ext/repo_comps.c new/libsolv-0.7.3/ext/repo_comps.c --- old/libsolv-0.7.2/ext/repo_comps.c 2018-11-22 12:59:31.000000000 +0100 +++ new/libsolv-0.7.3/ext/repo_comps.c 2018-12-11 13:59:34.000000000 +0100 @@ -107,7 +107,7 @@ { struct parsedata *pd = xmlp->userdata; Pool *pool = pd->pool; - Solvable *s = pd->solvable; + Solvable *s; switch(state) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/ext/repo_repomdxml.c new/libsolv-0.7.3/ext/repo_repomdxml.c --- old/libsolv-0.7.2/ext/repo_repomdxml.c 2018-11-22 12:59:31.000000000 +0100 +++ new/libsolv-0.7.3/ext/repo_repomdxml.c 2018-12-11 13:59:34.000000000 +0100 @@ -181,7 +181,7 @@ while (value) { char *p = strchr(value, ','); - if (*p) + if (p) *p++ = 0; if (*value) repodata_add_poolstr_array(pd->data, SOLVID_META, REPOSITORY_UPDATES, value); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/ext/repo_rpmdb.c new/libsolv-0.7.3/ext/repo_rpmdb.c --- old/libsolv-0.7.2/ext/repo_rpmdb.c 2018-11-22 12:59:31.000000000 +0100 +++ new/libsolv-0.7.3/ext/repo_rpmdb.c 2018-12-11 14:29:32.000000000 +0100 @@ -1896,6 +1896,8 @@ if (fread(lead, 96 + 16, 1, fp) != 1 || getu32(lead) != 0xedabeedb) { pool_error(pool, -1, "%s: not a rpm", rpm); + solv_chksum_free(leadsigchksumh, 0); + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } @@ -1908,12 +1910,16 @@ if (lead[78] != 0 || lead[79] != 5) { pool_error(pool, -1, "%s: not a rpm v5 header", rpm); + solv_chksum_free(leadsigchksumh, 0); + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } if (getu32(lead + 96) != 0x8eade801) { pool_error(pool, -1, "%s: bad signature header", rpm); + solv_chksum_free(leadsigchksumh, 0); + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } @@ -1922,6 +1928,8 @@ if (sigcnt >= MAX_SIG_CNT || sigdsize >= MAX_SIG_DSIZE) { pool_error(pool, -1, "%s: bad signature header", rpm); + solv_chksum_free(leadsigchksumh, 0); + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } @@ -1932,6 +1940,8 @@ { if (!headfromfp(&state, rpm, fp, lead + 96, sigcnt, sigdsize, sigpad, chksumh, leadsigchksumh)) { + solv_chksum_free(leadsigchksumh, 0); + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } @@ -1971,6 +1981,8 @@ if (fread(lead, l, 1, fp) != 1) { pool_error(pool, -1, "%s: unexpected EOF", rpm); + solv_chksum_free(leadsigchksumh, 0); + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } @@ -1991,6 +2003,7 @@ if (fread(lead, 16, 1, fp) != 1) { pool_error(pool, -1, "%s: unexpected EOF", rpm); + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } @@ -1999,6 +2012,7 @@ if (getu32(lead) != 0x8eade801) { pool_error(pool, -1, "%s: bad header", rpm); + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } @@ -2007,6 +2021,7 @@ if (sigcnt >= MAX_HDR_CNT || sigdsize >= MAX_HDR_DSIZE) { pool_error(pool, -1, "%s: bad header", rpm); + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } @@ -2014,6 +2029,7 @@ if (!headfromfp(&state, rpm, fp, lead, sigcnt, sigdsize, 0, chksumh, 0)) { + solv_chksum_free(chksumh, 0); fclose(fp); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/ext/solv_zchunk.c new/libsolv-0.7.3/ext/solv_zchunk.c --- old/libsolv-0.7.2/ext/solv_zchunk.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/ext/solv_zchunk.c 2019-01-24 16:32:12.000000000 +0100 @@ -300,10 +300,28 @@ #endif if ((p = getuint(p, zck->hdr_end, &zck->flags)) == 0) return open_error(zck); - if ((zck->flags & ~(1)) != 0) + if ((zck->flags & ~(3)) != 0) return open_error(zck); if ((p = getuint(p, zck->hdr_end, &zck->comp)) == 0 || (zck->comp != 0 && zck->comp != 2)) return open_error(zck); /* only uncompressed + zstd supported */ + /* skip all optional elements if present */ + if ((zck->flags & 2) != 0) + { + unsigned int nopt, lopt; + if ((p = getuint(p, zck->hdr_end, &nopt)) == 0) + return open_error(zck); + for (; nopt != 0; nopt--) + { + if ((p = getuint(p, zck->hdr_end, &lopt)) == 0) + return open_error(zck); + if ((p = getuint(p, zck->hdr_end, &lopt)) == 0) + return open_error(zck); + if (p + lopt > zck->hdr_end) + return open_error(zck); + p += lopt; + } + } + preface_size = p - (zck->hdr + lead_size); /* parse index: index size, index chksum type, num chunks, chunk data */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/ext/testcase.c new/libsolv-0.7.3/ext/testcase.c --- old/libsolv-0.7.2/ext/testcase.c 2018-11-26 12:59:35.000000000 +0100 +++ new/libsolv-0.7.3/ext/testcase.c 2018-12-20 17:35:49.000000000 +0100 @@ -576,6 +576,8 @@ Id flags, id, id2, namespaceid = 0; struct oplist *op; + if (!s) + return 0; while (*s == ' ' || *s == '\t') s++; if (!strncmp(s, "namespace:", 10)) @@ -964,11 +966,101 @@ return jobflags; } +static Id +testcase_str2jobsel(Pool *pool, const char *caller, char **pieces, int npieces, Id *whatp) +{ + Id job, what; + if (!strcmp(pieces[0], "pkg") && npieces == 2) + { + job = SOLVER_SOLVABLE; + what = testcase_str2solvid(pool, pieces[1]); + if (!what) + return pool_error(pool, -1, "%s: unknown package '%s'", caller, pieces[1]); + } + else if (!strcmp(pieces[0], "name") || !strcmp(pieces[0], "provides")) + { + /* join em again for dep2str... */ + char *sp; + for (sp = pieces[1]; sp < pieces[npieces - 1]; sp++) + if (*sp == 0) + *sp = ' '; + what = 0; + if (pieces[0][0] == 'p' && strncmp(pieces[1], "namespace:", 10) == 0) + { + char *spe = strchr(pieces[1], '('); + int l = strlen(pieces[1]); + if (spe && pieces[1][l - 1] == ')') + { + /* special namespace provides */ + if (strcmp(spe, "(<NULL>)") != 0) + { + pieces[1][l - 1] = 0; + what = testcase_str2dep(pool, spe + 1); + pieces[1][l - 1] = ')'; + } + what = pool_rel2id(pool, pool_strn2id(pool, pieces[1], spe - pieces[1], 1), what, REL_NAMESPACE, 1); + } + } + if (!what) + what = testcase_str2dep(pool, pieces[1]); + if (pieces[0][0] == 'n') + job = SOLVER_SOLVABLE_NAME; + else + job = SOLVER_SOLVABLE_PROVIDES; + } + else if (!strcmp(pieces[0], "oneof")) + { + Queue q; + job = SOLVER_SOLVABLE_ONE_OF; + queue_init(&q); + if (npieces > 1 && strcmp(pieces[1], "nothing") != 0) + { + int i; + for (i = 1; i < npieces; i++) + { + Id p = testcase_str2solvid(pool, pieces[i]); + if (!p) + { + queue_free(&q); + return pool_error(pool, -1, "%s: unknown package '%s'", caller, pieces[i]); + } + queue_push(&q, p); + } + } + what = pool_queuetowhatprovides(pool, &q); + queue_free(&q); + } + else if (!strcmp(pieces[0], "repo") && npieces == 2) + { + Repo *repo = testcase_str2repo(pool, pieces[1]); + if (!repo) + return pool_error(pool, -1, "%s: unknown repo '%s'", caller, pieces[1]); + job = SOLVER_SOLVABLE_REPO; + what = repo->repoid; + } + else if (!strcmp(pieces[0], "all") && npieces == 2 && !strcmp(pieces[1], "packages")) + { + job = SOLVER_SOLVABLE_ALL; + what = 0; + } + else + { + /* join em again for the error message... */ + char *sp; + for (sp = pieces[0]; sp < pieces[npieces - 1]; sp++) + if (*sp == 0) + *sp = ' '; + return pool_error(pool, -1, "%s: bad line '%s'", caller, pieces[0]); + } + *whatp = what; + return job; +} + Id testcase_str2job(Pool *pool, const char *str, Id *whatp) { int i; - Id job; + Id job, jobsel; Id what; char *s; char **pieces = 0; @@ -1020,116 +1112,12 @@ job |= str2jobflags(pool, flags); } } - if (!strcmp(pieces[1], "pkg")) - { - if (npieces != 3) - { - pool_error(pool, -1, "str2job: bad pkg selector in '%s'", str); - solv_free(pieces); - return -1; - } - job |= SOLVER_SOLVABLE; - what = testcase_str2solvid(pool, pieces[2]); - if (!what) - { - pool_error(pool, -1, "str2job: unknown package '%s'", pieces[2]); - solv_free(pieces); - return -1; - } - } - else if (!strcmp(pieces[1], "name") || !strcmp(pieces[1], "provides")) - { - /* join em again for dep2str... */ - char *sp; - for (sp = pieces[2]; sp < pieces[npieces - 1]; sp++) - if (*sp == 0) - *sp = ' '; - what = 0; - if (pieces[1][0] == 'p' && strncmp(pieces[2], "namespace:", 10) == 0) - { - char *spe = strchr(pieces[2], '('); - int l = strlen(pieces[2]); - if (spe && pieces[2][l - 1] == ')') - { - /* special namespace provides */ - if (strcmp(spe, "(<NULL>)") != 0) - { - pieces[2][l - 1] = 0; - what = testcase_str2dep(pool, spe + 1); - pieces[2][l - 1] = ')'; - } - what = pool_rel2id(pool, pool_strn2id(pool, pieces[2], spe - pieces[2], 1), what, REL_NAMESPACE, 1); - } - } - if (!what) - what = testcase_str2dep(pool, pieces[2]); - if (pieces[1][0] == 'n') - job |= SOLVER_SOLVABLE_NAME; - else - job |= SOLVER_SOLVABLE_PROVIDES; - } - else if (!strcmp(pieces[1], "oneof")) - { - Queue q; - job |= SOLVER_SOLVABLE_ONE_OF; - queue_init(&q); - if (npieces > 2 && strcmp(pieces[2], "nothing") != 0) - { - for (i = 2; i < npieces; i++) - { - Id p = testcase_str2solvid(pool, pieces[i]); - if (!p) - { - pool_error(pool, -1, "str2job: unknown package '%s'", pieces[i]); - queue_free(&q); - solv_free(pieces); - return -1; - } - queue_push(&q, p); - } - } - what = pool_queuetowhatprovides(pool, &q); - queue_free(&q); - } - else if (!strcmp(pieces[1], "repo")) - { - Repo *repo; - if (npieces != 3) - { - pool_error(pool, -1, "str2job: bad line '%s'", str); - solv_free(pieces); - return -1; - } - repo = testcase_str2repo(pool, pieces[2]); - if (!repo) - { - pool_error(pool, -1, "str2job: unknown repo '%s'", pieces[2]); - solv_free(pieces); - return -1; - } - job |= SOLVER_SOLVABLE_REPO; - what = repo->repoid; - } - else if (!strcmp(pieces[1], "all")) - { - if (npieces != 3 && strcmp(pieces[2], "packages") != 0) - { - pool_error(pool, -1, "str2job: bad line '%s'", str); - solv_free(pieces); - return -1; - } - job |= SOLVER_SOLVABLE_ALL; - what = 0; - } - else - { - pool_error(pool, -1, "str2job: unknown selection in '%s'", str); - solv_free(pieces); - return -1; - } - *whatp = what; + jobsel = testcase_str2jobsel(pool, "str2job", pieces + 1, npieces - 1, &what); solv_free(pieces); - return job; + if (jobsel == -1) + return -1; + *whatp = what; + return job | jobsel; } #define SELECTIONJOB_MATCHDEPS 1 @@ -1816,6 +1804,7 @@ { SOLVER_RULE_LEARNT, "learnt" }, { SOLVER_RULE_BEST, "best" }, { SOLVER_RULE_YUMOBS, "yumobs" }, + { SOLVER_RULE_RECOMMENDS, "recommends" }, { 0, 0 } }; @@ -2023,6 +2012,8 @@ /* map choice rules back to pkg rules */ if (solver_ruleclass(solv, id) == SOLVER_RULE_CHOICE) id = solver_rule2pkgrule(solv, id); + if (solver_ruleclass(solv, id) == SOLVER_RULE_RECOMMENDS) + id = solver_rule2pkgrule(solv, id); solver_allruleinfos(solv, id, &rq); for (i = 0; i < rq.count; i += 4) { @@ -2187,7 +2178,7 @@ Id lowscore; FILE *fp; Strqueue sq; - char *cmd, *out; + char *cmd, *out, *result; const char *s; if (!testcasename) @@ -2322,7 +2313,6 @@ if ((resultflags & ~TESTCASE_RESULT_REUSE_SOLVER) != 0) { - char *result; cmd = 0; for (i = 0; resultflags2str[i].str; i++) if ((resultflags & resultflags2str[i].flag) != 0) @@ -2333,7 +2323,6 @@ result = testcase_solverresult(solv, resultflags); if (!strcmp(resultname, "<inline>")) { - int i; Strqueue rsq; strqueue_init(&rsq); strqueue_split(&rsq, result); @@ -2365,6 +2354,7 @@ if (fclose(fp)) { pool_error(solv->pool, 0, "testcase_write: write error"); + solv_free(result); strqueue_free(&sq); return 0; } @@ -2372,29 +2362,29 @@ solv_free(result); } - cmd = strqueue_join(&sq); + result = strqueue_join(&sq); + strqueue_free(&sq); out = pool_tmpjoin(pool, dir, "/", testcasename); if (!(fp = fopen(out, "w"))) { pool_error(solv->pool, 0, "testcase_write: could not open '%s' for writing", out); - strqueue_free(&sq); + solv_free(result); return 0; } - if (*cmd && fwrite(cmd, strlen(cmd), 1, fp) != 1) + if (*result && fwrite(result, strlen(result), 1, fp) != 1) { pool_error(solv->pool, 0, "testcase_write: write error"); - strqueue_free(&sq); + solv_free(result); fclose(fp); return 0; } if (fclose(fp)) { pool_error(solv->pool, 0, "testcase_write: write error"); - strqueue_free(&sq); + solv_free(result); return 0; } - solv_free(cmd); - strqueue_free(&sq); + solv_free(result); return 1; } @@ -2789,7 +2779,7 @@ { int i = strlen(pieces[1]); s = strchr(pieces[1], '('); - if (!s && pieces[1][i - 1] != ')') + if (!s || pieces[1][i - 1] != ')') { pool_error(pool, 0, "testcase_read: bad namespace '%s'", pieces[1]); } @@ -2877,12 +2867,7 @@ } else if (!strcmp(pieces[0], "disable") && npieces == 3) { - Id p; - if (strcmp(pieces[1], "pkg")) - { - pool_error(pool, 0, "testcase_read: bad disable type '%s'", pieces[1]); - continue; - } + Id p, pp, jobsel, what = 0; if (!prepared) pool_createwhatprovides(pool); prepared = -1; @@ -2892,11 +2877,20 @@ map_init(pool->considered, pool->nsolvables); map_setall(pool->considered); } - p = testcase_str2solvid(pool, pieces[2]); - if (p) + jobsel = testcase_str2jobsel(pool, "disable", pieces + 1, npieces - 1, &what); + if (jobsel < 0) + continue; + if (jobsel == SOLVER_SOLVABLE_ALL) + map_empty(pool->considered); + else if (jobsel == SOLVER_SOLVABLE_REPO) + { + Repo *repo = pool_id2repo(pool, what); + Solvable *s; + FOR_REPO_SOLVABLES(repo, p, s) + MAPCLR(pool->considered, p); + } + FOR_JOB_SELECT(p, pp, jobsel, what) MAPCLR(pool->considered, p); - else - pool_error(pool, 0, "disable: unknown package '%s'", pieces[2]); } else if (!strcmp(pieces[0], "feature")) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/package/libsolv.changes new/libsolv-0.7.3/package/libsolv.changes --- old/libsolv-0.7.2/package/libsolv.changes 2018-12-07 15:20:15.000000000 +0100 +++ new/libsolv-0.7.3/package/libsolv.changes 2019-01-30 16:11:58.000000000 +0100 @@ -1,4 +1,15 @@ ------------------------------------------------------------------- +Wed Jan 30 15:51:36 CET 2019 - [email protected] + +- fixed a couple of null pointer derefs + [bnc#1120629] [bnc#1120630] [bnc#1120631] +- do favor evaluation before pruning allowing to (dis)favor + specific package versions +- no longer disable infarch rules when they don't conflict with + the job +- bump version to 0.7.3 + +------------------------------------------------------------------- Fri Dec 7 15:10:46 CET 2018 - [email protected] - do not autouninstall packages because of forcebest updates diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/package/libsolv.spec.in new/libsolv-0.7.3/package/libsolv.spec.in --- old/libsolv-0.7.2/package/libsolv.spec.in 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/package/libsolv.spec.in 2019-01-30 15:47:03.000000000 +0100 @@ -221,7 +221,7 @@ CMAKE_FLAGS="-DSUSE=1" %endif -cmake $CMAKE_FLAGS \ +cmake . $CMAKE_FLAGS \ -DCMAKE_INSTALL_PREFIX=%{_prefix} \ -DLIB=%{_lib} \ -DCMAKE_VERBOSE_MAKEFILE=TRUE \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/cleandeps.c new/libsolv-0.7.3/src/cleandeps.c --- old/libsolv-0.7.2/src/cleandeps.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/src/cleandeps.c 2018-12-19 14:30:15.000000000 +0100 @@ -748,7 +748,6 @@ continue; if (strncmp(pool_id2str(pool, s->name), "pattern:", 8) != 0) continue; - dp = s->repo->idarraydata + s->requires; for (dp = s->repo->idarraydata + s->requires; *dp; dp++) FOR_PROVIDES(p, pp, *dp) if (pool->solvables[p].repo == installed) @@ -1368,11 +1367,11 @@ if (!r->p || r == fr || cleandeps_rule_is_true(solv, r)) { /* update rule is true, check best rules */ - if (!solv->bestrules_pkg) + if (!solv->bestrules_info) continue; nj = solv->bestrules_end - solv->bestrules; - for (j = 0; j < nj; j++) - if (solv->bestrules_pkg[j] == i) + for (j = solv->bestrules_up - solv->bestrules; j < nj; j++) + if (solv->bestrules_info[j] == i) { r = solv->rules + solv->bestrules + j; if (!cleandeps_rule_is_true(solv, r)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/dirpool.c new/libsolv-0.7.3/src/dirpool.c --- old/libsolv-0.7.2/src/dirpool.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/src/dirpool.c 2018-12-11 13:59:34.000000000 +0100 @@ -85,7 +85,7 @@ return; dp->dirs = solv_extend_resize(dp->dirs, dp->ndirs, sizeof(Id), DIR_BLOCK); dirtraverse = solv_calloc_block(dp->ndirs, sizeof(Id), DIR_BLOCK); - for (parent = 0, i = 0; i < dp->ndirs; i++) + for (i = 0; i < dp->ndirs; i++) { if (dp->dirs[i] > 0) continue; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/order.c new/libsolv-0.7.3/src/order.c --- old/libsolv-0.7.2/src/order.c 2018-10-22 15:37:12.000000000 +0200 +++ new/libsolv-0.7.3/src/order.c 2018-12-11 13:59:34.000000000 +0100 @@ -1066,7 +1066,6 @@ #if 0 printf("do %s [%d]\n", pool_solvid2str(pool, te->p), temedianr[i]); #endif - s = pool->solvables + te->p; for (j = te->edges; od.invedgedata[j]; j++) { struct s_TransactionElement *te2 = od.tes + od.invedgedata[j]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/pool.c new/libsolv-0.7.3/src/pool.c --- old/libsolv-0.7.2/src/pool.c 2018-10-22 15:37:12.000000000 +0200 +++ new/libsolv-0.7.3/src/pool.c 2018-12-11 13:59:34.000000000 +0100 @@ -1536,6 +1536,7 @@ vprintf(format, args); else vfprintf(stderr, format, args); + va_end(args); return; } vsnprintf(buf, sizeof(buf), format, args); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/problems.c new/libsolv-0.7.3/src/problems.c --- old/libsolv-0.7.2/src/problems.c 2018-11-30 15:09:39.000000000 +0100 +++ new/libsolv-0.7.3/src/problems.c 2018-12-19 14:30:15.000000000 +0100 @@ -64,12 +64,12 @@ } v = -(v + 1); jp = solv->ruletojob.elements; - if (solv->bestrules_pkg) + if (solv->bestrules_info) { int ni = solv->bestrules_up - solv->bestrules; for (i = 0; i < ni; i++) { - int j = solv->bestrules_pkg[i]; + int j = solv->bestrules_info[i]; if (j < 0 && jp[-j - solv->jobrules] == v) solver_disablerule(solv, solv->rules + solv->bestrules + i); } @@ -131,12 +131,12 @@ } v = -(v + 1); jp = solv->ruletojob.elements; - if (solv->bestrules_pkg) + if (solv->bestrules_info) { int ni = solv->bestrules_up - solv->bestrules; for (i = 0; i < ni; i++) { - int j = solv->bestrules_pkg[i]; + int j = solv->bestrules_info[i]; if (j < 0 && jp[-j - solv->jobrules] == v) solver_enablerule(solv, solv->rules + solv->bestrules + i); } @@ -155,8 +155,8 @@ { if (rid >= solv->jobrules && rid < solv->jobrules_end) rid = -(solv->ruletojob.elements[rid - solv->jobrules] + 1); - else if (rid >= solv->bestrules && rid < solv->bestrules_up && solv->bestrules_pkg[rid - solv->bestrules] < 0) - rid = -(solv->ruletojob.elements[-solv->bestrules_pkg[rid - solv->bestrules] - solv->jobrules] + 1); + else if (rid >= solv->bestrules && rid < solv->bestrules_up && solv->bestrules_info[rid - solv->bestrules] < 0) + rid = -(solv->ruletojob.elements[-solv->bestrules_info[rid - solv->bestrules] - solv->jobrules] + 1); else if (rid > solv->infarchrules && rid < solv->infarchrules_end) { Pool *pool = solv->pool; @@ -252,13 +252,13 @@ continue; if (pool->considered && !MAPTST(pool->considered, p)) continue; /* do not uninstalled disabled packages */ - if (solv->bestrules_pkg && solv->bestrules_end > solv->bestrules) + if (solv->bestrules_info && solv->bestrules_end > solv->bestrules) { int j; for (j = start + 1; j < solv->problems.count - 1; j++) { Id vv = solv->problems.elements[j]; - if (vv >= solv->bestrules && vv < solv->bestrules_end && solv->bestrules_pkg[vv - solv->bestrules] == p) + if (vv >= solv->bestrules && vv < solv->bestrules_end && solv->bestrules_info[vv - solv->bestrules] == p) break; } if (j < solv->problems.count - 1) @@ -678,7 +678,7 @@ if (p > 0 && solv->decisionmap[p] > 0) return; /* false alarm */ /* check update/feature rule */ - p = solv->bestrules_pkg[why - solv->bestrules]; + p = solv->bestrules_info[why - solv->bestrules]; if (p < 0) { /* install job */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/repopage.c new/libsolv-0.7.3/src/repopage.c --- old/libsolv-0.7.2/src/repopage.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/src/repopage.c 2018-12-11 13:59:34.000000000 +0100 @@ -399,7 +399,6 @@ litlen -= 32; } } - litofs = 0; } return oo; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/rules.c new/libsolv-0.7.3/src/rules.c --- old/libsolv-0.7.2/src/rules.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/src/rules.c 2019-01-24 16:32:12.000000000 +0100 @@ -1463,12 +1463,12 @@ r = solv->rules + solv->featurerules + (p - solv->installed->start); if (r->p && r->d >= 0) solver_disablerule(solv, r); - if (solv->bestrules_pkg) + if (solv->bestrules_info) { int i, ni; ni = solv->bestrules_end - solv->bestrules; for (i = solv->bestrules_up - solv->bestrules; i < ni; i++) - if (solv->bestrules_pkg[i] == p) + if (solv->bestrules_info[i] == p) solver_disablerule(solv, solv->rules + solv->bestrules + i); } } @@ -1506,12 +1506,12 @@ } } } - if (solv->bestrules_pkg) + if (solv->bestrules_info) { int i, ni; ni = solv->bestrules_end - solv->bestrules; for (i = solv->bestrules_up - solv->bestrules; i < ni; i++) - if (solv->bestrules_pkg[i] == p) + if (solv->bestrules_info[i] == p) solver_enablerule(solv, solv->rules + solv->bestrules + i); } } @@ -1674,11 +1674,15 @@ } if (installed && pool->solvables[p].repo == installed && !haveinstalled) continue; /* installed package not in lock-step */ + if (lsq.count < 2) + solver_addrule(solv, -p, lsq.count ? lsq.elements[0] : 0, 0); + else + solver_addrule(solv, -p, 0, pool_queuetowhatprovides(pool, &lsq)); } - if (lsq.count < 2) - solver_addrule(solv, -p, lsq.count ? lsq.elements[0] : 0, 0); else - solver_addrule(solv, -p, 0, pool_queuetowhatprovides(pool, &lsq)); + { + solver_addrule(solv, -p, 0, 0); + } } } queue_free(&lsq); @@ -2126,7 +2130,13 @@ if ((set & SOLVER_SETARCH) != 0 && solv->infarchrules != solv->infarchrules_end) { if (select == SOLVER_SOLVABLE) - queue_push2(q, DISABLE_INFARCH, pool->solvables[what].name); + { + for (i = solv->infarchrules; i < solv->infarchrules_end; i++) + if (solv->rules[i].p == -what) + break; + if (i < solv->infarchrules_end) + queue_push2(q, DISABLE_INFARCH, pool->solvables[what].name); + } else { int qcnt = q->count; @@ -2140,8 +2150,12 @@ if (q->elements[i + 1] == s->name) break; if (i < q->count) - continue; - queue_push2(q, DISABLE_INFARCH, s->name); + continue; /* already have that DISABLE_INFARCH element */ + for (i = solv->infarchrules; i < solv->infarchrules_end; i++) + if (solv->rules[i].p == -p) + break; + if (i < solv->infarchrules_end) + queue_push2(q, DISABLE_INFARCH, s->name); } } } @@ -2719,8 +2733,8 @@ } if (rid >= solv->bestrules && rid < solv->bestrules_end) { - if (fromp && solv->bestrules_pkg[rid - solv->bestrules] > 0) - *fromp = solv->bestrules_pkg[rid - solv->bestrules]; + if (fromp && solv->bestrules_info[rid - solv->bestrules] > 0) + *fromp = solv->bestrules_info[rid - solv->bestrules]; return SOLVER_RULE_BEST; } if (rid >= solv->yumobsrules && rid < solv->yumobsrules_end) @@ -2740,13 +2754,11 @@ return SOLVER_RULE_YUMOBS; } if (rid >= solv->choicerules && rid < solv->choicerules_end) - { - return SOLVER_RULE_CHOICE; - } + return SOLVER_RULE_CHOICE; + if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end) + return SOLVER_RULE_RECOMMENDS; if (rid >= solv->learntrules) - { - return SOLVER_RULE_LEARNT; - } + return SOLVER_RULE_LEARNT; return SOLVER_RULE_UNKNOWN; } @@ -2773,6 +2785,8 @@ return SOLVER_RULE_YUMOBS; if (rid >= solv->choicerules && rid < solv->choicerules_end) return SOLVER_RULE_CHOICE; + if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end) + return SOLVER_RULE_RECOMMENDS; if (rid >= solv->learntrules && rid < solv->nrules) return SOLVER_RULE_LEARNT; return SOLVER_RULE_UNKNOWN; @@ -2834,7 +2848,9 @@ solver_rule2pkgrule(Solver *solv, Id rid) { if (rid >= solv->choicerules && rid < solv->choicerules_end) - return solv->choicerules_ref[rid - solv->choicerules]; + return solv->choicerules_info[rid - solv->choicerules]; + if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end) + return solv->recommendsrules_info[rid - solv->recommendsrules]; return 0; } @@ -2950,7 +2966,7 @@ Pool *pool = solv->pool; Map m, mneg; Rule *r; - Queue q, qi, qcheck; + Queue q, qi, qcheck, infoq; int i, j, rid, havechoice; Id p, d, pp; Id p2, pp2; @@ -2966,10 +2982,11 @@ return; } now = solv_timems(0); - solv->choicerules_ref = solv_calloc(solv->pkgrules_end, sizeof(Id)); + solv->choicerules_info = solv_calloc(solv->pkgrules_end, sizeof(Id)); queue_init(&q); queue_init(&qi); queue_init(&qcheck); + queue_init(&infoq); map_init(&m, pool->nsolvables); map_init(&mneg, pool->nsolvables); /* set up negative assertion map from infarch and dup rules */ @@ -3158,7 +3175,7 @@ solver_addrule(solv, r->p, 0, d); queue_push(&solv->weakruleq, solv->nrules - 1); - solv->choicerules_ref[solv->nrules - 1 - solv->choicerules] = rid; + queue_push(&infoq, rid); #if 0 printf("OLD "); solver_printrule(solv, SOLV_DEBUG_RESULT, solv->rules + rid); @@ -3166,20 +3183,21 @@ solver_printrule(solv, SOLV_DEBUG_RESULT, solv->rules + solv->nrules - 1); #endif } + if (infoq.count) + solv->choicerules_info = solv_memdup2(infoq.elements, infoq.count, sizeof(Id)); queue_free(&q); queue_free(&qi); queue_free(&qcheck); + queue_free(&infoq); map_free(&m); map_free(&mneg); solv->choicerules_end = solv->nrules; - /* shrink choicerules_ref */ - solv->choicerules_ref = solv_realloc2(solv->choicerules_ref, solv->choicerules_end - solv->choicerules, sizeof(Id)); POOL_DEBUG(SOLV_DEBUG_STATS, "choice rule creation took %d ms\n", solv_timems(now)); } -/* called when a choice rule is disabled by analyze_unsolvable. We also - * have to disable all other choice rules so that the best packages get - * picked */ +/* called when a choice rule needs to be disabled by analyze_unsolvable. + * We also have to disable all other choice rules so that the best packages + * get picked */ void solver_disablechoicerules(Solver *solv, Rule *r) { @@ -3188,7 +3206,8 @@ Map m; Rule *or; - or = solv->rules + solv->choicerules_ref[(r - solv->rules) - solv->choicerules]; + solver_disablerule(solv, r); + or = solv->rules + solv->choicerules_info[(r - solv->rules) - solv->choicerules]; map_init(&m, pool->nsolvables); FOR_RULELITERALS(p, pp, or) if (p > 0) @@ -3201,7 +3220,7 @@ r = solv->rules + rid; if (r->d < 0) continue; - or = solv->rules + solv->choicerules_ref[(r - solv->rules) - solv->choicerules]; + or = solv->rules + solv->choicerules_info[rid - solv->choicerules]; FOR_RULELITERALS(p, pp, or) if (p > 0 && MAPTST(&m, p)) break; @@ -3250,13 +3269,13 @@ Repo *installed = solv->installed; Queue q, q2; Rule *r; - Queue r2pkg; + Queue infoq; int i, oldcnt; solv->bestrules = solv->nrules; queue_init(&q); queue_init(&q2); - queue_init(&r2pkg); + queue_init(&infoq); if (havebestinstalljobs) { @@ -3297,7 +3316,7 @@ solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q)); if ((how & SOLVER_WEAK) != 0) queue_push(&solv->weakruleq, solv->nrules - 1); - queue_push(&r2pkg, -(solv->jobrules + j)); + queue_push(&infoq, -(solv->jobrules + j)); } } } @@ -3387,7 +3406,7 @@ solver_addrule(solv, -p2, d, 0); else solver_addrule(solv, -p2, 0, -d); - queue_push(&r2pkg, p); + queue_push(&infoq, p); } for (i = 0; i < q.count; i++) MAPCLR(&m, q.elements[i]); @@ -3398,16 +3417,16 @@ solver_addrule(solv, p2, q.count ? q.elements[0] : 0, 0); else solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q)); - queue_push(&r2pkg, p); + queue_push(&infoq, p); } map_free(&m); } - if (r2pkg.count) - solv->bestrules_pkg = solv_memdup2(r2pkg.elements, r2pkg.count, sizeof(Id)); + if (infoq.count) + solv->bestrules_info = solv_memdup2(infoq.elements, infoq.count, sizeof(Id)); solv->bestrules_end = solv->nrules; queue_free(&q); queue_free(&q2); - queue_free(&r2pkg); + queue_free(&infoq); } @@ -3442,7 +3461,7 @@ continue; if ((pool->obsoleteusescolors || pool->implicitobsoleteusescolors) && !pool_colormatch(pool, s2, os)) continue; - obsp2 = os->repo->idarraydata + os->obsoletes; + obsp2 = os->repo->idarraydata + os->obsoletes; while ((obs2 = *obsp2++) != 0) if (obs2 == obs) break; @@ -3460,7 +3479,7 @@ continue; if ((pool->obsoleteusescolors || pool->implicitobsoleteusescolors) && !pool_colormatch(pool, s2, os)) continue; - obsp2 = os->repo->idarraydata + os->obsoletes; + obsp2 = os->repo->idarraydata + os->obsoletes; while ((obs2 = *obsp2++) != 0) if (obs2 == obs) break; @@ -3524,7 +3543,7 @@ Repo *installed = solv->installed; Id p, op, *opp; Solvable *s; - Queue qo, qq, yumobsinfoq; + Queue qo, qq, infoq; int i, j, k; unsigned int now; @@ -3570,7 +3589,7 @@ queue_free(&qo); return; } - queue_init(&yumobsinfoq); + queue_init(&infoq); queue_init(&qq); for (i = 0; i < qo.count; i++) { @@ -3588,7 +3607,7 @@ else printf("%s\n", pool_solvid2str(pool, qq.elements[j])); #endif - + if (!qq.count) continue; /* at least two goups, build rules */ @@ -3617,22 +3636,70 @@ solver_addrule(solv, -p, qq.elements[groupstart], 0); else solver_addrule(solv, -p, 0, pool_ids2whatprovides(pool, qq.elements + groupstart, k - groupstart)); - queue_push(&yumobsinfoq, qo.elements[i]); + queue_push(&infoq, qo.elements[i]); } groupstart = k + 1; groupk++; } } } - if (yumobsinfoq.count) - solv->yumobsrules_info = solv_memdup2(yumobsinfoq.elements, yumobsinfoq.count, sizeof(Id)); - queue_free(&yumobsinfoq); + if (infoq.count) + solv->yumobsrules_info = solv_memdup2(infoq.elements, infoq.count, sizeof(Id)); + queue_free(&infoq); queue_free(&qq); queue_free(&qo); solv->yumobsrules_end = solv->nrules; POOL_DEBUG(SOLV_DEBUG_STATS, "yumobs rule creation took %d ms\n", solv_timems(now)); } +/* recommendsrules are a copy of some recommends package rule but + * with some disfavored literals removed */ +void +solver_addrecommendsrules(Solver *solv) +{ + Pool *pool = solv->pool; + int i, havedis, havepos; + Id p, pp; + Queue q, infoq; + + solv->recommendsrules = solv->nrules; + queue_init(&q); + queue_init(&infoq); + for (i = 0; i < solv->recommendsruleq->count; i++) + { + int rid = solv->recommendsruleq->elements[i]; + Rule *r = solv->rules + rid; + queue_empty(&q); + havedis = havepos = 0; + FOR_RULELITERALS(p, pp, r) + { + if (p > 0 && solv->favormap[p] < 0) + havedis = 1; + else + { + if (p > 0) + havepos = 1; + queue_push(&q, p); + } + } + if (!havedis) + continue; + solver_disablerule(solv, r); + if (!havepos || q.count < 2) + continue; + if (q.count == 2) + solver_addrule(solv, q.elements[0], q.elements[1], 0); + else + solver_addrule(solv, q.elements[0], 0, pool_ids2whatprovides(pool, q.elements + 1, q.count - 1)); + queue_push(&infoq, rid); + } + if (infoq.count) + solv->recommendsrules_info = solv_memdup2(infoq.elements, infoq.count, sizeof(Id)); + queue_free(&infoq); + queue_free(&q); + solv->recommendsrules_end = solv->nrules; +} + void solver_breakorphans(Solver *solv) { @@ -3696,7 +3763,7 @@ Pool *pool = solv->pool; int i; Id l, pp; - + queue_empty(dq); if (!solv->brokenorphanrules) return; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/rules.h new/libsolv-0.7.3/src/rules.h --- old/libsolv-0.7.2/src/rules.h 2018-10-22 15:37:12.000000000 +0200 +++ new/libsolv-0.7.3/src/rules.h 2018-12-18 16:44:45.000000000 +0100 @@ -71,7 +71,8 @@ SOLVER_RULE_CHOICE = 0x700, SOLVER_RULE_LEARNT = 0x800, SOLVER_RULE_BEST = 0x900, - SOLVER_RULE_YUMOBS = 0xa00 + SOLVER_RULE_YUMOBS = 0xa00, + SOLVER_RULE_RECOMMENDS = 0xb00 } SolverRuleinfo; #define SOLVER_RULE_TYPEMASK 0xff00 @@ -133,6 +134,9 @@ /* yumobs rules */ extern void solver_addyumobsrules(struct s_Solver *solv); +/* recommends rules */ +extern void solver_addrecommendsrules(struct s_Solver *solv); + /* policy rule disabling/reenabling */ extern void solver_disablepolicyrules(struct s_Solver *solv); extern void solver_reenablepolicyrules(struct s_Solver *solv, int jobidx); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/solver.c new/libsolv-0.7.3/src/solver.c --- old/libsolv-0.7.2/src/solver.c 2018-12-10 15:09:56.000000000 +0100 +++ new/libsolv-0.7.3/src/solver.c 2018-12-20 17:35:49.000000000 +0100 @@ -845,18 +845,19 @@ disable_recommendsrules(Solver *solv, Queue *weakq) { Pool *pool = solv->pool; - int i; + int i, rid; for (i = 0; i < weakq->count; i++) { - Rule *r; - if (!queue_contains(solv->recommendsruleq, weakq->elements[i])) - continue; - r = solv->rules + weakq->elements[i]; - if (r->d >= 0) + rid = weakq->elements[i]; + if ((rid >= solv->recommendsrules && rid < solv->recommendsrules_end) || queue_contains(solv->recommendsruleq, rid)) { - POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling "); - solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, r); - solver_disablerule(solv, r); + Rule *r = solv->rules + rid; + if (r->d >= 0) + { + POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling "); + solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, r); + solver_disablerule(solv, r); + } } } } @@ -894,6 +895,41 @@ solver_recordproblem(solv, why); } +/* fix a problem by disabling one or more weak rules */ +static void +disable_weakrules(Solver *solv, Queue *weakq) +{ + Pool *pool = solv->pool; + int i; + Id lastweak = 0; + for (i = 0; i < weakq->count; i++) + if (weakq->elements[i] > lastweak) + lastweak = weakq->elements[i]; + if (lastweak >= solv->recommendsrules && lastweak < solv->recommendsrules_end) + { + lastweak = 0; + for (i = 0; i < weakq->count; i++) + if (weakq->elements[i] < solv->recommendsrules && weakq->elements[i] > lastweak) + lastweak = weakq->elements[i]; + if (lastweak < solv->pkgrules_end) + { + disable_recommendsrules(solv, weakq); + return; + } + } + if (lastweak < solv->pkgrules_end && solv->strongrecommends && solv->recommendsruleq && queue_contains(solv->recommendsruleq, lastweak)) + { + disable_recommendsrules(solv, weakq); + return; + } + POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling "); + solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + lastweak); + /* choice rules need special handling */ + if (lastweak >= solv->choicerules && lastweak < solv->choicerules_end) + solver_disablechoicerules(solv, solv->rules + lastweak); + else + solver_fixproblem(solv, lastweak); +} /*------------------------------------------------------------------- * @@ -924,7 +960,7 @@ Map rseen; Queue weakq; Id pp, v, vv, why; - int i, idx; + int idx; Id *decisionmap = solv->decisionmap; int oldproblemcount; int oldlearntpoolcount; @@ -981,28 +1017,12 @@ if (weakq.count) { - Id lastweak; /* revert problems */ solv->problems.count = oldproblemcount; solv->learnt_pool.count = oldlearntpoolcount; - /* find last weak */ - lastweak = 0; - for (i = 0; i < weakq.count; i++) - if (weakq.elements[i] > lastweak) - lastweak = weakq.elements[i]; - if (lastweak < solv->pkgrules_end && solv->strongrecommends && solv->recommendsruleq && queue_contains(solv->recommendsruleq, lastweak)) - { - disable_recommendsrules(solv, &weakq); - queue_free(&weakq); - solver_reset(solv); - return 0; - } + /* disable some weak rules */ + disable_weakrules(solv, &weakq); queue_free(&weakq); - POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling "); - solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + lastweak); - if (lastweak >= solv->choicerules && lastweak < solv->choicerules_end) - solver_disablechoicerules(solv, solv->rules + lastweak); - solver_fixproblem(solv, lastweak); solver_reset(solv); return 0; } @@ -1160,6 +1180,15 @@ /*------------------------------------------------------------------- * * branch handling + * + * format is: + * [ -p1 p2 p3 .. pn opt_pkg opt_data size level ] + * + * pkgs are negative if we tried them (to prevent inifinite recursion) + * opt_pkg: recommends: package with the recommends + * rule: 0 + * opt_data: recommends: depid + * rule: ruleid */ static void @@ -1378,9 +1407,10 @@ solv_free(solv->obsoletes); solv_free(solv->obsoletes_data); solv_free(solv->specialupdaters); - solv_free(solv->choicerules_ref); - solv_free(solv->bestrules_pkg); + solv_free(solv->choicerules_info); + solv_free(solv->bestrules_info); solv_free(solv->yumobsrules_info); + solv_free(solv->recommendsrules_info); solv_free(solv->instbuddy); solv_free(solv); } @@ -2345,7 +2375,7 @@ policy_filter_unwanted(solv, dq, POLICY_MODE_CHOOSE); /* if we have multiple candidates we open a branch */ if (dq->count > 1) - createbranch(solv, level, dq, s - pool->solvables, rec); + createbranch(solv, level, dq, s - pool->solvables, rec); p = dq->elements[0]; POOL_DEBUG(SOLV_DEBUG_POLICY, "installing recommended %s\n", pool_solvid2str(pool, p)); olevel = level; @@ -2452,6 +2482,7 @@ break; } *rerunp = 1; + return level; } } return level; @@ -2705,7 +2736,7 @@ if (lastsi >= 0) { /* we have a recommended package that could not be installed */ - /* take it if our current selection is not recommended */ + /* find current selection and take new one if it is not recommended */ for (i = starti; i < endi - 4; i++) { p = -solv->branches.elements[i]; @@ -3113,10 +3144,6 @@ for (; i < pool->nsolvables; i++) if (MAPTST(addedmap, i)) queue_push(&solv->addedmap_deduceq, i); - j = 0; - for (i = 2; i < pool->nsolvables; i++) - if (MAPTST(addedmap, i)) - j++; } static void @@ -3266,9 +3293,10 @@ queuep_free(&solv->update_targets); queuep_free(&solv->cleandeps_updatepkgs); queue_empty(&solv->ruleassertions); - solv->bestrules_pkg = solv_free(solv->bestrules_pkg); + solv->bestrules_info = solv_free(solv->bestrules_info); solv->yumobsrules_info = solv_free(solv->yumobsrules_info); - solv->choicerules_ref = solv_free(solv->choicerules_ref); + solv->recommendsrules_info = solv_free(solv->recommendsrules_info); + solv->choicerules_info = solv_free(solv->choicerules_info); if (solv->noupdate.size) map_empty(&solv->noupdate); map_zerosize(&solv->multiversion); @@ -3338,9 +3366,9 @@ */ initialnrules = solv->pkgrules_end ? solv->pkgrules_end : 1; if (initialnrules > 1) - deduceq2addedmap(solv, &addedmap); + deduceq2addedmap(solv, &addedmap); /* also enables all pkg rules */ if (solv->nrules != initialnrules) - solver_shrinkrules(solv, initialnrules); + solver_shrinkrules(solv, initialnrules); /* shrink to just pkg rules */ solv->lastpkgrule = 0; solv->pkgrules_end = 0; @@ -3892,16 +3920,16 @@ else solv->yumobsrules = solv->yumobsrules_end = solv->nrules; + if (solv->havedisfavored && solv->strongrecommends) + solver_addrecommendsrules(solv); + else + solv->recommendsrules = solv->recommendsrules_end = solv->nrules; + if (1) solver_addchoicerules(solv); else solv->choicerules = solv->choicerules_end = solv->nrules; - if (0) - { - for (i = solv->featurerules; i < solv->nrules; i++) - solver_printruleclass(solv, SOLV_DEBUG_RESULT, solv->rules + i); - } /* all rules created * -------------------------------------------------------------- * prepare for solving @@ -4761,6 +4789,8 @@ char buf[64]; if (solver_ruleclass(solv, id) == SOLVER_RULE_CHOICE) id = solver_rule2pkgrule(solv, id); + if (solver_ruleclass(solv, id) == SOLVER_RULE_RECOMMENDS) + id = solver_rule2pkgrule(solv, id); rtype = solver_ruleinfo(solv, id, &depfrom, &depto, &dep); if ((rtype & SOLVER_RULE_TYPEMASK) == SOLVER_RULE_JOB) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/solver.h new/libsolv-0.7.3/src/solver.h --- old/libsolv-0.7.2/src/solver.h 2018-12-10 15:09:56.000000000 +0100 +++ new/libsolv-0.7.3/src/solver.h 2018-12-19 14:30:15.000000000 +0100 @@ -70,7 +70,7 @@ Id bestrules; /* rules from SOLVER_FORCEBEST */ Id bestrules_up; /* update rule part starts here*/ Id bestrules_end; - Id *bestrules_pkg; + Id *bestrules_info; /* < 0 : install rule, > 0 : pkg that needs to be updated */ Id yumobsrules; /* rules from yum obsoletes handling */ Id yumobsrules_end; @@ -78,7 +78,11 @@ Id choicerules; /* choice rules (always weak) */ Id choicerules_end; - Id *choicerules_ref; + Id *choicerules_info; /* the rule we used to generate the choice rule */ + + Id recommendsrules; /* rules from recommends pkg rules with disfavored literals */ + Id recommendsrules_end; + Id *recommendsrules_info; /* the original pkg rule rule */ Id learntrules; /* learnt rules, (end == nrules) */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/src/solverdebug.c new/libsolv-0.7.3/src/solverdebug.c --- old/libsolv-0.7.2/src/solverdebug.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/src/solverdebug.c 2018-12-18 16:44:45.000000000 +0100 @@ -128,6 +128,8 @@ POOL_DEBUG(type, "FEATURE "); else if (p >= solv->yumobsrules && p < solv->yumobsrules_end) POOL_DEBUG(type, "YUMOBS "); + else if (p >= solv->recommendsrules && p < solv->recommendsrules_end) + POOL_DEBUG(type, "RECOMMENDS "); solver_printrule(solv, type, r); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/test/testcases/lockstep/infarch_install_best.t new/libsolv-0.7.3/test/testcases/lockstep/infarch_install_best.t --- old/libsolv-0.7.2/test/testcases/lockstep/infarch_install_best.t 1970-01-01 01:00:00.000000000 +0100 +++ new/libsolv-0.7.3/test/testcases/lockstep/infarch_install_best.t 2019-01-15 14:14:06.000000000 +0100 @@ -0,0 +1,20 @@ +# test for issue 292 +repo system 0 testtags <inline> +#>=Pkg: nss 3.39.0 2.fc29 x86_64 +#>=Pkg: nss-sysinit 3.39.0 2.fc29 x86_64 +#>=Req: nss = 3.39.0-2.fc29 +repo available 0 testtags <inline> +#>=Pkg: nss 3.39.0 2.fc29 i686 +#>=Pkg: nss 3.41.0 1.fc29 x86_64 +#>=Pkg: nss-sysinit 3.41.0 1.fc29 x86_64 +#>=Req: nss = 3.41.0-1.fc29 + +system x86_64 rpm system + +poolflags implicitobsoleteusescolors +solverflags allowvendorchange keepexplicitobsoletes bestobeypolicy keeporphans yumobsoletes + +job install oneof nss-3.41.0-1.fc29.x86_64@available [setevr,setarch] +result transaction,problems <inline> +#>upgrade nss-3.39.0-2.fc29.x86_64@system nss-3.41.0-1.fc29.x86_64@available +#>upgrade nss-sysinit-3.39.0-2.fc29.x86_64@system nss-sysinit-3.41.0-1.fc29.x86_64@available diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/test/testcases/strongrecommends/disfavored.t new/libsolv-0.7.3/test/testcases/strongrecommends/disfavored.t --- old/libsolv-0.7.2/test/testcases/strongrecommends/disfavored.t 1970-01-01 01:00:00.000000000 +0100 +++ new/libsolv-0.7.3/test/testcases/strongrecommends/disfavored.t 2018-12-18 17:00:05.000000000 +0100 @@ -0,0 +1,34 @@ +# test strong recommends +# +# with normal recommends, the solver will +# not backtrack to fulfill them. +# +repo system 0 testtags <inline> +#>=Pkg: A 1 1 noarch +#>=Con: C +#>=Pkg: A2 1 1 noarch +#>=Con: C2 +repo available 0 testtags <inline> +#>=Pkg: A 1 2 noarch +#>=Pkg: B 1 1 noarch +#>=Rec: C +#>=Pkg: C 1 1 noarch +#>=Pkg: B2 1 1 noarch +#>=Rec: C2 +#>=Pkg: C2 1 1 noarch +#>=Pkg: D 1 1 noarch +#>=Prv: C +#>=Pkg: E 1 1 noarch +#>=Prv: C +system i686 rpm system +solverflags strongrecommends +job install name B +job install name B2 +job disfavor name C +result transaction,problems,alternatives <inline> +#>alternative 6b91d100 1 + D-1-1.noarch@available +#>alternative 6b91d100 2 E-1-1.noarch@available +#>install B-1-1.noarch@available +#>install B2-1-1.noarch@available +#>install D-1-1.noarch@available +#>upgrade A-1-1.noarch@system A-1-2.noarch@available diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.2/tools/repo2solv.c new/libsolv-0.7.3/tools/repo2solv.c --- old/libsolv-0.7.2/tools/repo2solv.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.3/tools/repo2solv.c 2019-01-22 09:59:48.000000000 +0100 @@ -169,9 +169,9 @@ close(fds[1]); } if (recursive) - execl("/usr/bin/find", ".", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0); + execl("/usr/bin/find", "/usr/bin/find", ".", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0); else - execl("/usr/bin/find", ".", "-maxdepth", "1", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0); + execl("/usr/bin/find", "/usr/bin/find", ".", "-maxdepth", "1", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0); perror("/usr/bin/find"); _exit(1); } @@ -208,6 +208,7 @@ repodata_set_location(data, p, 0, 0, bp[0] == '.' && bp[1] == '/' ? bp + 2 : bp); solv_free(rpm); } + solv_free(buf); fclose(fp); while (waitpid(pid, &wstatus, 0) == -1) {
