From 8399735689cb3b29dfcc47d3ec725cf94313c047 Mon Sep 17 00:00:00 2001 From: rootvector2 Date: Sun, 15 Mar 2026 17:22:13 +0530 Subject: [PATCH] Validate PKWARE compressed size before header subtraction --- lib/zip_source_pkware_decode.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/zip_source_pkware_decode.c b/lib/zip_source_pkware_decode.c index 090ad22f3..f350e2b60 100644 --- a/lib/zip_source_pkware_decode.c +++ b/lib/zip_source_pkware_decode.c @@ -53,6 +53,7 @@ static void trad_pkware_free(struct trad_pkware *); zip_source_t *zip_source_pkware_decode(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) { struct trad_pkware *ctx; zip_source_t *s2; + zip_stat_t st; if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) { zip_error_set(&za->error, ZIP_ER_INVAL, 0); @@ -63,6 +64,16 @@ zip_source_t *zip_source_pkware_decode(zip_t *za, zip_source_t *src, zip_uint16_ return NULL; } + if (zip_source_stat(src, &st) != 0) { + zip_error_set_from_source(&za->error, src); + return NULL; + } + + if ((st.valid & ZIP_STAT_COMP_SIZE) == 0 || st.comp_size < ZIP_CRYPTO_PKWARE_HEADERLEN) { + zip_error_set(&za->error, ZIP_ER_OPNOTSUPP, 0); + return NULL; + } + if ((ctx = trad_pkware_new(password, &za->error)) == NULL) { return NULL; } @@ -160,6 +171,10 @@ static zip_int64_t pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_u st->encryption_method = ZIP_EM_NONE; st->valid |= ZIP_STAT_ENCRYPTION_METHOD; if (st->valid & ZIP_STAT_COMP_SIZE) { + if (st->comp_size < ZIP_CRYPTO_PKWARE_HEADERLEN) { + zip_error_set(&ctx->error, ZIP_ER_INCONS, ZIP_ER_DETAIL_CDIR_ENTRY_INVALID); + return -1; + } st->comp_size -= ZIP_CRYPTO_PKWARE_HEADERLEN; }