From a4f1b2fc2c748bcbd7a743e15ff7eb3b2548eff4 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Thu, 23 Apr 2026 15:44:16 +0200 Subject: [PATCH] Split the checksum implementation into chksum_impl.c The goal is to move the implementation into the libsolvext at some point in time. --- src/CMakeLists.txt | 2 +- src/chksum.c | 161 ++++++++------------------------------------- src/chksum.h | 15 ++++- src/chksum_impl.c | 139 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 179 insertions(+), 138 deletions(-) create mode 100644 src/chksum_impl.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 812abe6e..4bdc2e18 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,7 @@ SET (libsolv_SRCS solver.c solverdebug.c repo_solv.c repo_write.c evr.c queue.c repo.c repodata.c repopage.c util.c policy.c solvable.c transaction.c order.c rules.c problems.c linkedpkg.c cplxdeps.c - chksum.c md5.c sha1.c sha2.c solvversion.c selection.c + chksum.c chksum_impl.c md5.c sha1.c sha2.c solvversion.c selection.c fileprovides.c diskusage.c suse.c solver_util.c cleandeps.c userinstalled.c filelistfilter.c decision.c) diff --git a/src/chksum.c b/src/chksum.c index aeb3f585..9d1a8e63 100644 --- a/src/chksum.c +++ b/src/chksum.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012, Novell Inc. + * Copyright (c) 2008-2026, SUSE LLC * * This program is licensed under the BSD license, read LICENSE.BSD * for further information @@ -26,59 +26,13 @@ #include "strfncs.h" #endif +/* keep in sync with chksum_impl.c */ struct s_Chksum { Id type; - int done; - unsigned char result[64]; - union { - MD5_CTX md5; - SHA1_CTX sha1; - SHA224_CTX sha224; - SHA256_CTX sha256; - SHA384_CTX sha384; - SHA512_CTX sha512; - } c; + void * (*impl)(struct s_Chksum *, int); + unsigned char result[SOLV_CHKSUM_MAXLEN]; }; -Chksum * -solv_chksum_create(Id type) -{ - Chksum *chk; - chk = solv_calloc(1, sizeof(*chk)); - chk->type = type; - switch(type) - { - case REPOKEY_TYPE_MD5: - solv_MD5_Init(&chk->c.md5); - return chk; - case REPOKEY_TYPE_SHA1: - solv_SHA1_Init(&chk->c.sha1); - return chk; - case REPOKEY_TYPE_SHA224: - solv_SHA224_Init(&chk->c.sha224); - return chk; - case REPOKEY_TYPE_SHA256: - solv_SHA256_Init(&chk->c.sha256); - return chk; - case REPOKEY_TYPE_SHA384: - solv_SHA384_Init(&chk->c.sha384); - return chk; - case REPOKEY_TYPE_SHA512: - solv_SHA512_Init(&chk->c.sha512); - return chk; - default: - break; - } - free(chk); - return 0; -} - -Chksum * -solv_chksum_create_clone(Chksum *chk) -{ - return solv_memdup(chk, sizeof(*chk)); -} - int solv_chksum_len(Id type) { @@ -110,93 +64,32 @@ solv_chksum_create_from_bin(Id type, const unsigned char *buf) return 0; chk = solv_calloc(1, sizeof(*chk)); chk->type = type; - chk->done = 1; memcpy(chk->result, buf, l); return chk; } -void -solv_chksum_add(Chksum *chk, const void *data, int len) +Chksum * +solv_chksum_create_clone(Chksum *chk) { - if (chk->done) - return; - switch(chk->type) - { - case REPOKEY_TYPE_MD5: - solv_MD5_Update(&chk->c.md5, (void *)data, len); - return; - case REPOKEY_TYPE_SHA1: - solv_SHA1_Update(&chk->c.sha1, data, len); - return; - case REPOKEY_TYPE_SHA224: - solv_SHA224_Update(&chk->c.sha224, data, len); - return; - case REPOKEY_TYPE_SHA256: - solv_SHA256_Update(&chk->c.sha256, data, len); - return; - case REPOKEY_TYPE_SHA384: - solv_SHA384_Update(&chk->c.sha384, data, len); - return; - case REPOKEY_TYPE_SHA512: - solv_SHA512_Update(&chk->c.sha512, data, len); - return; - default: - return; - } + if (chk->impl) + return chk->impl(chk, SOLV_CHKSUMP_IMPL_CLONE); + return solv_memdup(chk, sizeof(*chk)); +} + +static inline int +solv_chksum_finalize(Chksum *chk) +{ + unsigned char *end = chk->impl(chk, SOLV_CHKSUMP_IMPL_FINALIZE); + return end ? end - chk->result : 0; } const unsigned char * solv_chksum_get(Chksum *chk, int *lenp) { - if (chk->done) - { - if (lenp) - *lenp = solv_chksum_len(chk->type); - return chk->result; - } - switch(chk->type) - { - case REPOKEY_TYPE_MD5: - solv_MD5_Final(chk->result, &chk->c.md5); - chk->done = 1; - if (lenp) - *lenp = 16; - return chk->result; - case REPOKEY_TYPE_SHA1: - solv_SHA1_Final(&chk->c.sha1, chk->result); - chk->done = 1; - if (lenp) - *lenp = 20; - return chk->result; - case REPOKEY_TYPE_SHA224: - solv_SHA224_Final(chk->result, &chk->c.sha224); - chk->done = 1; - if (lenp) - *lenp = 28; - return chk->result; - case REPOKEY_TYPE_SHA256: - solv_SHA256_Final(chk->result, &chk->c.sha256); - chk->done = 1; - if (lenp) - *lenp = 32; - return chk->result; - case REPOKEY_TYPE_SHA384: - solv_SHA384_Final(chk->result, &chk->c.sha384); - chk->done = 1; - if (lenp) - *lenp = 48; - return chk->result; - case REPOKEY_TYPE_SHA512: - solv_SHA512_Final(chk->result, &chk->c.sha512); - chk->done = 1; - if (lenp) - *lenp = 64; - return chk->result; - default: - if (lenp) - *lenp = 0; - return 0; - } + int len = chk->impl ? solv_chksum_finalize(chk) : solv_chksum_len(chk->type); + if (lenp) + *lenp = len; + return len ? chk->result : 0; } Id @@ -208,7 +101,7 @@ solv_chksum_get_type(Chksum *chk) int solv_chksum_isfinished(Chksum *chk) { - return chk->done != 0; + return !chk->impl; } const char * @@ -256,12 +149,12 @@ solv_chksum_free(Chksum *chk, unsigned char *cp) { if (cp) { - const unsigned char *res; - int l; - res = solv_chksum_get(chk, &l); - if (l && res) - memcpy(cp, res, l); + int len = chk->impl ? solv_chksum_finalize(chk) : solv_chksum_len(chk->type); + if (len) + memcpy(cp, chk->result, len); } + else if (chk->impl) + chk->impl(chk, SOLV_CHKSUMP_IMPL_FREE); /* free resources */ solv_free(chk); return 0; } @@ -277,5 +170,5 @@ solv_chksum_cmp(Chksum *chk, Chksum *chk2) return 0; res1 = solv_chksum_get(chk, &len); res2 = solv_chksum_get(chk2, 0); - return memcmp(res1, res2, len) == 0 ? 1 : 0; + return res1 && res2 && memcmp(res1, res2, len) == 0 ? 1 : 0; } diff --git a/src/chksum.h b/src/chksum.h index 65b775bc..6253fadd 100644 --- a/src/chksum.h +++ b/src/chksum.h @@ -17,10 +17,7 @@ extern "C" { struct s_Chksum; typedef struct s_Chksum Chksum; -Chksum *solv_chksum_create(Id type); -Chksum *solv_chksum_create_clone(Chksum *chk); Chksum *solv_chksum_create_from_bin(Id type, const unsigned char *buf); -void solv_chksum_add(Chksum *chk, const void *data, int len); Id solv_chksum_get_type(Chksum *chk); int solv_chksum_isfinished(Chksum *chk); const unsigned char *solv_chksum_get(Chksum *chk, int *lenp); @@ -29,6 +26,18 @@ const char *solv_chksum_type2str(Id type); Id solv_chksum_str2type(const char *str); int solv_chksum_len(Id type); int solv_chksum_cmp(Chksum *chk, Chksum *chk2); +Chksum *solv_chksum_create_finished_clone(Chksum *chk); + +/* implementation */ +Chksum *solv_chksum_create(Id type); +Chksum *solv_chksum_create_clone(Chksum *chk); +void solv_chksum_add(Chksum *chk, const void *data, int len); + +#define SOLV_CHKSUM_MAXLEN 64 + +#define SOLV_CHKSUMP_IMPL_FREE 0 +#define SOLV_CHKSUMP_IMPL_FINALIZE 1 +#define SOLV_CHKSUMP_IMPL_CLONE 2 #ifdef LIBSOLV_INTERNAL diff --git a/src/chksum_impl.c b/src/chksum_impl.c new file mode 100644 index 00000000..2562eccf --- /dev/null +++ b/src/chksum_impl.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2026, SUSE LLC + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +#include +#include +#include +#include +#include + +#include "pool.h" +#include "util.h" +#include "chksum.h" + +#include "md5.h" +#include "sha1.h" +#include "sha2.h" + +/* keep in sync with chksum.c */ +struct s_Chksum { + Id type; + void *(*impl)(struct s_Chksum *, int op); + unsigned char result[SOLV_CHKSUM_MAXLEN]; + union { + MD5_CTX md5; + SHA1_CTX sha1; + SHA224_CTX sha224; + SHA256_CTX sha256; + SHA384_CTX sha384; + SHA512_CTX sha512; + } c; +}; + +static void * +solv_chksum_impl(Chksum *chk, int op) +{ + if (op == SOLV_CHKSUMP_IMPL_CLONE) + return solv_memdup(chk, sizeof(*chk)); + else if (op != SOLV_CHKSUMP_IMPL_FINALIZE) + return 0; + switch(chk->type) + { + case REPOKEY_TYPE_MD5: + solv_MD5_Final(chk->result, &chk->c.md5); + chk->impl = 0; + return chk->result + 16; + case REPOKEY_TYPE_SHA1: + solv_SHA1_Final(&chk->c.sha1, chk->result); + chk->impl = 0; + return chk->result + 20; + case REPOKEY_TYPE_SHA224: + solv_SHA224_Final(chk->result, &chk->c.sha224); + chk->impl = 0; + return chk->result + 28; + case REPOKEY_TYPE_SHA256: + solv_SHA256_Final(chk->result, &chk->c.sha256); + chk->impl = 0; + return chk->result + 32; + case REPOKEY_TYPE_SHA384: + solv_SHA384_Final(chk->result, &chk->c.sha384); + chk->impl = 0; + return chk->result + 48; + case REPOKEY_TYPE_SHA512: + solv_SHA512_Final(chk->result, &chk->c.sha512); + chk->impl = 0; + return chk->result + 64; + default: + break; + } + return 0; +} + +Chksum * +solv_chksum_create(Id type) +{ + Chksum *chk; + chk = solv_calloc(1, sizeof(*chk)); + chk->type = type; + chk->impl = solv_chksum_impl; + switch(type) + { + case REPOKEY_TYPE_MD5: + solv_MD5_Init(&chk->c.md5); + return chk; + case REPOKEY_TYPE_SHA1: + solv_SHA1_Init(&chk->c.sha1); + return chk; + case REPOKEY_TYPE_SHA224: + solv_SHA224_Init(&chk->c.sha224); + return chk; + case REPOKEY_TYPE_SHA256: + solv_SHA256_Init(&chk->c.sha256); + return chk; + case REPOKEY_TYPE_SHA384: + solv_SHA384_Init(&chk->c.sha384); + return chk; + case REPOKEY_TYPE_SHA512: + solv_SHA512_Init(&chk->c.sha512); + return chk; + default: + break; + } + free(chk); + return 0; +} + +void +solv_chksum_add(Chksum *chk, const void *data, int len) +{ + if (!chk->impl) + return; + switch(chk->type) + { + case REPOKEY_TYPE_MD5: + solv_MD5_Update(&chk->c.md5, (void *)data, len); + return; + case REPOKEY_TYPE_SHA1: + solv_SHA1_Update(&chk->c.sha1, data, len); + return; + case REPOKEY_TYPE_SHA224: + solv_SHA224_Update(&chk->c.sha224, data, len); + return; + case REPOKEY_TYPE_SHA256: + solv_SHA256_Update(&chk->c.sha256, data, len); + return; + case REPOKEY_TYPE_SHA384: + solv_SHA384_Update(&chk->c.sha384, data, len); + return; + case REPOKEY_TYPE_SHA512: + solv_SHA512_Update(&chk->c.sha512, data, len); + return; + default: + break; + } +} + -- 2.47.3