From fcad0d7280164e60a3e869c13ab338c104f4bb85 Mon Sep 17 00:00:00 2001 From: Jaromil Date: Sun, 15 Dec 2024 20:18:18 +0100 Subject: [PATCH] feat: introduce muntargz extract api function --- src/muntar.c | 23 ++++++++++++++++++++--- src/muntar.h | 4 ++++ test/muntar.bats | 33 ++++++++++++++++++++++++++++----- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/muntar.c b/src/muntar.c index b4d43e5..09f89bf 100644 --- a/src/muntar.c +++ b/src/muntar.c @@ -158,7 +158,7 @@ static int mtar_rewind(mtar_t *tar) { #include // for mkdir(2) -#if defined(_WIN32 +#if defined(_WIN32) #include #define makedir(path) CreateDirectory(path, NULL) #else @@ -237,13 +237,30 @@ int untar_to_path(const char *path, const uint8_t *buf, return(MTAR_ESUCCESS); } +#if !defined(NOGUNZIP) // gunzip and untar all in one #include +#define DECOMPRESSED_SIZE_RATIO 6 // raise this on errors int untargz_to_path(const char *path, const uint8_t *buf, const unsigned int len) { - return(0); + int res; + unsigned int destlen = len*6; + uint8_t *dest = malloc(destlen); + res = tinf_gzip_uncompress(dest,&destlen,buf,len); + // fprintf(stdout,"Compressed source length: %u\n",len); + // fprintf(stdout,"Uncompressed destination length: %u\n",destlen); + // fprintf(stdout,"Max buffer length: %u\n",len*6); + // fprintf(stdout,"Multiplier ratio: %u\n",destlen/len); + if(res != TINF_OK) { + fprintf(stderr,"Error in gunzip decompression (untargz_to_path)\n"); + free(dest); + exit(res); + } + res = untar_to_path(path, dest, destlen); + free(dest); + return(res); } - +#endif int mtar_load(mtar_t *tar, const char *name, const uint8_t *buf, size_t size) { diff --git a/src/muntar.h b/src/muntar.h index f92be95..46b34e6 100644 --- a/src/muntar.h +++ b/src/muntar.h @@ -32,6 +32,10 @@ // used by extract_embeddings(char *tmpdir) int untar_to_path(const char *path, const uint8_t *buf, const unsigned int len); +#if !defined(NOGUNZIP) +int untargz_to_path(const char *path, + const uint8_t *buf, const unsigned int len); +#endif enum { MTAR_ESUCCESS = 0, diff --git a/test/muntar.bats b/test/muntar.bats index 0a4665a..e78c344 100644 --- a/test/muntar.bats +++ b/test/muntar.bats @@ -40,7 +40,7 @@ int main(int argc, char **argv) { exit(0); } EOF - gcc -o muntar_list -I ${R}/src \ + gcc -o muntar_list -DNOGUNZIP -I ${R}/src \ ${R}/src/muntar.c ${R}/src/io.c examples.c muntar_list.c run ./muntar_list assert_success @@ -48,7 +48,6 @@ EOF assert_line --partial "examples/donut.c (743 bytes)" } - @test "muntar extract contents" { cat << EOF > muntar_extract.c #include @@ -63,13 +62,11 @@ int main(int argc, char **argv) { exit(res); } EOF - gcc -o muntar_extract -I ${R}/src \ + gcc -o muntar_extract -DNOGUNZIP -I ${R}/src \ ${R}/src/muntar.c examples.c muntar_extract.c run ./muntar_extract ${TMP}/extracted >&3 cat ${TMP}/extracted/examples/donut.c assert_success - # assert_file_size_equals ${TMP}/extracted/examples/donut.c \ - # `ls -l ${R}/examples/donut.c | cut -d' ' -f5` l=`sha256sum ${TMP}/extracted/examples/donut.c | cut -d' ' -f1` r=`sha256sum ${R}/examples/donut.c | cut -d' ' -f1` assert_equal $l $r @@ -125,3 +122,29 @@ EOF r=`sha256sum examples.tar | cut -d' ' -f1` assert_equal $l $r } + + +@test "muntargz extract contents" { + cat << EOF > muntargz_extract.c +#include +#include +#include +extern unsigned char examples_tar_gz[]; +extern unsigned int examples_tar_gz_len; +int main(int argc, char **argv) { + int res; + fprintf(stderr,"extract to %s\n",argv[1]); + res = untargz_to_path(argv[1], examples_tar_gz, examples_tar_gz_len); + exit(res); +} +EOF + gcc -o muntargz_extract -I ${R}/src \ + ${R}/src/tinfgzip.c ${R}/src/tinflate.c ${R}/src/muntar.c \ + examples_gzip.c muntargz_extract.c + run ./muntargz_extract ${TMP}/extractgz + >&3 cat ${TMP}/extractgz/examples/donut.c + assert_success + l=`sha256sum ${TMP}/extractgz/examples/donut.c | cut -d' ' -f1` + r=`sha256sum ${R}/examples/donut.c | cut -d' ' -f1` + assert_equal $l $r +}