Hello community, here is the log from the commit of package libsolv for openSUSE:Factory checked in at 2020-05-20 18:37:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libsolv (Old) and /work/SRC/openSUSE:Factory/.libsolv.new.2738 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libsolv" Wed May 20 18:37:11 2020 rev:78 rq:807025 version:0.7.13 Changes: -------- --- /work/SRC/openSUSE:Factory/libsolv/libsolv.changes 2020-01-27 00:21:54.821479413 +0100 +++ /work/SRC/openSUSE:Factory/.libsolv.new.2738/libsolv.changes 2020-05-20 18:37:16.420206983 +0200 @@ -1,0 +2,12 @@ +Fri Apr 24 12:00:30 CEST 2020 - [email protected] + +- Fix solvable swapping messing up idarrays +- bump version to 0.7.13 + +------------------------------------------------------------------- +Mon Apr 20 17:24:21 CEST 2020 - [email protected] + +- fix ruleinfo of complex dependencies returning the wrong origin +- bump version to 0.7.12 + +------------------------------------------------------------------- Old: ---- libsolv-0.7.11.tar.bz2 New: ---- libsolv-0.7.13.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libsolv.spec ++++++ --- /var/tmp/diff_new_pack.UfZ0aw/_old 2020-05-20 18:37:19.536213513 +0200 +++ /var/tmp/diff_new_pack.UfZ0aw/_new 2020-05-20 18:37:19.540213521 +0200 @@ -1,7 +1,7 @@ # # spec file for package libsolv # -# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -52,12 +52,12 @@ %bcond_with zypp Name: libsolv -Version: 0.7.11 +Version: 0.7.13 Release: 0 Summary: Package dependency solver using a satisfiability algorithm License: BSD-3-Clause Group: Development/Libraries/C and C++ -Url: https://github.com/openSUSE/libsolv +URL: https://github.com/openSUSE/libsolv Source: libsolv-%{version}.tar.bz2 BuildRequires: cmake BuildRequires: gcc-c++ ++++++ libsolv-0.7.11.tar.bz2 -> libsolv-0.7.13.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/CMakeLists.txt new/libsolv-0.7.13/CMakeLists.txt --- old/libsolv-0.7.11/CMakeLists.txt 2019-12-19 16:34:10.000000000 +0100 +++ new/libsolv-0.7.13/CMakeLists.txt 2020-04-20 17:19:12.000000000 +0200 @@ -58,6 +58,9 @@ SET (CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) INSTALL( FILES ${CMAKE_MODULE_PATH}/FindLibSolv.cmake DESTINATION ${CMAKE_INSTALL_PREFIX}/share/cmake/Modules ) +# for shared libraries on windows (DLLs), we just export all symbols for now +SET(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + INCLUDE (${CMAKE_SOURCE_DIR}/VERSION.cmake) SET (have_system x) @@ -431,9 +434,9 @@ ADD_SUBDIRECTORY (src) ADD_SUBDIRECTORY (ext) ADD_SUBDIRECTORY (tools) -IF (ENABLE_PERL OR ENABLE_PYTHON OR ENABLE_RUBY OR ENABLE_TCL) +IF (ENABLE_PERL OR ENABLE_PYTHON OR ENABLE_PYTHON3 OR ENABLE_RUBY OR ENABLE_TCL) ADD_SUBDIRECTORY (bindings) -ENDIF (ENABLE_PERL OR ENABLE_PYTHON OR ENABLE_RUBY OR ENABLE_TCL) +ENDIF (ENABLE_PERL OR ENABLE_PYTHON OR ENABLE_PYTHON3 OR ENABLE_RUBY OR ENABLE_TCL) ADD_SUBDIRECTORY (examples) ADD_SUBDIRECTORY (doc) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/NEWS new/libsolv-0.7.13/NEWS --- old/libsolv-0.7.11/NEWS 2020-01-22 13:59:13.000000000 +0100 +++ new/libsolv-0.7.13/NEWS 2020-04-24 12:05:38.000000000 +0200 @@ -2,6 +2,16 @@ This file contains the major changes between libsolv versions: +Version 0.7.13 +- fix solvable swapping messing up uninternalized idarrays + +Version 0.7.12 +- conda: support packages.conda repositories +- conda: de-priorize track features +- allow win32 to build shared lib +- selected bug fixes: + * fix ruleinfo of complex dependencies returning the wrong origin + Version 0.7.11 - ENABLE_RPMDB_LIBRPM is now the default - selected bug fixes: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/VERSION.cmake new/libsolv-0.7.13/VERSION.cmake --- old/libsolv-0.7.11/VERSION.cmake 2020-01-22 13:59:13.000000000 +0100 +++ new/libsolv-0.7.13/VERSION.cmake 2020-04-24 12:05:38.000000000 +0200 @@ -49,5 +49,5 @@ SET(LIBSOLV_MAJOR "0") SET(LIBSOLV_MINOR "7") -SET(LIBSOLV_PATCH "11") +SET(LIBSOLV_PATCH "13") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/ext/repo_conda.c new/libsolv-0.7.13/ext/repo_conda.c --- old/libsolv-0.7.11/ext/repo_conda.c 2019-11-14 14:20:15.000000000 +0100 +++ new/libsolv-0.7.13/ext/repo_conda.c 2020-04-24 12:00:43.000000000 +0200 @@ -22,6 +22,9 @@ Pool *pool; Repo *repo; Repodata *data; + + Stringpool fnpool; + Queue fndata; }; static int @@ -61,17 +64,91 @@ } static int +parse_trackfeatures_array(struct parsedata *pd, struct solv_jsonparser *jp, Id handle) +{ + int type = JP_ARRAY; + while (type > 0 && (type = jsonparser_parse(jp)) > 0 && type != JP_ARRAY_END) + { + if (type == JP_STRING) + { + char *p = jp->value, *pe; + while (*p == ' ' || *p == '\t') + p++; + if (!*p) + continue; + for (pe = p + strlen(p) - 1; pe > p; pe--) + if (*pe != ' ' && *pe != '\t') + break; + repodata_add_idarray(pd->data, handle, SOLVABLE_TRACK_FEATURES, pool_strn2id(pd->pool, p, pe - p + 1, 1)); + } + else + type = jsonparser_skip(jp, type); + } + return type; +} + +static void +parse_trackfeatures_string(struct parsedata *pd, const char *p, Id handle) +{ + const char *pe; + for (; *p; p++) + { + if (*p == ' ' || *p == '\t' || *p == ',') + continue; + pe = p + 1; + while (*pe && *pe != ' ' && *pe != '\t' && *pe != ',') + pe++; + repodata_add_idarray(pd->data, handle, SOLVABLE_TRACK_FEATURES, pool_strn2id(pd->pool, p, pe - p, 1)); + p = pe - 1; + } +} + +static void +swap_solvables(Pool *pool, Repodata *data, Id pa, Id pb) +{ + Solvable tmp; + + tmp = pool->solvables[pa]; + pool->solvables[pa] = pool->solvables[pb]; + pool->solvables[pb] = tmp; + repodata_swap_attrs(data, pa, pb); +} + +static Id * +fn2data(struct parsedata *pd, const char *fn, Id *fntypep, int create) +{ + size_t l = strlen(fn), extl = 0; + Id fnid; + if (l > 6 && !strcmp(fn + l - 6, ".conda")) + extl = 6; + else if (l > 8 && !strcmp(fn + l - 8, ".tar.bz2")) + extl = 8; + else + return 0; + fnid = stringpool_strn2id(&pd->fnpool, fn, l - extl, create); + if (!fnid) + return 0; + if (fnid * 2 + 2 > pd->fndata.count) + queue_insertn(&pd->fndata, pd->fndata.count, fnid * 2 + 2 - pd->fndata.count, 0); + if (fntypep) + *fntypep = extl == 8 ? 1 : 2; /* 1: legacy .tar.bz2 2: .conda */ + return pd->fndata.elements + 2 * fnid; +} + +static int parse_package(struct parsedata *pd, struct solv_jsonparser *jp, char *kfn) { int type = JP_OBJECT; Pool *pool= pd->pool; Repodata *data = pd->data; Solvable *s; - Id handle = repo_add_solvable(pd->repo); - s = pool_id2solvable(pool, handle); + Id handle; char *fn = 0; char *subdir = 0; + Id *fndata = 0, fntype = 0; + handle = repo_add_solvable(pd->repo); + s = pool_id2solvable(pool, handle); while (type > 0 && (type = jsonparser_parse(jp)) > 0 && type != JP_OBJECT_END) { if (type == JP_STRING && !strcmp(jp->key, "build")) @@ -107,17 +184,44 @@ ts /= 1000; repodata_set_num(data, handle, SOLVABLE_BUILDTIME, ts); } + else if (type == JP_STRING && !strcmp(jp->key, "track_features")) + parse_trackfeatures_string(pd, jp->value, handle); + else if (type == JP_ARRAY && !strcmp(jp->key, "track_features")) + type = parse_trackfeatures_array(pd, jp, handle); else type = jsonparser_skip(jp, type); } if (fn || kfn) - repodata_set_location(data, handle, 0, subdir, fn ? fn : kfn); + { + repodata_set_location(data, handle, 0, subdir, fn ? fn : kfn); + fndata = fn2data(pd, fn ? fn : kfn, &fntype, 1); + } solv_free(fn); solv_free(subdir); if (!s->evr) s->evr = 1; if (s->name) s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); + + if (fndata) + { + /* deal with legacy package entries */ + if (fndata[0] && fndata[0] > fntype) + { + /* ignore this package */ + repo_free_solvable(pd->repo, handle, 1); + return type; + } + if (fndata[0] && fndata[0] < fntype) + { + /* replace old package */ + swap_solvables(pool, data, handle, fndata[1]); + repo_free_solvable(pd->repo, handle, 1); + handle = fndata[1]; + } + fndata[0] = fntype; + fndata[1] = handle; + } return type; } @@ -161,7 +265,11 @@ { if (type == JP_OBJECT && !strcmp("packages", jp->key)) type = parse_packages(pd, jp); - if (type == JP_ARRAY && !strcmp("packages", jp->key)) + else if (type == JP_ARRAY && !strcmp("packages", jp->key)) + type = parse_packages2(pd, jp); + else if (type == JP_OBJECT && !strcmp("packages.conda", jp->key)) + type = parse_packages(pd, jp); + else if (type == JP_ARRAY && !strcmp("packages.conda", jp->key)) type = parse_packages2(pd, jp); else type = jsonparser_skip(jp, type); @@ -184,6 +292,8 @@ pd.pool = pool; pd.repo = repo; pd.data = data; + stringpool_init_empty(&pd.fnpool); + queue_init(&pd.fndata); jsonparser_init(&jp, fp); if ((type = jsonparser_parse(&jp)) != JP_OBJECT) @@ -192,6 +302,8 @@ ret = pool_error(pool, -1, "parse error line %d", jp.line); jsonparser_free(&jp); + queue_free(&pd.fndata); + stringpool_free(&pd.fnpool); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/ext/repo_updateinfoxml.c new/libsolv-0.7.13/ext/repo_updateinfoxml.c --- old/libsolv-0.7.11/ext/repo_updateinfoxml.c 2019-11-12 11:29:13.000000000 +0100 +++ new/libsolv-0.7.13/ext/repo_updateinfoxml.c 2020-04-20 17:34:14.000000000 +0200 @@ -524,7 +524,7 @@ Queue q; queue_init(&q); - for (p = 1; p < pool->nsolvables; p++) + FOR_REPO_SOLVABLES(repo, p, s) { const char *status; s = pool->solvables + p; @@ -578,7 +578,7 @@ else if (q.elements[i + 1] == retractedname && q.elements[i + 2] == retractedevr) { s = pool->solvables + q.elements[i]; - s->provides = repo_addid_dep(repo, s->provides, retractedmarker, 0); + s->provides = repo_addid_dep(s->repo, s->provides, retractedmarker, 0); } } queue_free(&q); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/ext/solv_ed25519.h new/libsolv-0.7.13/ext/solv_ed25519.h --- old/libsolv-0.7.11/ext/solv_ed25519.h 1970-01-01 01:00:00.000000000 +0100 +++ new/libsolv-0.7.13/ext/solv_ed25519.h 2020-05-18 18:24:10.000000000 +0200 @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2020, SUSE LLC. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +/* simple and slow ed25519 verification code. */ + +#ifndef LIBSOLV_CHKSUM_H +#include "chksum.h" +#endif + +#define MPED25519_LEN (32 / MP_T_BYTES) + +#if MP_T_BYTES == 4 +# define MPED25519_CONST1(x) (mp_t)x +#elif MP_T_BYTES == 1 +# define MPED25519_CONST1(x) (mp_t)(x >> 0), (mp_t)(x >> 8), (mp_t)(x >> 16), (mp_t)(x >> 24) +#endif + +#define MPED25519_CONST(a, b, c, d, e, f, g, h) { \ + MPED25519_CONST1(h), MPED25519_CONST1(g), MPED25519_CONST1(f), MPED25519_CONST1(e), \ + MPED25519_CONST1(d), MPED25519_CONST1(c), MPED25519_CONST1(b), MPED25519_CONST1(a) \ +} + +static mp_t ed25519_q[] = /* mod prime */ + MPED25519_CONST(0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFED); +static mp_t ed25519_d[] = /* -(121665/121666) */ + MPED25519_CONST(0x52036CEE, 0x2B6FFE73, 0x8CC74079, 0x7779E898, 0x00700A4D, 0x4141D8AB, 0x75EB4DCA, 0x135978A3); +static mp_t ed25519_p58[] = /* (q-5)/8 */ + MPED25519_CONST(0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD); +static mp_t ed25519_sqrtm1[] = /* sqrt(-1) */ + MPED25519_CONST(0x2B832480, 0x4FC1DF0B, 0x2B4D0099, 0x3DFBD7A7, 0x2F431806, 0xAD2FE478, 0xC4EE1B27, 0x4A0EA0B0); +static mp_t ed25519_n[] = /* l */ + MPED25519_CONST(0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x14DEF9DE, 0xA2F79CD6, 0x5812631A, 0x5CF5D3ED); +static mp_t ed25519_gx[] = /* base point */ + MPED25519_CONST(0x216936D3, 0xCD6E53FE, 0xC0A4E231, 0xFDD6DC5C, 0x692CC760, 0x9525A7B2, 0xC9562D60, 0x8F25D51A); +static mp_t ed25519_gy[] = /* base point */ + MPED25519_CONST(0x66666666, 0x66666666, 0x66666666, 0x66666666, 0x66666666, 0x66666666, 0x66666666, 0x66666658); +static mp_t ed25519_one[] = /* 1 */ + MPED25519_CONST(0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001); +static mp_t ed25519_qm2[] = /* mod - 2 */ + MPED25519_CONST(0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFEB); + +/* small helpers to save some typing */ +static inline void +mped25519_add(mp_t *target, mp_t *m1, mp_t *m2) +{ + mpadd(MPED25519_LEN, target, m1, m2, ed25519_q); +} + +static inline void +mped25519_sub(mp_t *target, mp_t *m1, mp_t *m2) +{ + mpsub(MPED25519_LEN, target, m1, m2, ed25519_q); +} + +static void +mped25519_mul(mp_t *target, mp_t *m1, mp_t *m2) +{ + mp_t tmp[MPED25519_LEN * 2]; + int i, j; + mp2_t x; + + mpzero(MPED25519_LEN * 2, tmp); + for (i = 0; i < MPED25519_LEN; i++) + { + for (x = 0, j = 0; j < MPED25519_LEN; j++) + { + x += (mp2_t)tmp[i + j] + (mp2_t)m1[i] * m2[j]; + tmp[i + j] = x; + x >>= MP_T_BITS; + } + tmp[i + j] = x; + } + for (x = 0, i = 0; i < MPED25519_LEN; i++) + { + x += (mp2_t)tmp[i] + (mp2_t)tmp[i + MPED25519_LEN] * 38; + tmp[i] = x; + x >>= MP_T_BITS; + } + x *= 38; + if ((tmp[MPED25519_LEN - 1] & (1 << (MP_T_BITS - 1))) != 0) + { + x += 19; + tmp[MPED25519_LEN - 1] -= 1 << (MP_T_BITS - 1); + } + for (i = 0; x && i < MPED25519_LEN; i++) + { + x += (mp2_t)tmp[i]; + tmp[i] = x; + x >>= MP_T_BITS; + } + if (tmp[MPED25519_LEN - 1] >= ed25519_q[MPED25519_LEN - 1]) + mpsubmod(MPED25519_LEN, tmp, ed25519_q); + mpcpy(MPED25519_LEN, target, tmp); +} + +static inline void +mped25519_inv(mp_t *target, mp_t *a) +{ + mppow(MPED25519_LEN, target, a, MPED25519_LEN, ed25519_qm2, ed25519_q); +} + +/* recover x coordinate from y and sign */ +static int +mped25519_recover_x(mp_t *x, mp_t *y, int sign) +{ + mp_t num[MPED25519_LEN], den[MPED25519_LEN]; + mp_t tmp1[MPED25519_LEN], tmp2[MPED25519_LEN]; + + if (!mpisless(MPED25519_LEN, y, ed25519_q)) + return 0; + /* calculate num=y^2-1 and den=dy^2+1 */ + mped25519_mul(num, y, y); + mped25519_mul(den, num, ed25519_d); + mped25519_sub(num, num, ed25519_one); + mped25519_add(den, den, ed25519_one); + + /* calculate x = num*den^3 * (num*den^7)^p58 */ + mped25519_mul(tmp1, den, den); /* tmp1 = den^2 */ + mped25519_mul(tmp2, tmp1, den); /* tmp2 = den^3 */ + mped25519_mul(tmp1, tmp2, tmp2); /* tmp1 = den^6 */ + mped25519_mul(x, tmp1, den); /* x = den^7 */ + mped25519_mul(tmp1, x, num); /* tmp1 = num * den^7 */ + mppow(MPED25519_LEN, x, tmp1, MPED25519_LEN, ed25519_p58, ed25519_q); /* x = tmp1 ^ p58 */ + mped25519_mul(tmp1, x, tmp2); /* tmp1 = x * den^3 */ + mped25519_mul(x, tmp1, num); /* x = tmp1 * num */ + + /* check if den*x^2 == num */ + mped25519_mul(tmp2, x, x); + mped25519_mul(tmp1, tmp2, den); + if (!mpisequal(MPED25519_LEN, tmp1, num)) { + mped25519_mul(tmp1, x, ed25519_sqrtm1); /* x = x * sqrt(-1) */ + mpcpy(MPED25519_LEN, x, tmp1); + mped25519_mul(tmp2, x, x); + mped25519_mul(tmp1, tmp2, den); + if (!mpisequal(MPED25519_LEN, tmp1, num)) + return 0; + } + if (mpiszero(MPED25519_LEN, x)) + return 0; /* (0,1) is bad */ + if ((x[0] & 1) != sign) + mped25519_sub(x, ed25519_q, x); + return 1; +} + +static void +mped25519_setfromle(int len, mp_t *out, const unsigned char *buf, int bufl, int highmask) +{ + unsigned char lebuf[64]; /* bufl must be <= 64 */ + int i; + for (i = 0; i < bufl; i++) + lebuf[bufl - 1 - i] = buf[i]; + lebuf[0] &= highmask; + mpsetfrombe(len, out, lebuf, bufl); +} + +static void +mped25519_modn_fromle(mp_t *out, const unsigned char *buf, int bufl) +{ + mp_t tmp[64 / MP_T_BYTES]; /* bufl must be <= 64 */ + mp_t tmp2[MPED25519_LEN]; + int len = (bufl + MP_T_BYTES - 1) / MP_T_BYTES; + mped25519_setfromle(len, tmp, buf, bufl, 0xff); + mpzero(MPED25519_LEN, out); + mpmul_add(MPED25519_LEN, out, ed25519_one, len, tmp, tmp2, ed25519_n); +} + +/* see https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html */ +/* M=7 add=6 */ +static void +mped25519_ptdouble(mp_t *p_x, mp_t *p_y, mp_t *p_z) +{ + mp_t B[MPED25519_LEN], C[MPED25519_LEN], D[MPED25519_LEN]; + mp_t F[MPED25519_LEN], H[MPED25519_LEN], J[MPED25519_LEN]; + + mped25519_add(C, p_x, p_y); + mped25519_mul(B, C, C); + mped25519_mul(C, p_x, p_x); + mped25519_mul(D, p_y, p_y); + mped25519_sub(F, C, D); + mped25519_mul(H, p_z, p_z); + mped25519_add(H, H, H); + mped25519_add(J, F, H); + mped25519_add(H, C, D); + mped25519_mul(p_y, H, F); + mped25519_mul(p_z, J, F); + mped25519_sub(H, H, B); + mped25519_mul(p_x, J, H); +} + +/* M=12 add=7 */ +static void +mped25519_ptadd(mp_t *p_x, mp_t *p_y, mp_t *p_z, mp_t *q_x, mp_t *q_y, mp_t *q_z) +{ + mp_t A[MPED25519_LEN], B[MPED25519_LEN], C[MPED25519_LEN]; + mp_t D[MPED25519_LEN], E[MPED25519_LEN], F[MPED25519_LEN]; + mp_t G[MPED25519_LEN], H[MPED25519_LEN], J[MPED25519_LEN]; + + mped25519_mul(A, p_z, q_z); + mped25519_mul(B, A, A); + mped25519_mul(C, p_x, q_x); + mped25519_mul(D, p_y, q_y); + mped25519_mul(F, ed25519_d, C); + mped25519_mul(E, F, D); + mped25519_sub(F, B, E); + mped25519_add(G, B, E); + mped25519_add(H, p_x, p_y); + mped25519_add(J, q_x, q_y); + mped25519_mul(p_x, H, J); + mped25519_sub(p_x, p_x, C); + mped25519_sub(p_x, p_x, D); + mped25519_mul(H, p_x, F); + mped25519_mul(p_x, H, A); + mped25519_add(H, D, C); + mped25519_mul(J, H, G); + mped25519_mul(p_y, J, A); + mped25519_mul(p_z, F, G); +} + +static inline void +mped25519_ptcpy(mp_t *p_x, mp_t *p_y, mp_t *p_z, mp_t *q_x, mp_t *q_y, mp_t *q_z) +{ + mpcpy(MPED25519_LEN, p_x, q_x); + mpcpy(MPED25519_LEN, p_y, q_y); + mpcpy(MPED25519_LEN, p_z, q_z); +} + +#if 0 +static void +mped25519_mpdump(mp_t *p, char *s, int c) +{ + if (c) + fprintf(stderr, "%c.", c); + mpdump(MPED25519_LEN, p, s); +} + +static void +mped25519_ptdump(mp_t *p_x, mp_t *p_y, mp_t *p_z, char *s) +{ + if (p_z) + { + mp_t zi[MPED25519_LEN], px[MPED25519_LEN], py[MPED25519_LEN]; + mped25519_mpdump(p_x, s, 'X'); + mped25519_mpdump(p_y, s, 'Y'); + mped25519_mpdump(p_z, s, 'Z'); + mped25519_inv(zi, p_z); + mped25519_mul(px, p_x, zi); + mped25519_mul(py, p_y, zi); + p_x = px; + p_y = py; + } + mped25519_mpdump(p_x, s, 'x'); + mped25519_mpdump(p_y, s, 'y'); +} +#endif + + +/* scalar multiplication and add: r = s1*p1 + s2*p2 */ +/* needs about 13 + (256 - 32) / 2 = 125 point additions */ +static int +mped25519_scmult2(mp_t *r_x, mp_t *r_y, mp_t *s1, mp_t *p1_x, mp_t * p1_y, mp_t *s2, mp_t *p2_x, mp_t * p2_y) +{ + mp_t p_x[MPED25519_LEN], p_y[MPED25519_LEN], p_z[MPED25519_LEN]; + mp_t pi_z[MPED25519_LEN]; + mp_t tabx[16][MPED25519_LEN]; + mp_t taby[16][MPED25519_LEN]; + mp_t tabz[16][MPED25519_LEN]; + int i, x, dodouble = 0; + + mpzero(MPED25519_LEN, p_x); + mpzero(MPED25519_LEN, p_y); + mpzero(MPED25519_LEN, p_z); + p_y[0] = p_z[0] = 1; + + /* setup table: tab[i * 4 + j] = i * p1 + j * p2 */ + mped25519_ptcpy(tabx[0], taby[0], tabz[0], p_x, p_y, p_z); + for (i = 4; i < 16; i += 4) + mped25519_ptcpy(tabx[i], taby[i], tabz[i], p1_x, p1_y, ed25519_one); + mped25519_ptdouble(tabx[8], taby[8], tabz[8]); + mped25519_ptadd(tabx[12], taby[12], tabz[12], tabx[8], taby[8], tabz[8]); + mped25519_ptcpy(tabx[1], taby[1], tabz[1], p2_x, p2_y, ed25519_one); + for (i = 2; i < 16; i++) + { + if ((i & 3) == 0) + continue; + mped25519_ptcpy(tabx[i], taby[i], tabz[i], tabx[i - 1], taby[i - 1], tabz[i - 1]); + mped25519_ptadd(tabx[i], taby[i], tabz[i], p2_x, p2_y, ed25519_one); + } + /* now do the scalar multiplication */ + for (i = 255; i >= 0; i--) + { + if (dodouble) + mped25519_ptdouble(p_x, p_y, p_z); + x = s1[i / MP_T_BITS] & (1 << (i % MP_T_BITS)) ? 4 : 0; + x |= s2[i / MP_T_BITS] & (1 << (i % MP_T_BITS)) ? 1 : 0; + if (!x) + continue; + if (i > 0) + { + i--; + x <<= 1; + mped25519_ptdouble(p_x, p_y, p_z); + x |= s1[i / MP_T_BITS] & (1 << (i % MP_T_BITS)) ? 4 : 0; + x |= s2[i / MP_T_BITS] & (1 << (i % MP_T_BITS)) ? 1 : 0; + } + mped25519_ptadd(p_x, p_y, p_z, tabx[x], taby[x], tabz[x]); + dodouble = 1; + } +#if 0 + mped25519_ptdump(p_x, p_y, p_z, "r = "); +#endif + mped25519_inv(pi_z, p_z); + mped25519_mul(r_x, p_x, pi_z); + mped25519_mul(r_y, p_y, pi_z); + return mpiszero(MPED25519_LEN, p_z) ? 0 : 1; +} + +static int +mped25519(const unsigned char *pub, const unsigned char *sigr, const unsigned char *sigs, const unsigned char *data, unsigned int datal) +{ + unsigned char hbuf[64], rbuf[32]; + int i; + mp_t pub_x[MPED25519_LEN], pub_y[MPED25519_LEN]; + mp_t h[MPED25519_LEN], s[MPED25519_LEN]; + mp_t r_x[MPED25519_LEN], r_y[MPED25519_LEN]; + Chksum *chk; + + if ((sigs[31] & 0xe0) != 0) + return 0; + /* uncompress pubkey, we invert the sign to get -pub */ + mped25519_setfromle(MPED25519_LEN, pub_y, pub, 32, 0x7f); + if (!mped25519_recover_x(pub_x, pub_y, pub[31] & 0x80 ? 0 : 1)) + return 0; /* bad pubkey */ +#if 0 + mped25519_ptdump(pub_x, pub_y, 0, "pub = "); +#endif + /* calculate h and s */ + chk = solv_chksum_create(REPOKEY_TYPE_SHA512); + if (!chk) + return 0; + solv_chksum_add(chk, sigr, 32); + solv_chksum_add(chk, pub, 32); + solv_chksum_add(chk, data, datal); + solv_chksum_free(chk, hbuf); + mped25519_modn_fromle(h, hbuf, 64); + mped25519_modn_fromle(s, sigs, 32); +#if 0 + mped25519_mpdump(s, "s = ", 0); + mped25519_mpdump(h, "h = ", 0); +#endif + /* calculate r = s * G - h * pub */ + if (!mped25519_scmult2(r_x, r_y, s, ed25519_gx, ed25519_gy, h, pub_x, pub_y)) + return 0; + /* compress r into rbuf and verify that it matches sigr */ + for (i = 0; i < 32; i++) + rbuf[i] = r_y[i / MP_T_BYTES] >> (8 * (i % MP_T_BYTES)); + if ((r_x[0] & 1) != 0) + rbuf[31] |= 0x80; + return memcmp(sigr, rbuf, 32) == 0 ? 1 : 0; +} + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/ext/solv_pgpvrfy.c new/libsolv-0.7.13/ext/solv_pgpvrfy.c --- old/libsolv-0.7.11/ext/solv_pgpvrfy.c 2018-10-01 11:09:18.000000000 +0200 +++ new/libsolv-0.7.13/ext/solv_pgpvrfy.c 2020-05-18 18:24:10.000000000 +0200 @@ -1,11 +1,11 @@ /* - * Copyright (c) 2013, SUSE Inc. + * Copyright (c) 2013-2020, SUSE LLC. * * This program is licensed under the BSD license, read LICENSE.BSD * for further information */ -/* simple and slow rsa/dsa verification code. */ +/* simple and slow pgp signature verification code. */ #include <stdio.h> #include <stdlib.h> @@ -14,6 +14,10 @@ #include "util.h" #include "solv_pgpvrfy.h" +#ifndef ENABLE_PGPVRFY_ED25519 +#define ENABLE_PGPVRFY_ED25519 1 +#endif + typedef unsigned int mp_t; typedef unsigned long long mp2_t; #define MP_T_BYTES 4 @@ -38,6 +42,19 @@ memcpy(target, source, len * MP_T_BYTES); } +static void +mpsetfrombe(int len, mp_t *target, const unsigned char *buf, int bufl) +{ + int i, mpl = len * MP_T_BYTES; + buf += bufl; + if (bufl >= mpl) + bufl = mpl; + if (mpl) + memset(target, 0, mpl); + for (i = 0; bufl > 0; bufl--, i++) + target[i / MP_T_BYTES] |= (int)(*--buf) << (8 * (i % MP_T_BYTES)); +} + #if 0 static void mpdump(int l, mp_t *a, char *s) { @@ -50,6 +67,30 @@ } #endif +/* subtract mod if target >= mod */ +static inline void mpsubmod(int len, mp_t *target, mp_t *mod) +{ + int i; + mp2_t n; + if (target[len - 1] < mod[len - 1]) + return; + if (target[len - 1] == mod[len - 1]) + { + for (i = len - 2; i >= 0; i--) + if (target[i] < mod[i]) + return; + else if (target[i] > mod[i]) + break; + } + /* target >= mod, subtract mod */ + for (n = 0, i = 0; i < len; i++) + { + mp2_t n2 = (mp2_t)mod[i] + n; + n = n2 > target[i] ? 1 : 0; + target[i] -= (mp_t)n2; + } +} + /* target[len] = x, target = target % mod * assumes that target < (mod << MP_T_BITS)! */ static void @@ -87,30 +128,12 @@ } target[i] = x; if (x >= mod[i]) - { - mp_t n; - if (x == mod[i]) - { - for (j = i - 1; j >= 0; j--) - if (target[j] < mod[j]) - return; - else if (target[j] > mod[j]) - break; - } - /* target >= mod, subtract mod */ - n = 0; - for (j = 0; j <= i; j++) - { - mp2_t n2 = mod[j] + n; - n = n2 > target[j] ? 1 : 0; - target[j] -= (mp_t)n2; - } - } + mpsubmod(i + 1, target, mod); } /* target += src * m */ static void -mpmult_add_int(int len, mp_t *target, mp_t *src, mp2_t m, mp_t *mod) +mpmul_add_int(int len, mp_t *target, mp_t *src, mp2_t m, mp_t *mod) { int i; mp2_t x = 0; @@ -139,7 +162,7 @@ /* target += m1 * m2 */ static void -mpmult_add(int len, mp_t *target, mp_t *m1, int m2len, mp_t *m2, mp_t *tmp, mp_t *mod) +mpmul_add(int len, mp_t *target, mp_t *m1, int m2len, mp_t *m2, mp_t *tmp, mp_t *mod) { int i, j; for (j = m2len - 1; j >= 0; j--) @@ -151,19 +174,19 @@ for (i = 0; i < j; i++) { if (m2[i]) - mpmult_add_int(len, target, tmp, m2[i], mod); + mpmul_add_int(len, target, tmp, m2[i], mod); mpshift(len, tmp, mod); } if (m2[i]) - mpmult_add_int(len, target, tmp, m2[i], mod); + mpmul_add_int(len, target, tmp, m2[i], mod); } /* target = target * m */ static void -mpmult_inplace(int len, mp_t *target, mp_t *m, mp_t *tmp1, mp_t *tmp2, mp_t *mod) +mpmul_inplace(int len, mp_t *target, mp_t *m, mp_t *tmp1, mp_t *tmp2, mp_t *mod) { mpzero(len, tmp1); - mpmult_add(len, tmp1, target, len, m, tmp2, mod); + mpmul_add(len, tmp1, target, len, m, tmp2, mod); mpcpy(len, target, tmp1); } @@ -172,12 +195,12 @@ mppow_int(int len, mp_t *target, mp_t *t, mp_t *mod, int e) { mp_t *t2 = t + len * 16; - mpmult_inplace(len, target, target, t, t2, mod); - mpmult_inplace(len, target, target, t, t2, mod); - mpmult_inplace(len, target, target, t, t2, mod); - mpmult_inplace(len, target, target, t, t2, mod); + mpmul_inplace(len, target, target, t, t2, mod); + mpmul_inplace(len, target, target, t, t2, mod); + mpmul_inplace(len, target, target, t, t2, mod); + mpmul_inplace(len, target, target, t, t2, mod); if (e) - mpmult_inplace(len, target, t + len * e, t, t2, mod); + mpmul_inplace(len, target, t + len * e, t, t2, mod); } /* target = b ^ e (b has to be < mod) */ @@ -196,7 +219,7 @@ t = mpnew(len * 17); mpcpy(len, t + len, b); for (j = 2; j < 16; j++) - mpmult_add(len, t + len * j, b, len, t + len * j - len, t + len * 16, mod); + mpmul_add(len, t + len * j, b, len, t + len * j - len, t + len * 16, mod); for (; i >= 0; i--) { #if MP_T_BYTES == 4 @@ -218,11 +241,11 @@ /* target = m1 * m2 (m1 has to be < mod) */ static void -mpmult(int len, mp_t *target, mp_t *m1, int m2len, mp_t *m2, mp_t *mod) +mpmul(int len, mp_t *target, mp_t *m1, int m2len, mp_t *m2, mp_t *mod) { mp_t *tmp = mpnew(len); mpzero(len, target); - mpmult_add(len, target, m1, m2len, m2, tmp, mod); + mpmul_add(len, target, m1, m2len, m2, tmp, mod); free(tmp); } @@ -239,6 +262,12 @@ } static int +mpisequal(int len, mp_t *a, mp_t *b) +{ + return memcmp(a, b, len * MP_T_BYTES) == 0; +} + +static int mpiszero(int len, mp_t *a) { int i; @@ -255,10 +284,57 @@ for (i = 0; i < len; i++) if (a[i]--) return; - else - a[i] = -(mp_t)1; } +#if ENABLE_PGPVRFY_ED25519 +/* target = m1 + m2 (m1, m2 < mod). target may be m1 or m2 */ +static void +mpadd(int len, mp_t *target, mp_t *m1, mp_t *m2, mp_t *mod) +{ + int i; + mp2_t x = 0; + for (i = 0; i < len; i++) + { + x += (mp2_t)m1[i] + m2[i]; + target[i] = x; + x >>= MP_T_BITS; + } + if (x || !mpisless(len, target, mod)) + { + for (x = 0, i = 0; i < len; i++) + { + x = (mp2_t)target[i] - mod[i] - x; + target[i] = x; + x = x & ((mp2_t)1 << MP_T_BITS) ? 1 : 0; + } + } +} + +/* target = m1 - m2 (m1, m2 < mod). target may be m1 or m2 */ +static void +mpsub(int len, mp_t *target, mp_t *m1, mp_t *m2, mp_t *mod) +{ + int i; + mp2_t x = 0; + for (i = 0; i < len; i++) + { + x = (mp2_t)m1[i] - m2[i] - x; + target[i] = x; + x = x & ((mp2_t)1 << MP_T_BITS) ? 1 : 0; + } + if (x) + { + for (x = 0, i = 0; i < len; i++) + { + x += (mp2_t)target[i] + mod[i]; + target[i] = x; + x >>= MP_T_BITS; + } + } +} +#endif + + static int mpdsa(int pl, mp_t *p, int ql, mp_t *q, mp_t *g, mp_t *y, mp_t *r, mp_t *s, int hl, mp_t *h) { @@ -289,26 +365,26 @@ mppow(ql, w, s, ql, tmp, q); /* w = s ^ tmp (s ^ -1) */ u1 = mpnew(pl); /* note pl */ /* order is important here: h can be >= q */ - mpmult(ql, u1, w, hl, h, q); /* u1 = w * h */ + mpmul(ql, u1, w, hl, h, q); /* u1 = w * h */ u2 = mpnew(ql); /* u2 = 0 */ - mpmult(ql, u2, w, ql, r, q); /* u2 = w * r */ + mpmul(ql, u2, w, ql, r, q); /* u2 = w * r */ free(w); gu1 = mpnew(pl); yu2 = mpnew(pl); mppow(pl, gu1, g, ql, u1, p); /* gu1 = g ^ u1 */ mppow(pl, yu2, y, ql, u2, p); /* yu2 = y ^ u2 */ - mpmult(pl, u1, gu1, pl, yu2, p); /* u1 = gu1 * yu2 */ + mpmul(pl, u1, gu1, pl, yu2, p); /* u1 = gu1 * yu2 */ free(gu1); free(yu2); mpzero(ql, u2); u2[0] = 1; /* u2 = 1 */ - mpmult(ql, tmp, u2, pl, u1, q); /* tmp = u2 * u1 */ + mpmul(ql, tmp, u2, pl, u1, q); /* tmp = u2 * u1 */ free(u1); free(u2); #if 0 mpdump(ql, tmp, "res = "); #endif - if (memcmp(tmp, r, ql * MP_T_BYTES) != 0) + if (!mpisequal(ql, tmp, r)) { free(tmp); return 0; @@ -336,7 +412,7 @@ #if 0 mpdump(nl, tmp, "res = "); #endif - if (memcmp(tmp, c, nl * MP_T_BYTES) != 0) + if (!mpisequal(nl, tmp, c)) { free(tmp); return 0; @@ -345,25 +421,19 @@ return 1; } +#if ENABLE_PGPVRFY_ED25519 +# include "solv_ed25519.h" +#endif + /* create mp with size tbits from data with size dbits */ static mp_t * mpbuild(const unsigned char *d, int dbits, int tbits, int *mplp) { int l = (tbits + MP_T_BITS - 1) / MP_T_BITS; - int dl, i; - mp_t *out = mpnew(l ? l : 1); if (mplp) *mplp = l; - dl = (dbits + 7) / 8; - d += dl; - if (dbits > tbits) - dl = (tbits + 7) / 8; - for (i = 0; dl > 0; dl--, i++) - { - int x = *--d; - out[i / MP_T_BYTES] |= x << (8 * (i % MP_T_BYTES)); - } + mpsetfrombe(l, out, d, (dbits + 7) / 8); return out; } @@ -390,6 +460,8 @@ return mpi + 2; } +/* sig: 0:algo 1:hash 2-:mpidata */ +/* pub: 0:algo 1-:mpidata */ int solv_pgpvrfy(const unsigned char *pub, int publ, const unsigned char *sig, int sigl) { @@ -515,6 +587,36 @@ free(hx); break; } +#if ENABLE_PGPVRFY_ED25519 + case 22: /* EdDSA */ + { + unsigned char sigdata[64]; + const unsigned char *r, *s; + int rlen, slen; + + /* check the curve */ + if (publ < 11 || memcmp(pub + 1, "\011\053\006\001\004\001\332\107\017\001", 10) != 0) + return 0; /* we only support the Ed25519 curve */ + /* the pubkey always has 7 + 256 bits */ + if (publ != 1 + 10 + 2 + 1 + 32 || pub[1 + 10 + 0] != 1 || pub[1 + 10 + 1] != 7 || pub[1 + 10 + 2] != 0x40) + return 0; + mpi = sig + 2 + hashl; + mpil = sigl - (2 + hashl); + r = findmpi(&mpi, &mpil, 256, &rlen); + s = findmpi(&mpi, &mpil, 256, &slen); + if (!r || !s) + return 0; + memset(sigdata, 0, 64); + rlen = (rlen + 7) / 8; + slen = (slen + 7) / 8; + if (rlen) + memcpy(sigdata + 32 - rlen, r, rlen); + if (slen) + memcpy(sigdata + 64 - slen, s, rlen); + res = mped25519(pub + 1 + 10 + 2 + 1, sigdata, sigdata + 32, sig + 2, hashl); + break; + } +#endif default: return 0; /* unsupported pubkey algo */ } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/ext/solv_xfopen.c new/libsolv-0.7.13/ext/solv_xfopen.c --- old/libsolv-0.7.11/ext/solv_xfopen.c 2019-04-11 16:48:29.000000000 +0200 +++ new/libsolv-0.7.13/ext/solv_xfopen.c 2020-04-17 18:24:14.000000000 +0200 @@ -61,7 +61,15 @@ static ssize_t cookie_gzread(void *cookie, char *buf, size_t nbytes) { - return gzread((gzFile)cookie, buf, nbytes); + ssize_t r = gzread((gzFile)cookie, buf, nbytes); + if (r == 0) + { + int err = 0; + gzerror((gzFile)cookie, &err); + if (err == Z_BUF_ERROR) + r = -1; + } + return r; } static ssize_t cookie_gzwrite(void *cookie, const char *buf, size_t nbytes) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/package/libsolv.changes new/libsolv-0.7.13/package/libsolv.changes --- old/libsolv-0.7.11/package/libsolv.changes 2020-01-22 13:59:13.000000000 +0100 +++ new/libsolv-0.7.13/package/libsolv.changes 2020-04-24 12:05:38.000000000 +0200 @@ -1,4 +1,16 @@ ------------------------------------------------------------------- +Fri Apr 24 12:00:30 CEST 2020 - [email protected] + +- Fix solvable swapping messing up idarrays +- bump version to 0.7.13 + +------------------------------------------------------------------- +Mon Apr 20 17:24:21 CEST 2020 - [email protected] + +- fix ruleinfo of complex dependencies returning the wrong origin +- bump version to 0.7.12 + +------------------------------------------------------------------- Wed Jan 22 13:52:48 CET 2020 - [email protected] - fixed solv_zchunk decoding error if large chunks are used diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/CMakeLists.txt new/libsolv-0.7.13/src/CMakeLists.txt --- old/libsolv-0.7.11/src/CMakeLists.txt 2019-07-01 11:34:26.000000000 +0200 +++ new/libsolv-0.7.13/src/CMakeLists.txt 2020-04-20 17:24:09.000000000 +0200 @@ -48,11 +48,19 @@ ENDIF (HAVE_LINKER_VERSION_SCRIPT) IF (DISABLE_SHARED) -ADD_LIBRARY (libsolv STATIC ${libsolv_SRCS}) + ADD_LIBRARY (libsolv STATIC ${libsolv_SRCS}) ELSE (DISABLE_SHARED) -ADD_LIBRARY (libsolv SHARED ${libsolv_SRCS}) + ADD_LIBRARY (libsolv SHARED ${libsolv_SRCS}) ENDIF (DISABLE_SHARED) +IF (WIN32) + IF (DISABLE_SHARED) + TARGET_COMPILE_DEFINITIONS(libsolv PUBLIC SOLV_STATIC_LIB) + ELSE (DISABLE_SHARED) + TARGET_COMPILE_DEFINITIONS(libsolv PRIVATE SOLV_EXPORTS) + ENDIF (DISABLE_SHARED) +ENDIF (WIN32) + SET_TARGET_PROPERTIES(libsolv PROPERTIES OUTPUT_NAME "solv") SET_TARGET_PROPERTIES(libsolv PROPERTIES SOVERSION ${LIBSOLV_SOVERSION}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/knownid.h new/libsolv-0.7.13/src/knownid.h --- old/libsolv-0.7.11/src/knownid.h 2019-11-14 14:20:15.000000000 +0100 +++ new/libsolv-0.7.13/src/knownid.h 2020-04-16 23:34:15.000000000 +0200 @@ -266,6 +266,7 @@ KNOWNID(LIBSOLV_SELF_DESTRUCT_PKG, "libsolv-self-destruct-pkg()"), /* this package will self-destruct on installation */ KNOWNID(SOLVABLE_CONSTRAINS, "solvable:constrains"), /* conda */ +KNOWNID(SOLVABLE_TRACK_FEATURES, "solvable:track_features"), /* conda */ KNOWNID(ID_NUM_INTERNAL, 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/policy.c new/libsolv-0.7.13/src/policy.c --- old/libsolv-0.7.11/src/policy.c 2019-09-30 14:39:28.000000000 +0200 +++ new/libsolv-0.7.13/src/policy.c 2020-04-17 17:39:21.000000000 +0200 @@ -836,8 +836,14 @@ static int pool_buildversioncmp(Pool *pool, Solvable *s1, Solvable *s2) { - const char *bv1 = solvable_lookup_str(s1, SOLVABLE_BUILDVERSION); - const char *bv2 = solvable_lookup_str(s2, SOLVABLE_BUILDVERSION); + const char *bv1, *bv2; + unsigned int cnt1, cnt2; + cnt1 = solvable_lookup_count(s1, SOLVABLE_TRACK_FEATURES); + cnt2 = solvable_lookup_count(s2, SOLVABLE_TRACK_FEATURES); + if (cnt1 != cnt2) + return cnt1 > cnt2 ? -1 : 1; + bv1 = solvable_lookup_str(s1, SOLVABLE_BUILDVERSION); + bv2 = solvable_lookup_str(s2, SOLVABLE_BUILDVERSION); if (!bv1 && !bv2) return 0; return pool_evrcmp_str(pool, bv1 ? bv1 : "" , bv2 ? bv2 : "", EVRCMP_COMPARE); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/repo.c new/libsolv-0.7.13/src/repo.c --- old/libsolv-0.7.11/src/repo.c 2019-06-05 15:24:17.000000000 +0200 +++ new/libsolv-0.7.13/src/repo.c 2020-04-24 12:00:43.000000000 +0200 @@ -213,6 +213,8 @@ int j; for (j = dstart; j < dend; j++) data->attrs[j - data->start] = solv_free(data->attrs[j - data->start]); + if (data->lasthandle >= dstart && data->lasthandle < dend) + data->lasthandle = 0; } if (data->incoreoffset) memset(data->incoreoffset + (dstart - data->start), 0, (dend - dstart) * sizeof(Id)); @@ -737,6 +739,32 @@ } } +static Offset * +solvable_offsetptr(Solvable *s, Id keyname) +{ + switch(keyname) + { + case SOLVABLE_PROVIDES: + return &s->provides; + case SOLVABLE_OBSOLETES: + return &s->obsoletes; + case SOLVABLE_CONFLICTS: + return &s->conflicts; + case SOLVABLE_REQUIRES: + return &s->requires; + case SOLVABLE_RECOMMENDS: + return &s->recommends; + case SOLVABLE_SUGGESTS: + return &s->suggests; + case SOLVABLE_SUPPLEMENTS: + return &s->supplements; + case SOLVABLE_ENHANCES: + return &s->enhances; + default: + return 0; + } +} + static void repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md) { @@ -1131,18 +1159,6 @@ return 0; } -static int -lookup_idarray_solvable(Repo *repo, Offset off, Queue *q) -{ - Id *p; - - queue_empty(q); - if (off) - for (p = repo->idarraydata + off; *p; p++) - queue_push(q, *p); - return 1; -} - int repo_lookup_idarray(Repo *repo, Id entry, Id keyname, Queue *q) { @@ -1150,24 +1166,25 @@ int i; if (entry >= 0) { + Offset *offp; switch (keyname) { case SOLVABLE_PROVIDES: - return lookup_idarray_solvable(repo, repo->pool->solvables[entry].provides, q); case SOLVABLE_OBSOLETES: - return lookup_idarray_solvable(repo, repo->pool->solvables[entry].obsoletes, q); case SOLVABLE_CONFLICTS: - return lookup_idarray_solvable(repo, repo->pool->solvables[entry].conflicts, q); case SOLVABLE_REQUIRES: - return lookup_idarray_solvable(repo, repo->pool->solvables[entry].requires, q); case SOLVABLE_RECOMMENDS: - return lookup_idarray_solvable(repo, repo->pool->solvables[entry].recommends, q); case SOLVABLE_SUGGESTS: - return lookup_idarray_solvable(repo, repo->pool->solvables[entry].suggests, q); case SOLVABLE_SUPPLEMENTS: - return lookup_idarray_solvable(repo, repo->pool->solvables[entry].supplements, q); case SOLVABLE_ENHANCES: - return lookup_idarray_solvable(repo, repo->pool->solvables[entry].enhances, q); + offp = solvable_offsetptr(repo->pool->solvables + entry, keyname); + if (*offp) + { + Id *p; + for (p = repo->idarraydata + *offp; *p; p++) + queue_push(q, *p); + } + return 1; } } data = repo_lookup_repodata_opt(repo, entry, keyname); @@ -1270,6 +1287,37 @@ return 0; } +unsigned int +repo_lookup_count(Repo *repo, Id entry, Id keyname) +{ + Repodata *data; + if (keyname >= SOLVABLE_NAME && keyname <= RPM_RPMDBID) + if (entry >= 0 && keyname >= SOLVABLE_NAME && keyname <= RPM_RPMDBID) + { + Id *p; + Offset *offp; + unsigned int cnt; + switch (keyname) + { + case SOLVABLE_PROVIDES: + case SOLVABLE_OBSOLETES: + case SOLVABLE_CONFLICTS: + case SOLVABLE_REQUIRES: + case SOLVABLE_RECOMMENDS: + case SOLVABLE_SUGGESTS: + case SOLVABLE_SUPPLEMENTS: + case SOLVABLE_ENHANCES: + offp = solvable_offsetptr(repo->pool->solvables + entry, keyname); + for (cnt = 0, p = repo->idarraydata + *offp; *p; p++) + cnt++; + return cnt; + } + return 1; + } + data = repo_lookup_repodata_opt(repo, entry, keyname); + return data ? repodata_lookup_count(data, entry, keyname) : 0; +} + /***********************************************************************/ Repodata * @@ -1429,32 +1477,19 @@ marker = solv_depmarker(keyname, marker); if (p >= 0) { - Solvable *s = repo->pool->solvables + p; + Offset *offp; switch (keyname) { case SOLVABLE_PROVIDES: - s->provides = repo_addid_dep(repo, s->provides, dep, marker); - return; case SOLVABLE_OBSOLETES: - s->obsoletes = repo_addid_dep(repo, s->obsoletes, dep, marker); - return; case SOLVABLE_CONFLICTS: - s->conflicts = repo_addid_dep(repo, s->conflicts, dep, marker); - return; case SOLVABLE_REQUIRES: - s->requires = repo_addid_dep(repo, s->requires, dep, marker); - return; case SOLVABLE_RECOMMENDS: - s->recommends = repo_addid_dep(repo, s->recommends, dep, marker); - return; case SOLVABLE_SUGGESTS: - s->suggests = repo_addid_dep(repo, s->suggests, dep, marker); - return; case SOLVABLE_SUPPLEMENTS: - s->supplements = repo_addid_dep(repo, s->supplements, dep, marker); - return; case SOLVABLE_ENHANCES: - s->enhances = repo_addid_dep(repo, s->enhances, dep, marker); + offp = solvable_offsetptr(repo->pool->solvables + p, keyname); + *offp = repo_addid_dep(repo, *offp, dep, marker); return; } } @@ -1468,16 +1503,6 @@ repo_add_deparray(repo, p, keyname, id, 0); } -static Offset -repo_set_idarray_solvable(Repo *repo, Queue *q) -{ - Offset o = 0; - int i; - for (i = 0; i < q->count; i++) - repo_addid_dep(repo, o, q->elements[i], 0); - return o; -} - void repo_set_deparray(Repo *repo, Id p, Id keyname, Queue *q, Id marker) { @@ -1512,32 +1537,23 @@ } if (p >= 0) { - Solvable *s = repo->pool->solvables + p; + Offset off, *offp; + int i; switch (keyname) { case SOLVABLE_PROVIDES: - s->provides = repo_set_idarray_solvable(repo, q); - return; case SOLVABLE_OBSOLETES: - s->obsoletes = repo_set_idarray_solvable(repo, q); - return; case SOLVABLE_CONFLICTS: - s->conflicts = repo_set_idarray_solvable(repo, q); - return; case SOLVABLE_REQUIRES: - s->requires = repo_set_idarray_solvable(repo, q); - return; case SOLVABLE_RECOMMENDS: - s->recommends = repo_set_idarray_solvable(repo, q); - return; case SOLVABLE_SUGGESTS: - s->suggests = repo_set_idarray_solvable(repo, q); - return; case SOLVABLE_SUPPLEMENTS: - s->supplements = repo_set_idarray_solvable(repo, q); - return; case SOLVABLE_ENHANCES: - s->enhances = repo_set_idarray_solvable(repo, q); + off = 0; + for (i = 0; i < q->count; i++) + off = repo_addid_dep(repo, off, q->elements[i], 0); + offp = solvable_offsetptr(repo->pool->solvables + p, keyname); + *offp = off; return; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/repo.h new/libsolv-0.7.13/src/repo.h --- old/libsolv-0.7.11/src/repo.h 2019-09-30 14:39:28.000000000 +0200 +++ new/libsolv-0.7.13/src/repo.h 2020-04-16 23:34:15.000000000 +0200 @@ -189,6 +189,7 @@ const char *repo_lookup_checksum(Repo *repo, Id entry, Id keyname, Id *typep); const unsigned char *repo_lookup_bin_checksum(Repo *repo, Id entry, Id keyname, Id *typep); const void *repo_lookup_binary(Repo *repo, Id entry, Id keyname, int *lenp); +unsigned int repo_lookup_count(Repo *repo, Id entry, Id keyname); /* internal */ Id solv_depmarker(Id keyname, Id marker); void repo_set_id(Repo *repo, Id p, Id keyname, Id id); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/repodata.c new/libsolv-0.7.13/src/repodata.c --- old/libsolv-0.7.11/src/repodata.c 2019-08-28 14:51:03.000000000 +0200 +++ new/libsolv-0.7.13/src/repodata.c 2020-04-24 12:00:43.000000000 +0200 @@ -841,6 +841,57 @@ return dp; } +unsigned int +repodata_lookup_count(Repodata *data, Id solvid, Id keyname) +{ + unsigned char *dp; + Repokey *key; + unsigned int cnt = 0; + + dp = find_key_data(data, solvid, keyname, &key); + if (!dp) + return 0; + switch (key->type) + { + case REPOKEY_TYPE_IDARRAY: + case REPOKEY_TYPE_REL_IDARRAY: + for (cnt = 1; (*dp & 0xc0) != 0; dp++) + if ((*dp & 0xc0) == 0x40) + cnt++; + return cnt; + case REPOKEY_TYPE_FIXARRAY: + case REPOKEY_TYPE_FLEXARRAY: + data_read_id(dp, (int *)&cnt); + return cnt; + case REPOKEY_TYPE_DIRSTRARRAY: + for (;;) + { + cnt++; + while (*dp & 0x80) + dp++; + if (!(*dp++ & 0x40)) + return cnt; + dp += strlen((const char *)dp) + 1; + } + case REPOKEY_TYPE_DIRNUMNUMARRAY: + for (;;) + { + cnt++; + while (*dp++ & 0x80) + ; + while (*dp++ & 0x80) + ; + while (*dp & 0x80) + dp++; + if (!(*dp++ & 0x40)) + return cnt; + } + default: + break; + } + return 1; +} + /* highly specialized function to speed up fileprovides adding. * - repodata must be available * - solvid must be >= data->start and < data->end @@ -3049,6 +3100,8 @@ tmpattrs = data->attrs[dest - data->start]; data->attrs[dest - data->start] = data->attrs[src - data->start]; data->attrs[src - data->start] = tmpattrs; + if (data->lasthandle == src || data->lasthandle == dest) + data->lasthandle = 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/repodata.h new/libsolv-0.7.13/src/repodata.h --- old/libsolv-0.7.11/src/repodata.h 2018-10-22 15:37:12.000000000 +0200 +++ new/libsolv-0.7.13/src/repodata.h 2020-04-16 23:34:15.000000000 +0200 @@ -229,6 +229,7 @@ const unsigned char *repodata_lookup_bin_checksum(Repodata *data, Id solvid, Id keyname, Id *typep); int repodata_lookup_idarray(Repodata *data, Id solvid, Id keyname, Queue *q); const void *repodata_lookup_binary(Repodata *data, Id solvid, Id keyname, int *lenp); +unsigned int repodata_lookup_count(Repodata *data, Id solvid, Id keyname); /* internal */ /* internal, used in fileprovides code */ const unsigned char *repodata_lookup_packed_dirstrarray(Repodata *data, Id solvid, Id keyname); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/rules.c new/libsolv-0.7.13/src/rules.c --- old/libsolv-0.7.11/src/rules.c 2020-01-22 13:04:17.000000000 +0100 +++ new/libsolv-0.7.13/src/rules.c 2020-02-12 11:39:14.000000000 +0100 @@ -613,7 +613,7 @@ } else { - Id *qele; + Id *qele, d; int qcnt; qele = bq.elements + i; @@ -653,7 +653,17 @@ break; if (j < qcnt) continue; - addpkgrule(solv, qele[0], 0, pool_ids2whatprovides(pool, qele + 1, qcnt - 1), type, dep); + d = pool_ids2whatprovides(pool, qele + 1, qcnt - 1); + if (solv->ruleinfoq && qele[0] != p) + { + int oldcount = solv->ruleinfoq->count; + addpkgrule(solv, qele[0], 0, d, type, dep); + /* fixup from element of ruleinfo */ + if (solv->ruleinfoq->count > oldcount) + solv->ruleinfoq->elements[oldcount + 1] = p; + } + else + addpkgrule(solv, qele[0], 0, d, type, dep); if (m) for (j = 0; j < qcnt; j++) if (qele[j] > 0 && !MAPTST(m, qele[j])) @@ -2729,7 +2739,8 @@ if (*odp) return; } - if (p < 0 && pool->whatprovidesdata[d] < 0 && type == SOLVER_RULE_PKG_CONFLICTS) + /* set p2 for multiversion conflicts */ + if (p < 0 && pool->whatprovidesdata[d] < 0 && pool->whatprovidesdata[d + 1] >= 0 && type == SOLVER_RULE_PKG_CONFLICTS) p2 = pool->whatprovidesdata[d]; } else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/solvable.c new/libsolv-0.7.13/src/solvable.c --- old/libsolv-0.7.11/src/solvable.c 2019-10-22 14:22:01.000000000 +0200 +++ new/libsolv-0.7.13/src/solvable.c 2020-04-16 23:34:15.000000000 +0200 @@ -323,6 +323,12 @@ return chk ? pool_bin2hex(s->repo->pool, chk, solv_chksum_len(*typep)) : 0; } +unsigned int +solvable_lookup_count(Solvable *s, Id keyname) +{ + return s->repo ? repo_lookup_count(s->repo, s - s->repo->pool->solvables, keyname) : 0; +} + static inline const char * evrid2vrstr(Pool *pool, Id evrid) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/src/solvable.h new/libsolv-0.7.13/src/solvable.h --- old/libsolv-0.7.11/src/solvable.h 2019-10-22 14:22:01.000000000 +0200 +++ new/libsolv-0.7.13/src/solvable.h 2020-04-16 23:34:15.000000000 +0200 @@ -64,6 +64,7 @@ const char *solvable_lookup_checksum(Solvable *s, Id keyname, Id *typep); int solvable_lookup_idarray(Solvable *s, Id keyname, Queue *q); int solvable_lookup_deparray(Solvable *s, Id keyname, Queue *q, Id marker); +unsigned int solvable_lookup_count(Solvable *s, Id keyname); /* internal */ /* setter functions */ void solvable_set_id(Solvable *s, Id keyname, Id id); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/win32/config.h new/libsolv-0.7.13/win32/config.h --- old/libsolv-0.7.11/win32/config.h 1970-01-01 01:00:00.000000000 +0100 +++ new/libsolv-0.7.13/win32/config.h 2020-04-20 17:19:12.000000000 +0200 @@ -0,0 +1,13 @@ +#ifdef _WIN32 + #ifdef SOLV_STATIC_LIB + #define SOLV_API + #else + #ifdef SOLV_EXPORTS + #define SOLV_API __declspec(dllexport) + #else + #define SOLV_API __declspec(dllimport) + #endif + #endif +#else + #define SOLV_API +#endif \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/win32/getopt.c new/libsolv-0.7.13/win32/getopt.c --- old/libsolv-0.7.11/win32/getopt.c 2019-04-11 16:48:30.000000000 +0200 +++ new/libsolv-0.7.13/win32/getopt.c 2020-04-20 17:19:12.000000000 +0200 @@ -5,8 +5,10 @@ #include <stdlib.h> #include <stdio.h> -char *optarg; -int optind=1, opterr=1, optopt, __optpos, __optreset=0; +#include "config.h" + +SOLV_API char *optarg; +SOLV_API int optind=1, opterr=1, optopt, __optpos, __optreset=0; #define optpos __optpos diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libsolv-0.7.11/win32/getopt.h new/libsolv-0.7.13/win32/getopt.h --- old/libsolv-0.7.11/win32/getopt.h 2019-04-11 16:48:30.000000000 +0200 +++ new/libsolv-0.7.13/win32/getopt.h 2020-04-20 17:19:12.000000000 +0200 @@ -5,9 +5,12 @@ extern "C" { #endif +#include "config.h" + int getopt(int, char * const [], const char *); -extern char *optarg; -extern int optind, opterr, optopt, optreset; + +SOLV_API extern char *optarg; +SOLV_API extern int optind, opterr, optopt, optreset; struct option { const char *name;
