From: Michael Tremer Date: Thu, 18 Mar 2021 18:46:22 +0000 (+0000) Subject: compress: Move cookie onto heap X-Git-Tag: 0.9.28~1285^2~516 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=990184213578334f45f463942d970df916b7ba71;p=pakfire.git compress: Move cookie onto heap Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/compress.c b/src/libpakfire/compress.c index 726b57dd6..bea2095bf 100644 --- a/src/libpakfire/compress.c +++ b/src/libpakfire/compress.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -212,17 +213,50 @@ static ssize_t xz_write(void* data, const char* buffer, size_t size) { static int xz_close(void* data) { struct xz_cookie* cookie = (struct xz_cookie*)data; + if (!cookie) + return -1; + + if (cookie->mode == 'w') { + while (1) { + cookie->stream.next_out = cookie->buffer; + cookie->stream.avail_out = sizeof(cookie->buffer); + + lzma_ret ret = lzma_code(&cookie->stream, LZMA_FINISH); + if (ret != LZMA_OK && ret != LZMA_STREAM_END) + return -1; + + size_t bytes_to_write = sizeof(cookie->buffer) - cookie->stream.avail_out; + if (bytes_to_write) { + size_t bytes_written = fwrite(cookie->buffer, 1, bytes_to_write, cookie->f); + + if (bytes_written != bytes_to_write) + return -1; + } + + if (ret == LZMA_STREAM_END) + break; + } + } - // Free the deocder lzma_end(&cookie->stream); // Close input file - fclose(cookie->f); + int r = fclose(cookie->f); + free(cookie); - return 0; + return r; } +static cookie_io_functions_t xz_functions = { + .read = xz_read, + .write = xz_write, + .seek = NULL, + .close = xz_close, +}; + FILE* pakfire_xzfopen(FILE* f, const char* mode) { + lzma_ret ret; + if (!f) { errno = EBADFD; return NULL; @@ -233,39 +267,30 @@ FILE* pakfire_xzfopen(FILE* f, const char* mode) { return NULL; } - struct xz_cookie cookie = { - .f = f, - .mode = *mode, - .stream = LZMA_STREAM_INIT, - .done = 0, - }; + struct xz_cookie* cookie = calloc(1, sizeof(*cookie)); + if (!cookie) + return NULL; - lzma_ret ret; + cookie->f = f; + cookie->mode = *mode; - // Initialise the encoder/decoder - switch (cookie.mode) { + switch (cookie->mode) { case 'r': - ret = lzma_stream_decoder(&cookie.stream, UINT64_MAX, 0); + ret = lzma_stream_decoder(&cookie->stream, UINT64_MAX, 0); break; case 'w': - ret = lzma_easy_encoder(&cookie.stream, XZ_COMPRESSION_LEVEL, LZMA_CHECK_SHA256); + ret = lzma_easy_encoder(&cookie->stream, XZ_COMPRESSION_LEVEL, LZMA_CHECK_SHA256); break; default: errno = ENOTSUP; + free(cookie); return NULL; } if (ret != LZMA_OK) return NULL; - cookie_io_functions_t functions = { - .read = xz_read, - .write = xz_write, - .seek = NULL, - .close = xz_close, - }; - - return fopencookie(&cookie, mode, functions); + return fopencookie(cookie, mode, xz_functions); }