From 1e0e318b510dcd886b303f23f12652b60f1eb5b9 Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Tue, 02 May 2023 20:06:51 -0400 Subject: gzip: Fix flushing deflate() apparently must be called with avail_in=0 and Z_FINISH after processing all input, not with Z_FINISH on the last non-empty input buffer. --- diff --git a/src/gzip.c b/src/gzip.c index 736cbd7..1263ffc 100644 --- a/src/gzip.c +++ b/src/gzip.c @@ -174,8 +174,8 @@ opkg_opk_gzip_read(struct opkg_opk_gzip *gzip, void *record) } } -int -opkg_opk_gzip_write(struct opkg_opk_gzip *gzip, void *record, size_t size, +static int +_opkg_opk_gzip_write(struct opkg_opk_gzip *gzip, void *record, size_t size, int last) { /* Sanity check */ @@ -223,6 +223,16 @@ opkg_opk_gzip_write(struct opkg_opk_gzip *gzip, void *record, size_t size, } int +opkg_opk_gzip_write(struct opkg_opk_gzip *gzip, void *record, size_t size) +{ + if (_opkg_opk_gzip_write(gzip, record, size, 0) == OPKG_OPK_OK) { + return OPKG_OPK_OK; + } else { + return OPKG_OPK_ERROR; + } +} + +int opkg_opk_gzip_free(struct opkg_opk_gzip *gzip) { int ret; @@ -233,6 +243,9 @@ opkg_opk_gzip_free(struct opkg_opk_gzip *gzip) ret = OPKG_OPK_ERROR; } } else { + if (_opkg_opk_gzip_write(gzip, NULL, 0, 1) != OPKG_OPK_END) { + ret = OPKG_OPK_ERROR; + } if (deflateEnd(&gzip->stream) != Z_OK) { ret = OPKG_OPK_ERROR; } diff --git a/src/gzip.h b/src/gzip.h index 437b855..ecf659a 100644 --- a/src/gzip.h +++ b/src/gzip.h @@ -66,8 +66,7 @@ int opkg_opk_gzip_read(struct opkg_opk_gzip *gzip, void *record); int -opkg_opk_gzip_write(struct opkg_opk_gzip *gzip, void *record, size_t size, - int last); +opkg_opk_gzip_write(struct opkg_opk_gzip *gzip, void *record, size_t size); /* * Frees a decompression structure. diff --git a/src/ustar.c b/src/ustar.c index 88ae7b6..13e7621 100644 --- a/src/ustar.c +++ b/src/ustar.c @@ -334,7 +334,7 @@ opkg_opk_ustar_write_header(struct opkg_opk_ustar *ustar, sprintf(ustar->header.chksum, "%o", chksum); if (opkg_opk_gzip_write(ustar->gzip, &ustar->header, - OPKG_OPK_USTAR_RECORD_SIZE, 0) != OPKG_OPK_OK) { + OPKG_OPK_USTAR_RECORD_SIZE) != OPKG_OPK_OK) { return OPKG_OPK_ERROR; } @@ -365,7 +365,7 @@ opkg_opk_ustar_write_data(struct opkg_opk_ustar *ustar, size_t size) /* Write to gzip stream. */ if (opkg_opk_gzip_write(ustar->gzip, ustar->record, - OPKG_OPK_USTAR_RECORD_SIZE, 0) != OPKG_OPK_OK) { + OPKG_OPK_USTAR_RECORD_SIZE) != OPKG_OPK_OK) { return OPKG_OPK_ERROR; } @@ -378,9 +378,9 @@ opkg_opk_ustar_write_trailer(struct opkg_opk_ustar *ustar) { memset(ustar->record, 0, OPKG_OPK_USTAR_RECORD_SIZE); if (opkg_opk_gzip_write(ustar->gzip, ustar->record, - OPKG_OPK_USTAR_RECORD_SIZE, 0) != OPKG_OPK_OK || + OPKG_OPK_USTAR_RECORD_SIZE) != OPKG_OPK_OK || opkg_opk_gzip_write(ustar->gzip, ustar->record, - OPKG_OPK_USTAR_RECORD_SIZE, 1) != OPKG_OPK_END) + OPKG_OPK_USTAR_RECORD_SIZE) != OPKG_OPK_OK) { return OPKG_OPK_ERROR; } -- cgit v0.9.1