@@ -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