diff --git a/include/vieter_package.h b/include/vieter_package.h index c9a941e..179ff57 100644 --- a/include/vieter_package.h +++ b/include/vieter_package.h @@ -1,23 +1,21 @@ #ifndef VIETER_PACKAGE #define VIETER_PACKAGE +#include +#include +#include +#include + +#include +#include + typedef struct vieter_package vieter_package; -typedef enum vieter_package_error { - vieter_package_ok = 0, - vieter_package_unarchive_error = 1, - vieter_package_stat_error = 2 -} vieter_package_error; - -/* - * Allocate an empty package - */ -vieter_package *vieter_package_init(); - /* * Parse package file into something usable by libvieter. + * The pointer returned by this function will need to freed at a later point. */ -vieter_package_error vieter_package_read_archive(vieter_package *pkg, const char *pkg_path); +vieter_package *vieter_package_read_archive(const char *pkg_path); /* * Deallocate a package. diff --git a/src/package/vieter_package.c b/src/package/vieter_package.c index d1ef6c4..3bb19ba 100644 --- a/src/package/vieter_package.c +++ b/src/package/vieter_package.c @@ -1,29 +1,30 @@ -#include -#include -#include -#include - #include "vieter_package_internal.h" #include "sha256.h" +#define SMALL_BUFF_SIZE 128 + #define ADD_STRING(section, field) if (pkg_info->field != 0) { \ - size_to_be_written = snprintf(aux, small_buff_size, section, pkg_info->field); \ - if (size_to_be_written > small_buff_size) { \ - aux = realloc(aux, size_to_be_written + 1); \ - small_buff_size = size_to_be_written + 1; \ - snprintf(aux, small_buff_size, section, pkg_info->field); \ - } \ - if (buff_size < strlen(description) + small_buff_size + 1) { \ + snprintf(aux, SMALL_BUFF_SIZE, section, pkg_info->field); \ + if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \ description = realloc(description, buff_size * 2); \ buff_size *= 2; \ } \ strcat(description, aux); \ } - #define ADD_ARRAY(section, field) i = 0; if (pkg_info->field != NULL) { \ - ADD_STRING(section, field->array[i]); i++; \ + snprintf(aux, SMALL_BUFF_SIZE, section, pkg_info->field->array[i]); i++; \ + if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \ + description = realloc(description, buff_size * 2); \ + buff_size *= 2; \ + } \ + strcat(description, aux); \ while (pkg_info->field->array[i] != NULL) { \ - ADD_STRING("\n%s", field->array[i]); i++; \ + snprintf(aux, SMALL_BUFF_SIZE, "\n%s", pkg_info->field->array[i]); i++; \ + if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \ + description = realloc(description, buff_size * 2); \ + buff_size *= 2; \ + } \ + strcat(description, aux); \ } \ } @@ -40,7 +41,7 @@ vieter_package *vieter_package_init() { return calloc(sizeof(vieter_package_info), 1); } -vieter_package_error vieter_package_read_archive(vieter_package *pkg, const char *pkg_path) { +vieter_package *vieter_package_read_archive(const char *pkg_path) { struct archive *a = archive_read_new(); struct archive_entry *entry = archive_entry_new(); @@ -57,7 +58,7 @@ vieter_package_error vieter_package_read_archive(vieter_package *pkg, const char // Exit early if we weren't able to successfully open the archive for reading if (r != ARCHIVE_OK) { - return vieter_package_unarchive_error; + return NULL; } int compression_code = archive_filter_code(a, 0); @@ -103,9 +104,7 @@ vieter_package_error vieter_package_read_archive(vieter_package *pkg, const char struct stat stats; if (stat(pkg_path, &stats) != 0) { - // errno is set if stat() fails; the calling function should check - // the value of errno in case vieter_package_stat_error is returned - return vieter_package_stat_error; + return NULL; } pkg_info->csize = stats.st_size; @@ -113,31 +112,31 @@ vieter_package_error vieter_package_read_archive(vieter_package *pkg, const char archive_read_free(a); // Create final return value + vieter_package *pkg = vieter_package_init(); pkg->path = strdup(pkg_path); pkg->info = pkg_info; pkg->files = files; pkg->compression = compression_code; - return vieter_package_ok; + return pkg; } void vieter_package_sha256sum(vieter_package *pkg, char *res) { FILE *f = fopen(pkg->path, "r"); - // Try to read 100KiB at a time - unsigned char *in = malloc(102400); - // Actual number of bytes read - size_t read_size; + fseek(f, 0, SEEK_END); + size_t size = ftell(f); + rewind(f); + unsigned char *in = malloc(size); + fread(in, 1, size, f); + fclose(f); + unsigned char hash[32]; SHA256_CTX *ctx = malloc(sizeof(SHA256_CTX)); - sha256_init(ctx); - while ((read_size = fread(in, 1, 102400, f)) != 0) { - sha256_update(ctx, in, read_size); - } - unsigned char hash[SHA256_BLOCK_SIZE]; + sha256_init(ctx); + sha256_update(ctx, in, size); sha256_final(ctx, hash); - fclose(f); free(in); free(ctx); @@ -148,8 +147,8 @@ void vieter_package_sha256sum(vieter_package *pkg, char *res) { unsigned int half_byte = 0; int j = 0; - // We advance 2 bytes in the string for every one byte of the hash - for (int i = 0; i < SHA256_BLOCK_SIZE; i++) { + // We advance in the string 2 bytes for every one byte of the hash + for (int i = 0; i < 32; i++) { // We transform the first half byte into the second character to keep // each byte from becoming reversed in the final string half_byte = hash[i] & 0b1111; @@ -171,32 +170,19 @@ void vieter_package_sha256sum(vieter_package *pkg, char *res) { res[j] = '\0'; } - - char *vieter_package_to_description(vieter_package *pkg) { vieter_package_info *pkg_info = pkg->info; size_t buff_size = 1024; - int small_buff_size = 128; - int size_to_be_written; - char *aux = malloc(sizeof(char) * small_buff_size); + char aux[SMALL_BUFF_SIZE]; char *description = malloc(sizeof(char) * buff_size); // Helper variable for ADD_ARRAY macro int i; // special case for FILENAME // assuming .pkg.tar.zst; other formats are valid, this should account for that - size_to_be_written = snprintf(aux, small_buff_size, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name, + snprintf(aux, SMALL_BUFF_SIZE, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name, pkg_info->version, pkg_info->arch); - - // We neither want to let an arbritrarily long input to overflow the buffer - // nor to truncate perfectly valid inputs - if (size_to_be_written > small_buff_size) { - aux = realloc(aux, size_to_be_written + 1); - small_buff_size = size_to_be_written + 1; - snprintf(aux, small_buff_size, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name, - pkg_info->version, pkg_info->arch); - } strcpy(description, aux); ADD_STRING("\n\n%%NAME%%\n%s", name); @@ -207,11 +193,11 @@ char *vieter_package_to_description(vieter_package *pkg) { ADD_STRING("\n\n%%CSIZE%%\n%ld", csize); ADD_STRING("\n\n%%ISIZE%%\n%ld", size); - char checksum[SHA256_BLOCK_SIZE * 2 + 1]; + char checksum[65]; vieter_package_sha256sum(pkg, checksum); - snprintf(aux, small_buff_size, "\n\n%%SHA256SUM%%\n%s", checksum); - if (buff_size < strlen(description) + small_buff_size + 1) { + snprintf(aux, SMALL_BUFF_SIZE, "\n\n%%SHA256SUM%%\n%s", checksum); + if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { description = realloc(description, buff_size * 2); buff_size *= 2; } @@ -230,7 +216,8 @@ char *vieter_package_to_description(vieter_package *pkg) { ADD_ARRAY("\n\n%%MAKEDEPENDS%%\n%s", makedepends); ADD_ARRAY("\n\n%%CHECKDEPENDS%%\n%s", checkdepends); - strcat(description, "\n\n"); + snprintf(aux, SMALL_BUFF_SIZE, "\n\n"); + strcat(description, aux); return description; } diff --git a/src/package/vieter_package_dynarray.c b/src/package/vieter_package_dynarray.c index 6da07ee..2cc20b6 100644 --- a/src/package/vieter_package_dynarray.c +++ b/src/package/vieter_package_dynarray.c @@ -12,18 +12,12 @@ void vieter_package_dynarray_add(vieter_package_dynarray *da, const char *s) { // An empty vieter_package_dynarray does not have an allocated internal array yet if (da->size == 0) { da->array = malloc(sizeof(char*) * da->capacity); - - // Initialise all char*'s to 0 so array[i] == NULL can be used to see if field is empty - memset(da->array, 0, sizeof(char*) * da->capacity); } // Double array size if it's full else if (da->size == da->capacity) { // if the realloc fails, access to memory in da->array is lost da->array = realloc(da->array, sizeof(char*) * da->capacity * 2); da->capacity *= 2; - - // Same as the previous memset, but only for newly allocated pointers - memset(da->array + da->size, 0, sizeof(char*) * da->capacity / 2); } da->array[da->size] = strdup(s); diff --git a/test/package/test_package.c b/test/package/test_package.c index 3c8b249..5bbda26 100644 --- a/test/package/test_package.c +++ b/test/package/test_package.c @@ -39,9 +39,8 @@ void test_info_parse() { } void test_pkg_read_archive_files() { - vieter_package *pkg = vieter_package_init(); - vieter_package_error e = vieter_package_read_archive(pkg, "./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst"); - TEST_ASSERT_(e == vieter_package_ok, "failure parsing pkg archive"); + vieter_package *pkg = vieter_package_read_archive("./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst"); + TEST_ASSERT_(pkg != NULL, "failure parsing pkg archive"); FILE *f = fopen("./test/package/files", "r"); TEST_ASSERT_(f != NULL, "could not find test files file in ./test/package"); @@ -59,12 +58,12 @@ void test_pkg_read_archive_files() { TEST_CHECK(pkg->compression = 14); vieter_package_free(&pkg); + } void test_pkg_read_archive_desc() { - vieter_package *pkg = vieter_package_init(); - vieter_package_error e = vieter_package_read_archive(pkg, "./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst"); - TEST_ASSERT_(e == vieter_package_ok, "failure parsing pkg archive"); + vieter_package *pkg = vieter_package_read_archive("./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst"); + TEST_ASSERT_(pkg != NULL, "failure parsing pkg archive"); char *description = vieter_package_to_description(pkg);