From: Michael Tremer Date: Wed, 12 Apr 2023 13:55:35 +0000 (+0000) Subject: archive: Remove any nested functions from reading files X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=94e71d7a7120900100e91fc54ec2d5c763ab2da3;p=people%2Fstevee%2Fpakfire.git archive: Remove any nested functions from reading files Nested functions require an executable stack which we want to avoid. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index 019438f6..880c2170 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -577,11 +577,17 @@ struct pakfire_archive_read_cookie { // A reference to the archive struct pakfire_archive* archive; + // The path we are reading + char path[PATH_MAX]; + // A copy of the underlying file descriptor FILE* f; // The opened archive struct archive* a; + + // File handle opened by the cookie + FILE* __f; }; static ssize_t __pakfire_archive_cookie_read(void* c, char* buffer, size_t size) { @@ -612,9 +618,41 @@ static cookie_io_functions_t pakfire_archive_read_functions = { .close = __pakfire_archive_cookie_close, }; +// Tries to find a matching file in the archive +static int __pakfire_archive_read_filter(struct pakfire* pakfire, struct archive* a, + struct archive_entry* e, void* data) { + struct pakfire_archive_read_cookie* cookie = (struct pakfire_archive_read_cookie*)data; + + // Fetch path + const char* p = archive_entry_pathname(e); + if (!p) + return PAKFIRE_WALK_ERROR; + + // We found a match + if (strcmp(cookie->path, p) == 0) + return PAKFIRE_WALK_DONE; + + // Otherwise we skip the file + return PAKFIRE_WALK_SKIP; +} + +// Reads a matching file into memory +static int __pakfire_archive_read(struct pakfire* pakfire, struct archive* a, + struct archive_entry* e, void* data) { + struct pakfire_archive_read_cookie* cookie = (struct pakfire_archive_read_cookie*)data; + + // Create a file descriptor + cookie->__f = fopencookie(cookie, "r", pakfire_archive_read_functions); + if (!cookie->__f) { + ERROR(pakfire, "Could not open /%s: %m\n", cookie->path); + return PAKFIRE_WALK_ERROR; + } + + return PAKFIRE_WALK_DONE; +} + PAKFIRE_EXPORT FILE* pakfire_archive_read(struct pakfire_archive* archive, const char* path) { struct pakfire_archive_read_cookie* cookie = NULL; - FILE* f = NULL; int r; // Check if path is absolute @@ -638,6 +676,13 @@ PAKFIRE_EXPORT FILE* pakfire_archive_read(struct pakfire_archive* archive, const // Store a reference to the archive cookie->archive = pakfire_archive_ref(archive); + // Store the path + r = pakfire_string_set(cookie->path, path); + if (r) { + ERROR(archive->pakfire, "Could not set path: %m\n"); + goto ERROR; + } + // Clone the archive file descriptor to read the file independently cookie->f = pakfire_archive_clone_file(archive); if (!cookie->f) { @@ -651,47 +696,14 @@ PAKFIRE_EXPORT FILE* pakfire_archive_read(struct pakfire_archive* archive, const if (!cookie->a) goto ERROR; - // Tries to find a matching file in the archive - int __pakfire_archive_read_filter(struct pakfire* pakfire, struct archive* a, - struct archive_entry* e, void* data) { - // Stop reading the archive after we have found our file - if (f) - return PAKFIRE_WALK_END; - - // Fetch path - const char* p = archive_entry_pathname(e); - if (!p) - return PAKFIRE_WALK_ERROR; - - // We found a match - if (strcmp(path, p) == 0) - return PAKFIRE_WALK_OK; - - // Otherwise we skip the file - return PAKFIRE_WALK_SKIP; - } - - // Reads a matching file into memory - int __pakfire_archive_read(struct pakfire* pakfire, struct archive* a, - struct archive_entry* e, void* data) { - // Create a file descriptor - f = fopencookie(cookie, "r", pakfire_archive_read_functions); - if (!f) { - ERROR(pakfire, "Could not open /%s: %m\n", path); - return PAKFIRE_WALK_ERROR; - } - - return PAKFIRE_WALK_DONE; - } - // Walk through the archive r = pakfire_walk(archive->pakfire, cookie->a, - __pakfire_archive_read, __pakfire_archive_read_filter, NULL); + __pakfire_archive_read, __pakfire_archive_read_filter, cookie); if (r) goto ERROR; // Nothing found - if (!f) { + if (!cookie->__f) { ERROR(archive->pakfire, "Could not find /%s\n", path); // No such file or directory @@ -699,7 +711,7 @@ PAKFIRE_EXPORT FILE* pakfire_archive_read(struct pakfire_archive* archive, const goto ERROR; } - return f; + return cookie->__f; ERROR: if (cookie)