Skip to content

Commit 4a9cb56

Browse files
committed
Simplify bound checks in the central directory
1 parent 9d9bf25 commit 4a9cb56

1 file changed

Lines changed: 7 additions & 18 deletions

File tree

src/lib/otezip.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,12 @@ static int otezip_load_central(zip_t *za) {
348348
uint16_t filename_len = otezip_rd16 (h + 28);
349349
uint16_t extra_len = otezip_rd16 (h + 30);
350350
uint16_t comment_len = otezip_rd16 (h + 32);
351+
size_t entry_size = 46 + (size_t)filename_len + (size_t)extra_len + (size_t)comment_len;
351352

352-
/* Field lengths are 16-bit per spec; further validation occurs when
353-
* advancing offsets and allocating memory below. */
353+
if (entry_size > cd_size - off) {
354+
free (cd_buf);
355+
return OTEZIP_ERR_INCONS;
356+
}
354357

355358
struct otezip_entry *e = &za->entries[i];
356359
e->method = otezip_rd16 (h + 10);
@@ -360,35 +363,21 @@ static int otezip_load_central(zip_t *za) {
360363
e->comp_size = otezip_rd32 (h + 20);
361364
e->uncomp_size = otezip_rd32 (h + 24);
362365
e->local_hdr_ofs = otezip_rd32 (h + 42);
366+
e->external_attr = otezip_rd32 (h + 38);
363367

364-
/* Reject entries with absurdly large sizes to avoid allocating
365-
* more than our allowed maximum. */
366368
if ((uint64_t)e->comp_size > OTEZIP_MAX_PAYLOAD || (uint64_t)e->uncomp_size > OTEZIP_MAX_PAYLOAD) {
367369
free (cd_buf);
368370
return OTEZIP_ERR_INCONS;
369371
}
370-
e->external_attr = otezip_rd32 (h + 38);
371372

372-
/* Validate filename fits in buffer before allocating */
373-
if ((size_t)(46 + filename_len) > cd_size - off) {
374-
free (cd_buf);
375-
return OTEZIP_ERR_INCONS;
376-
}
377373
e->name = (char *)malloc (filename_len + 1u);
378374
if (!e->name) {
379375
free (cd_buf);
380376
return OTEZIP_ERR_READ;
381377
}
382378
memcpy (e->name, h + 46, filename_len);
383379
e->name[filename_len] = '\0';
384-
385-
/* Safely advance offset, checking for overflow and bounds */
386-
uint64_t advance = 46 + (uint64_t)filename_len + (uint64_t)extra_len + (uint64_t)comment_len;
387-
if (advance > (uint64_t)cd_size - off) {
388-
free (cd_buf);
389-
return OTEZIP_ERR_INCONS;
390-
}
391-
off += (size_t)advance;
380+
off += entry_size;
392381
}
393382
free (cd_buf);
394383
return 0;

0 commit comments

Comments
 (0)