From: Michael Tremer Date: Tue, 13 Jul 2021 13:25:30 +0000 (+0000) Subject: archive: Refactor parser for legacy chksums format X-Git-Tag: 0.9.28~1029 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c4251babaf3ef491571d22da6f72cac4e6b1e089;p=pakfire.git archive: Refactor parser for legacy chksums format Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index 21e496e9c..a22a7b1e2 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -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))