]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Refactor parser for legacy chksums format
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 13 Jul 2021 13:25:30 +0000 (13:25 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 13 Jul 2021 13:25:30 +0000 (13:25 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index 21e496e9cdab2e0e7614b7e20ab995c08c029be6..a22a7b1e2c5fa72f39ead32400fe8ab136b02269 100644 (file)
@@ -531,69 +531,6 @@ CLEANUP:
        return r;
 }
 
-static int pakfire_archive_parse_entry_checksums(struct pakfire_archive* archive,
-               struct archive* a, struct archive_entry* e) {
-       char* data;
-       size_t data_size;
-
-       int r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, e, &data, &data_size);
-       if (r)
-               return 1;
-
-       // Empty file
-       if (data_size <= 0)
-               return 1;
-
-       // Terminate string.
-       data[data_size] = '\0';
-
-       const char* filename = NULL;
-       const char* checksum = NULL;
-
-       char* p = data;
-       while (*p) {
-               // Filename starts here
-               filename = p;
-
-               // Find end of filename
-               while (!isspace(*p))
-                       p++;
-
-               // Terminate filename
-               *p++ = '\0';
-
-               // Skip any spaces
-               while (isspace(*p))
-                       p++;
-
-               // Checksum starts here
-               checksum = p;
-
-               // Find end of checksum
-               while (!isspace(*p))
-                       p++;
-
-               // Terminate the checksum
-               *p++ = '\0';
-
-               // Add new checksum object
-               if (filename && checksum) {
-                       r = pakfire_archive_add_chksum(archive, filename, checksum, NULL);
-                       if (r)
-                               goto ERROR;
-               }
-
-               // Eat up any space before next thing starts
-               while (isspace(*p))
-                       p++;
-       }
-
-ERROR:
-       free(data);
-
-       return 0;
-}
-
 /*
        This function tries (very easily) to find out whether something is a valid
        archive or not.
@@ -1144,10 +1081,115 @@ ERROR:
        return r;
 }
 
-static int pakfire_archive_load_checksums_legacy(struct pakfire_archive* archive) {
+static int pakfire_archive_load_checksums_legacy_line(
+               struct pakfire_archive* archive, char* line) {
+       char path[PATH_MAX] = "";
+       char hexdigest[LINE_MAX] = "";
+       char* tok = NULL;
+
+       unsigned int i = 0;
+       int r = 1;
+
+       char* word = strtok_r(line, " ", &tok);
+       while (word) {
+               switch (i) {
+                       // path
+                       case 0:
+                               r = pakfire_string_set(path, word);
+                               if (r < 0)
+                                       return r;
+                               break;
+
+                       // hexdigest
+                       case 1:
+                               r = pakfire_string_set(hexdigest, word);
+                               if (r < 0)
+                                       return r;
+                               break;
+
+                       default:
+                               ERROR(archive->pakfire, "Invalid line in checksums:\n%s\n", line);
+                               r = 1;
+                               return r;
+               }
+
+               word = strtok_r(NULL, " ", &tok);
+               i++;
+       }
+
+       // Check if we have input for path and hexdigest
+       if (!*path || !*hexdigest) {
+               errno = EINVAL;
+               return r;
+       }
+
+       unsigned char digest[EVP_MAX_MD_SIZE];
+
+       // Convert hexdigest to digest
+       r = pakfire_unhexlify(digest, sizeof(digest), hexdigest);
+       if (r)
+               return r;
+
+       // Add a chksum object
+       r = pakfire_archive_add_chksum(archive, path, digest, NULL);
+       if (r)
+               return r;
+
+       // Success
        return 0;
 }
 
+static int pakfire_archive_load_checksums_legacy(struct pakfire_archive* archive) {
+       char* buffer = NULL;
+       size_t length = 0;
+
+       // Find chksums
+       int r = open_archive_and_read(archive, "chksums", &buffer, &length);
+       if (r)
+               return r;
+
+       // Empty file
+       if (!length) {
+               ERROR(archive->pakfire, "Checksums file was unexpectedly empty\n");
+               return 1;
+       }
+
+       char line[LINE_MAX];
+       char* l = line;
+
+       // Split the input into lines and call pakfire_archive_load_checksums_legacy_line
+       for (char* p = buffer; (size_t)(p - buffer) < length; p++) {
+               if (*p == '\n' || p == (buffer + length)) {
+                       // Terminate line
+                       *l = '\0';
+
+                       // Process the line
+                       r = pakfire_archive_load_checksums_legacy_line(archive, line);
+                       if (r)
+                               goto ERROR;
+
+                       // Reset line pointer
+                       l = line;
+
+                       continue;
+               }
+
+               // Copy character to line
+               *l++ = *p;
+
+               // Check if line has enough space
+               if ((size_t)(l - line) >= sizeof(line)) {
+                       errno = ENOBUFS;
+                       goto ERROR;
+               }
+       }
+
+ERROR:
+       if (buffer)
+               free(buffer);
+       return r;
+}
+
 static int pakfire_archive_load_checksums(struct pakfire_archive* archive) {
        // Do nothing if the list has already been loaded
        if (!STAILQ_EMPTY(&archive->chksums))