Refactor package module into C #6
2 changed files with 33 additions and 28 deletions
|
|
@ -1,16 +1,10 @@
|
||||||
#ifndef VIETER_PACKAGE
|
#ifndef VIETER_PACKAGE
|
||||||
#define VIETER_PACKAGE
|
#define VIETER_PACKAGE
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <archive.h>
|
|
||||||
#include <archive_entry.h>
|
|
||||||
|
|
||||||
typedef struct vieter_package vieter_package;
|
typedef struct vieter_package vieter_package;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse package file into something usable by libvieter.
|
* Parse package file into something usable by libvieter.
|
||||||
* The pointer returned by this function will need to freed at a later point.
|
* The pointer returned by this function will need to freed at a later point.
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,29 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
|
||||||
#include "vieter_package_internal.h"
|
#include "vieter_package_internal.h"
|
||||||
#include "sha256.h"
|
#include "sha256.h"
|
||||||
|
|
|||||||
|
|
||||||
#define SMALL_BUFF_SIZE 128
|
|
||||||
|
|
||||||
#define ADD_STRING(section, field) if (pkg_info->field != 0) { \
|
#define ADD_STRING(section, field) if (pkg_info->field != 0) { \
|
||||||
snprintf(aux, SMALL_BUFF_SIZE, section, pkg_info->field); \
|
size_to_be_written = snprintf(aux, small_buff_size, section, pkg_info->field); \
|
||||||
if (buff_size < strlen(description) + SMALL_BUFF_SIZE + 1) { \
|
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) { \
|
||||||
description = realloc(description, buff_size * 2); \
|
description = realloc(description, buff_size * 2); \
|
||||||
buff_size *= 2; \
|
buff_size *= 2; \
|
||||||
} \
|
} \
|
||||||
strcat(description, aux); \
|
strcat(description, aux); \
|
||||||
}
|
}
|
||||||
|
Jef Roosens
commented
This check is not safe, the dynarray code doesn't make any guarantees about empty fields being NULL, they're simply malloc'ed and not initialised. This check is not safe, the dynarray code doesn't make any guarantees about empty fields being NULL, they're simply malloc'ed and not initialised.
|
|||||||
|
|
||||||
#define ADD_ARRAY(section, field) i = 0; if (pkg_info->field != NULL) { \
|
#define ADD_ARRAY(section, field) i = 0; if (pkg_info->field != NULL) { \
|
||||||
snprintf(aux, SMALL_BUFF_SIZE, section, pkg_info->field->array[i]); i++; \
|
ADD_STRING(section, 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) { \
|
while (pkg_info->field->array[i] != NULL) { \
|
||||||
snprintf(aux, SMALL_BUFF_SIZE, "\n%s", pkg_info->field->array[i]); i++; \
|
ADD_STRING("\n%s", 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); \
|
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,19 +169,32 @@ void vieter_package_sha256sum(vieter_package *pkg, char *res) {
|
||||||
res[j] = '\0';
|
res[j] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *vieter_package_to_description(vieter_package *pkg) {
|
char *vieter_package_to_description(vieter_package *pkg) {
|
||||||
vieter_package_info *pkg_info = pkg->info;
|
vieter_package_info *pkg_info = pkg->info;
|
||||||
|
|
||||||
|
Jef Roosens
commented
This should also use This should also use `SMALL_BUFF_SIZE` I think, just for consistency.
|
|||||||
size_t buff_size = 1024;
|
size_t buff_size = 1024;
|
||||||
char aux[SMALL_BUFF_SIZE];
|
int small_buff_size = 128;
|
||||||
|
int size_to_be_written;
|
||||||
|
char *aux = malloc(sizeof(char) * small_buff_size);
|
||||||
char *description = malloc(sizeof(char) * buff_size);
|
char *description = malloc(sizeof(char) * buff_size);
|
||||||
// Helper variable for ADD_ARRAY macro
|
// Helper variable for ADD_ARRAY macro
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
Jef Roosens
commented
Vieter doesn't only supports zstd-compressed archives. Currently it also accepts xz- or gzip-compressed archives, so this should be accounted for. This choice was made noteably because Archlinux ARM uses xz-compressed archives instead of zstd. Vieter doesn't only supports zstd-compressed archives. Currently it also accepts xz- or gzip-compressed archives, so this should be accounted for.
This choice was made noteably because Archlinux ARM uses xz-compressed archives instead of zstd.
|
|||||||
// special case for FILENAME
|
// special case for FILENAME
|
||||||
// assuming .pkg.tar.zst; other formats are valid, this should account for that
|
// assuming .pkg.tar.zst; other formats are valid, this should account for that
|
||||||
snprintf(aux, SMALL_BUFF_SIZE, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name,
|
size_to_be_written = snprintf(aux, small_buff_size, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst", pkg_info->name,
|
||||||
pkg_info->version, pkg_info->arch);
|
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);
|
strcpy(description, aux);
|
||||||
|
|
||||||
ADD_STRING("\n\n%%NAME%%\n%s", name);
|
ADD_STRING("\n\n%%NAME%%\n%s", name);
|
||||||
|
|
@ -216,8 +228,7 @@ char *vieter_package_to_description(vieter_package *pkg) {
|
||||||
ADD_ARRAY("\n\n%%MAKEDEPENDS%%\n%s", makedepends);
|
ADD_ARRAY("\n\n%%MAKEDEPENDS%%\n%s", makedepends);
|
||||||
ADD_ARRAY("\n\n%%CHECKDEPENDS%%\n%s", checkdepends);
|
ADD_ARRAY("\n\n%%CHECKDEPENDS%%\n%s", checkdepends);
|
||||||
|
|
||||||
snprintf(aux, SMALL_BUFF_SIZE, "\n\n");
|
strcat(description, "\n\n");
|
||||||
strcat(description, aux);
|
|
||||||
|
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in a new issue
General note for
snprintfusage: what happens if the value is larger than the buffer? Is it simply cut off? Cuz if so, we shouldn't be making assumptions about the length of the input.I used
snprintfbecause I didn't want to risk any buffer overflows, but it can truncate perfectly valid inputs if they are long enough (e.g. very long url). I'll turnauxinto a malloc'd string and use the return value ofsnprintfto reallocate memory as is necessary without any overflows.