Skip to content

Commit 5c83b74

Browse files
committed
Accept EOCD-only empty archives
1 parent a26a596 commit 5c83b74

2 files changed

Lines changed: 19 additions & 4 deletions

File tree

src/lib/otezip.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,12 +299,24 @@ static int otezip_load_central(zip_t *za) {
299299
return OTEZIP_ERR_INCONS;
300300
}
301301

302+
/* A valid empty ZIP may contain only an EOCD record with an empty
303+
* central directory. Accept that case without trying to read or parse
304+
* any central directory entries. */
305+
if (n_entries == 0) {
306+
if (cd_size != 0) {
307+
return OTEZIP_ERR_INCONS;
308+
}
309+
za->entries = NULL;
310+
za->n_entries = 0;
311+
return 0;
312+
}
313+
302314
/* read entire central directory */
303315
if (fseek (za->fp, cd_ofs, SEEK_SET) != 0) {
304316
return OTEZIP_ERR_READ;
305317
}
306318
/* Validate central directory size isn't unreasonably large */
307-
if (cd_size == 0 || cd_size > OTEZIP_MAX_PAYLOAD) {
319+
if (cd_size > OTEZIP_MAX_PAYLOAD) {
308320
return OTEZIP_ERR_INCONS;
309321
}
310322
uint8_t *cd_buf = (uint8_t *)malloc (cd_size);
@@ -317,7 +329,7 @@ static int otezip_load_central(zip_t *za) {
317329
}
318330

319331
/* Validate number of entries is reasonable (max ~1.4M entries fits in cd_size) */
320-
if (n_entries == 0 || (size_t)n_entries * 46 > cd_size) {
332+
if ((size_t)n_entries * 46 > cd_size) {
321333
free (cd_buf);
322334
return OTEZIP_ERR_INCONS;
323335
}
@@ -673,7 +685,7 @@ static int otezip_extract_entry(zip_t *za, struct otezip_entry *e, uint8_t **out
673685

674686
/* Helper function to validate archive state */
675687
static int otezip_is_valid(const zip_t *za) {
676-
return (za != NULL && za->entries != NULL);
688+
return (za != NULL && za->fp != NULL);
677689
}
678690

679691
/* -------------- public API implementation --------------- */

test/unit/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ CFLAGS += -I../../src/include
44
LDFLAGS ?=
55

66
# Define test targets
7-
TESTS = test_deflate test_mzip_deflate test_lzma test_zstd test_lzfse
7+
TESTS = test_deflate test_mzip_deflate test_lzma test_zstd test_lzfse test_empty_zip
88

99
all: $(TESTS)
1010

@@ -23,6 +23,9 @@ test_lzma: test_lzma.c
2323
test_lzfse: test_lzfse.c
2424
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
2525

26+
test_empty_zip: test_empty_zip.c ../../src/lib/otezip.c ../../src/include/otezip/zip.h ../../src/include/otezip/config.h
27+
$(CC) $(CFLAGS) -o $@ $< ../../src/lib/otezip.c $(LDFLAGS)
28+
2629
clean:
2730
rm -f $(TESTS)
2831

0 commit comments

Comments
 (0)