]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
archive: Remove any nested functions from reading files
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 12 Apr 2023 13:55:35 +0000 (13:55 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 12 Apr 2023 13:55:35 +0000 (13:55 +0000)
Nested functions require an executable stack which we want to avoid.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index 019438f62bfeab7cd130d8f3c351078f903465ca..880c21707bba1cb56393681f412b5cd6485b14d9 100644 (file)
@@ -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)