From: Michael Tremer Date: Fri, 19 Aug 2022 12:27:03 +0000 (+0000) Subject: file: Refactor how we store digests X-Git-Tag: 0.9.28~427 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9802aaf66bde4ca361f9a3955719b1f880285115;p=pakfire.git file: Refactor how we store digests Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/file.c b/src/_pakfire/file.c index b1a05ffea..339cdeed3 100644 --- a/src/_pakfire/file.c +++ b/src/_pakfire/file.c @@ -248,11 +248,14 @@ static PyObject* File_digest(FileObject* self, PyObject* args) { } static PyObject* _File_hexdigest(FileObject* self, enum pakfire_digests type) { - const char* hexdigest = pakfire_file_get_hexdigest(self->file, type); + char* hexdigest = pakfire_file_get_hexdigest(self->file, type); if (!hexdigest) Py_RETURN_NONE; - return PyUnicode_FromString(hexdigest); + PyObject* obj = PyUnicode_FromString(hexdigest); + free(hexdigest); + + return obj; } static PyObject* File_hexdigest(FileObject* self, PyObject* args) { diff --git a/src/_pakfire/package.c b/src/_pakfire/package.c index 783e813f8..dcb039dbd 100644 --- a/src/_pakfire/package.c +++ b/src/_pakfire/package.c @@ -194,7 +194,7 @@ static void Package_set_uuid(PackageObject* self, PyObject* value) { } static PyObject* Package_get_hexdigest(PackageObject* self, enum pakfire_digests type) { - enum pakfire_digests digest = PAKFIRE_DIGEST_NONE; + enum pakfire_digests digest = 0; const char* hexdigest = pakfire_package_get_hexdigest(self->package, &digest); if (!hexdigest) diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c index 9cd02e736..5ba760e58 100644 --- a/src/libpakfire/db.c +++ b/src/libpakfire/db.c @@ -851,7 +851,7 @@ static const struct pakfire_digest { } pakfire_digests[] = { { PAKFIRE_DIGEST_SHA512, "sha512:" }, { PAKFIRE_DIGEST_SHA256, "sha256:" }, - { PAKFIRE_DIGEST_NONE, NULL }, + { 0, NULL }, }; static char* pakfire_db_pack_digest(enum pakfire_digests type, const char* hexdigest) { @@ -872,7 +872,7 @@ static char* pakfire_db_pack_digest(enum pakfire_digests type, const char* hexdi } static const char* pakfire_db_unpack_digest(const char* hexdigest, enum pakfire_digests* type) { - *type = PAKFIRE_DIGEST_NONE; + *type = 0; // Don't do anything for empty input if (!hexdigest || !*hexdigest) @@ -988,7 +988,7 @@ static int pakfire_db_file_add_digests(struct pakfire_db* db, unsigned long id, PAKFIRE_DIGEST_SHA256, // Sentinel - PAKFIRE_DIGEST_NONE, + 0, }; const char* sql = "INSERT INTO file_digests(file, type, digest) VALUES(?, ?, ?)"; @@ -1449,7 +1449,7 @@ int pakfire_db_add_package(struct pakfire_db* db, goto ERROR; } - enum pakfire_digests digest_type = PAKFIRE_DIGEST_NONE; + enum pakfire_digests digest_type = 0; const char* hexdigest = pakfire_package_get_hexdigest(pkg, &digest_type); if (hexdigest) { @@ -1830,7 +1830,7 @@ static int pakfire_db_load_package(struct pakfire_db* db, struct pakfire_repo* r // Digest const char* digest = (const char*)sqlite3_column_text(stmt, 8); if (digest) { - enum pakfire_digests digest_type = PAKFIRE_DIGEST_NONE; + enum pakfire_digests digest_type = 0; // Unpack digest const char* hexdigest = pakfire_db_unpack_digest(digest, &digest_type); diff --git a/src/libpakfire/dist.c b/src/libpakfire/dist.c index dc8120b44..9f06ffedf 100644 --- a/src/libpakfire/dist.c +++ b/src/libpakfire/dist.c @@ -260,7 +260,7 @@ static int pakfire_dist_add_source(struct pakfire* pakfire, struct pakfire_packa // Download the file if it does not exist in the cache if (access(cache_path, R_OK) != 0) { r = pakfire_downloader_retrieve(downloader, BASEURL, mirrorlist, - NULL, filename, cache_path, PAKFIRE_DIGEST_NONE, NULL, 0, 0); + NULL, filename, cache_path, 0, NULL, 0, 0); if (r) return r; } diff --git a/src/libpakfire/downloader.c b/src/libpakfire/downloader.c index 8349d513e..626a66c0b 100644 --- a/src/libpakfire/downloader.c +++ b/src/libpakfire/downloader.c @@ -285,17 +285,12 @@ static struct pakfire_transfer* pakfire_downloader_create_transfer( } // Check if expected digest is set - switch (md) { - case PAKFIRE_DIGEST_NONE: - break; - - default: - if (!expected_digest || !expected_digest_length) { - ERROR(downloader->pakfire, "Expected message digest or size is not set\n"); - errno = EINVAL; - return NULL; - } - break; + if (md) { + if (!expected_digest || !expected_digest_length) { + ERROR(downloader->pakfire, "Expected message digest or size is not set\n"); + errno = EINVAL; + return NULL; + } } // Expected digest length cannot be too long @@ -357,9 +352,6 @@ static struct pakfire_transfer* pakfire_downloader_create_transfer( case PAKFIRE_DIGEST_SHA256: transfer->md = EVP_sha256(); break; - - case PAKFIRE_DIGEST_NONE: - break; } // Copy the expected digest diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index 6d28da9ef..0dc6e167b 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -37,17 +38,6 @@ #include #include -#define MAX_DIGESTS 4 - -struct pakfire_file_digest { - enum pakfire_digests type; - unsigned char digest[EVP_MAX_MD_SIZE]; - size_t length; - - // Add a buffer to store the hex representation - char* hexdigest; -}; - struct pakfire_file { struct pakfire* pakfire; int nrefs; @@ -80,7 +70,13 @@ struct pakfire_file { char symlink[PATH_MAX]; // Digests - struct pakfire_file_digest digests[MAX_DIGESTS]; + struct pakfire_file_digests { + // SHA-512 + unsigned char sha512[SHA512_DIGEST_LENGTH]; + + // SHA-256 + unsigned char sha256[SHA256_DIGEST_LENGTH]; + } digests; #warning TODO capabilities, config, data // capabilities @@ -129,7 +125,7 @@ static const struct pakfire_libarchive_digest { } pakfire_libarchive_digests[] = { { PAKFIRE_DIGEST_SHA512, ARCHIVE_ENTRY_DIGEST_SHA512 }, { PAKFIRE_DIGEST_SHA256, ARCHIVE_ENTRY_DIGEST_SHA256 }, - { PAKFIRE_DIGEST_NONE, 0 }, + { 0, 0 }, }; int pakfire_file_copy_archive_entry(struct pakfire_file* file, struct archive_entry* entry) { @@ -177,9 +173,7 @@ int pakfire_file_copy_archive_entry(struct pakfire_file* file, struct archive_en type->pakfire; type++) { const unsigned char* digest = archive_entry_digest(entry, type->libarchive); if (digest) { - size_t length = pakfire_digest_length(type->pakfire); - - r = pakfire_file_set_digest(file, type->pakfire, digest, length); + r = pakfire_file_set_digest(file, type->pakfire, digest); if (r) return r; } @@ -229,18 +223,6 @@ struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file) { } static void pakfire_file_free(struct pakfire_file* file) { - struct pakfire_file_digest* digest = NULL; - - // Free any generated hexdigests - for (unsigned int i = 0; i < MAX_DIGESTS; i++) { - digest = &file->digests[i]; - - if (digest->hexdigest) { - free(digest->hexdigest); - digest->hexdigest = NULL; - } - } - pakfire_unref(file->pakfire); free(file); } @@ -382,105 +364,75 @@ PAKFIRE_EXPORT void pakfire_file_set_mtime(struct pakfire_file* file, time_t tim file->mtime = time; } -static struct pakfire_file_digest* pakfire_file_find_digest( - struct pakfire_file* file, enum pakfire_digests type) { - struct pakfire_file_digest* digest = NULL; - - for (unsigned int i = 0; i < MAX_DIGESTS; i++) { - digest = &file->digests[i]; - - if (digest->type == type) - return digest; +/* + Returns one if the digest is not all zeros. +*/ +static int pakfire_file_has_digest(const unsigned char* digest, const size_t length) { + for (unsigned int i = 0; i < length; i++) { + if (digest[i]) + return 1; } - // No match - return NULL; + return 0; } PAKFIRE_EXPORT const unsigned char* pakfire_file_get_digest( - struct pakfire_file* file, enum pakfire_digests type, size_t* length) { - const struct pakfire_file_digest* digest = pakfire_file_find_digest(file, type); - if (!digest) - return NULL; + struct pakfire_file* file, const enum pakfire_digests type, size_t* length) { - // Export length - if (length) - *length = digest->length; + switch (type) { + case PAKFIRE_DIGEST_SHA512: + if (!pakfire_file_has_digest(file->digests.sha512, sizeof(file->digests.sha512))) + return NULL; - return digest->digest; -} + if (length) + *length = sizeof(file->digests.sha512); -PAKFIRE_EXPORT const char* pakfire_file_get_hexdigest( - struct pakfire_file* file, enum pakfire_digests type) { - struct pakfire_file_digest* digest = pakfire_file_find_digest(file, type); - if (!digest) - return NULL; + return file->digests.sha512; + + case PAKFIRE_DIGEST_SHA256: + if (!pakfire_file_has_digest(file->digests.sha256, sizeof(file->digests.sha256))) + return NULL; - // Generate the hexdigest if non exists - if (!digest->hexdigest) { - const size_t length = pakfire_digest_length(digest->type); - if (!length) - return NULL; + if (length) + *length = sizeof(file->digests.sha256); - digest->hexdigest = __pakfire_hexlify(digest->digest, length); + return file->digests.sha256; } - return digest->hexdigest; + return NULL; } PAKFIRE_EXPORT int pakfire_file_set_digest(struct pakfire_file* file, - enum pakfire_digests type, const unsigned char* digest, size_t length) { - if (!digest || !length) { + const enum pakfire_digests type, const unsigned char* digest) { + if (!digest) { errno = EINVAL; return 1; } - // Find any existing digests of this type - struct pakfire_file_digest* d = pakfire_file_find_digest(file, type); - - // If there is no digest, we will try finding a new one - if (!d) - d = pakfire_file_find_digest(file, PAKFIRE_DIGEST_NONE); - - // If we could not find a free spot, we probably run out of space - if (!d) { - errno = ENOBUFS; - return 1; - } + switch (type) { + case PAKFIRE_DIGEST_SHA512: + memcpy(file->digests.sha512, digest, sizeof(file->digests.sha512)); + break; - // Check if the digest fits into our pre-allocated buffer space - if (length > sizeof(d->digest)) { - errno = ENOBUFS; - return 1; + case PAKFIRE_DIGEST_SHA256: + memcpy(file->digests.sha256, digest, sizeof(file->digests.sha256)); + break; } - // Store type & length - d->type = type; - d->length = length; - - // Store digest - memcpy(d->digest, digest, d->length); - return 0; } -PAKFIRE_EXPORT int pakfire_file_set_hexdigest(struct pakfire_file* file, - enum pakfire_digests type, const char* hexdigest) { - const size_t digest_length = pakfire_digest_length(type); - if (!digest_length) { - errno = EINVAL; - return 1; - } +PAKFIRE_EXPORT char* pakfire_file_get_hexdigest( + struct pakfire_file* file, const enum pakfire_digests type) { + const unsigned char* digest = NULL; + size_t length = 0; - // Allocate a buffer for the binary representation of the digest - unsigned char* digest = alloca(digest_length); + // Fetch the digest + digest = pakfire_file_get_digest(file, type, &length); if (!digest) - return 1; - - // Convert from hex to binary - __pakfire_unhexlify(digest, digest_length, hexdigest); + return NULL; - return pakfire_file_set_digest(file, type, digest, digest_length); + return __pakfire_hexlify(digest, length); } static int pakfire_file_levels(struct pakfire_file* file) { diff --git a/src/libpakfire/include/pakfire/file.h b/src/libpakfire/include/pakfire/file.h index 276fb9a45..7429c8ca7 100644 --- a/src/libpakfire/include/pakfire/file.h +++ b/src/libpakfire/include/pakfire/file.h @@ -66,14 +66,12 @@ void pakfire_file_set_ctime(struct pakfire_file* file, time_t time); time_t pakfire_file_get_mtime(struct pakfire_file* file); void pakfire_file_set_mtime(struct pakfire_file* file, time_t time); -const unsigned char* pakfire_file_get_digest( - struct pakfire_file* file, enum pakfire_digests type, size_t* length); -const char* pakfire_file_get_hexdigest( - struct pakfire_file* file, enum pakfire_digests type); +const unsigned char* pakfire_file_get_digest(struct pakfire_file* file, + const enum pakfire_digests type, size_t* length); +char* pakfire_file_get_hexdigest(struct pakfire_file* file, + const enum pakfire_digests type); int pakfire_file_set_digest(struct pakfire_file* file, - enum pakfire_digests type, const unsigned char* digest, size_t length); -int pakfire_file_set_hexdigest(struct pakfire_file* file, - enum pakfire_digests type, const char* hexdigest); + const enum pakfire_digests type, const unsigned char* digest); struct pakfire_file* pakfire_file_parse_from_file(const char* list, unsigned int format); diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index 6f972f670..4b1d06c51 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -30,7 +30,6 @@ struct pakfire; enum pakfire_digests { - PAKFIRE_DIGEST_NONE = 0, PAKFIRE_DIGEST_SHA256 = 1, PAKFIRE_DIGEST_SHA512 = 2, }; diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index 37378e8c9..305db5927 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -96,7 +96,6 @@ global: pakfire_file_set_ctime; pakfire_file_set_digest; pakfire_file_set_group; - pakfire_file_set_hexdigest; pakfire_file_set_mode; pakfire_file_set_mtime; pakfire_file_set_path; diff --git a/src/libpakfire/package.c b/src/libpakfire/package.c index 6d358183e..735ca0f9f 100644 --- a/src/libpakfire/package.c +++ b/src/libpakfire/package.c @@ -404,7 +404,7 @@ static enum pakfire_digests pakfire_package_id2digest(Id id) { return PAKFIRE_DIGEST_SHA256; } - return PAKFIRE_DIGEST_NONE; + return 0; } PAKFIRE_EXPORT const unsigned char* pakfire_package_get_digest( @@ -586,7 +586,7 @@ PAKFIRE_EXPORT void pakfire_package_set_maintainer(struct pakfire_package* pkg, static int pakfire_package_make_cache_path(struct pakfire_package* pkg) { const char* filename = pakfire_package_get_filename(pkg); - enum pakfire_digests digest = PAKFIRE_DIGEST_NONE; + enum pakfire_digests digest; const char* hexdigest = pakfire_package_get_hexdigest(pkg, &digest); if (hexdigest && strlen(hexdigest) >= 3) @@ -1135,7 +1135,7 @@ PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags if (build_id) pakfire_package_dump_add_line(&string, _("Build ID"), build_id); - enum pakfire_digests digest = PAKFIRE_DIGEST_NONE; + enum pakfire_digests digest = 0; // Digest const char* hexdigest = pakfire_package_get_hexdigest(pkg, &digest); @@ -1147,9 +1147,6 @@ PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags case PAKFIRE_DIGEST_SHA256: pakfire_package_dump_add_line(&string, _("SHA256 Digest"), hexdigest); break; - - case PAKFIRE_DIGEST_NONE: - break; } // Source package diff --git a/src/libpakfire/repo.c b/src/libpakfire/repo.c index 0715dfbf9..17c19fca2 100644 --- a/src/libpakfire/repo.c +++ b/src/libpakfire/repo.c @@ -139,7 +139,7 @@ static int pakfire_repo_import_key(struct pakfire_repo* repo, const char* url) { // Try to download the key int r = pakfire_repo_retrieve(repo, NULL, url, path, - PAKFIRE_DIGEST_NONE, NULL, 0, PAKFIRE_TRANSFER_NOTEMP|PAKFIRE_TRANSFER_NOPROGRESS); + 0, NULL, 0, PAKFIRE_TRANSFER_NOTEMP|PAKFIRE_TRANSFER_NOPROGRESS); if (r) goto ERROR; @@ -307,7 +307,7 @@ static int pakfire_repo_download_database(struct pakfire_repo* repo, const char* pakfire_string_format(database_url, "repodata/%s", database); return pakfire_repo_retrieve(repo, title, database_url, cache_path, - PAKFIRE_DIGEST_NONE, NULL, 0, 0); + 0, NULL, 0, 0); } static int pakfire_repo_read_metadata(struct pakfire_repo* repo, const char* path, int refresh) { @@ -400,7 +400,7 @@ static int pakfire_repo_refresh_mirrorlist(struct pakfire_repo* repo, const int return pakfire_repo_retrieve(repo, NULL, repo->appdata->mirrorlist_url, repo->appdata->mirrorlist, - PAKFIRE_DIGEST_NONE, NULL, 0, PAKFIRE_TRANSFER_NOPROGRESS); + 0, NULL, 0, PAKFIRE_TRANSFER_NOPROGRESS); } static int pakfire_repo_refresh_metadata(struct pakfire_repo* repo, const int force) { @@ -415,7 +415,7 @@ static int pakfire_repo_refresh_metadata(struct pakfire_repo* repo, const int fo } int r = pakfire_repo_retrieve(repo, NULL, - "repodata/repomd.json", repo->appdata->metadata, PAKFIRE_DIGEST_NONE, + "repodata/repomd.json", repo->appdata->metadata, 0, NULL, 0, PAKFIRE_TRANSFER_NOPROGRESS); if (r) return r; diff --git a/src/libpakfire/request.c b/src/libpakfire/request.c index 040ce4a72..8607d9320 100644 --- a/src/libpakfire/request.c +++ b/src/libpakfire/request.c @@ -471,7 +471,7 @@ static int pakfire_request_add_url(struct pakfire_request* request, int action, // Download the file r = pakfire_downloader_retrieve(downloader, NULL, NULL, NULL, - url, path, PAKFIRE_DIGEST_NONE, NULL, 0, PAKFIRE_TRANSFER_NOTEMP); + url, path, 0, NULL, 0, PAKFIRE_TRANSFER_NOTEMP); if (r) goto ERROR; diff --git a/src/libpakfire/transaction.c b/src/libpakfire/transaction.c index fb47e5a47..7d551e283 100644 --- a/src/libpakfire/transaction.c +++ b/src/libpakfire/transaction.c @@ -691,7 +691,7 @@ static int pakfire_transaction_verify(struct pakfire_transaction* transaction, return 0; } - enum pakfire_digests digest_type = PAKFIRE_DIGEST_NONE; + enum pakfire_digests digest_type = 0; // Fetch digest from package const unsigned char* expected_digest = pakfire_package_get_digest(pkg, &digest_type); @@ -1169,7 +1169,7 @@ static int pakfire_transaction_download_package(struct pakfire_transaction* tran goto ERROR; } - enum pakfire_digests digest_type = PAKFIRE_DIGEST_NONE; + enum pakfire_digests digest_type = 0; // Retrieve package digest const unsigned char* digest = pakfire_package_get_digest(pkg, &digest_type); diff --git a/src/libpakfire/util.c b/src/libpakfire/util.c index d901e5bad..49fbe2fec 100644 --- a/src/libpakfire/util.c +++ b/src/libpakfire/util.c @@ -479,9 +479,6 @@ size_t pakfire_digest_length(enum pakfire_digests digest) { case PAKFIRE_DIGEST_SHA256: return 32; - - case PAKFIRE_DIGEST_NONE: - return 0; } return 0; diff --git a/tests/libpakfire/downloader.c b/tests/libpakfire/downloader.c index 94263ff17..e6618801f 100644 --- a/tests/libpakfire/downloader.c +++ b/tests/libpakfire/downloader.c @@ -38,7 +38,7 @@ static int test_simple(const struct test* t) { // Retrieve a file ASSERT_SUCCESS( pakfire_downloader_retrieve(d, NULL, NULL, NULL, DOWNLOAD_URL, DOWNLOAD_PATH, - PAKFIRE_DIGEST_NONE, NULL, 0, 0) + 0, NULL, 0, 0) ); // Everything passed @@ -61,13 +61,13 @@ static int test_retrieve_with_pending_transfers(const struct test* t) { // Add a transfer ASSERT_SUCCESS( pakfire_downloader_add_transfer(d, NULL, NULL, NULL, DOWNLOAD_URL, DOWNLOAD_PATH, - PAKFIRE_DIGEST_NONE, NULL, 0, 0) + 0, NULL, 0, 0) ); // Retrieve a file ASSERT_SUCCESS( pakfire_downloader_retrieve(d, NULL, NULL, NULL, DOWNLOAD_URL, DOWNLOAD_PATH, - PAKFIRE_DIGEST_NONE, NULL, 0, 0) + 0, NULL, 0, 0) ); @@ -103,7 +103,7 @@ static int test_retrieve_with_mirrors(const struct test* t) { // Retrieve a file which exists ASSERT_SUCCESS(pakfire_downloader_retrieve(d, NULL, m, - NULL, "beep-1.3-2.ip3.x86_64.pfm", DOWNLOAD_PATH, PAKFIRE_DIGEST_NONE, NULL, 0, 0)); + NULL, "beep-1.3-2.ip3.x86_64.pfm", DOWNLOAD_PATH, 0, NULL, 0, 0)); // Everything passed r = EXIT_SUCCESS; @@ -140,7 +140,7 @@ static int test_retrieve_online(const struct test* t) { ASSERT_SUCCESS( pakfire_downloader_retrieve(d, NULL, NULL, NULL, "https://mirror1.ipfire.org/releases/pakfire/pakfire-0.9.27.tar.gz", - DOWNLOAD_PATH, PAKFIRE_DIGEST_NONE, NULL, 0, 0) + DOWNLOAD_PATH, 0, NULL, 0, 0) ); // Everything passed