@@ -539,10 +539,11 @@ int git_delta_apply(
539539 * out = NULL ;
540540 * out_len = 0 ;
541541
542- /* Check that the base size matches the data we were given;
543- * if not we would underflow while accessing data from the
544- * base object, resulting in data corruption or segfault.
545- */
542+ /*
543+ * Check that the base size matches the data we were given;
544+ * if not we would underflow while accessing data from the
545+ * base object, resulting in data corruption or segfault.
546+ */
546547 if ((hdr_sz (& base_sz , & delta , delta_end ) < 0 ) || (base_sz != base_len )) {
547548 giterr_set (GITERR_INVALID , "failed to apply delta: base size does not match given data" );
548549 return -1 ;
@@ -564,42 +565,43 @@ int git_delta_apply(
564565 while (delta < delta_end ) {
565566 unsigned char cmd = * delta ++ ;
566567 if (cmd & 0x80 ) {
567- /* cmd is a copy instruction; copy from the base.
568- */
569- size_t off = 0 , len = 0 ;
570-
571- if (cmd & 0x01 ) off = * delta ++ ;
572- if (cmd & 0x02 ) off |= * delta ++ << 8UL ;
573- if (cmd & 0x04 ) off |= * delta ++ << 16UL ;
574- if (cmd & 0x08 ) off |= * delta ++ << 24UL ;
575-
576- if (cmd & 0x10 ) len = * delta ++ ;
577- if (cmd & 0x20 ) len |= * delta ++ << 8UL ;
578- if (cmd & 0x40 ) len |= * delta ++ << 16UL ;
579- if (!len ) len = 0x10000 ;
580-
581- if (base_len < off + len || res_sz < len )
568+ /* cmd is a copy instruction; copy from the base. */
569+ size_t off = 0 , len = 0 , end ;
570+
571+ #define ADD_DELTA (o , shift ) { if (delta < delta_end) (o) |= ((unsigned) *delta++ << shift); else goto fail; }
572+ if (cmd & 0x01 ) ADD_DELTA (off , 0UL );
573+ if (cmd & 0x02 ) ADD_DELTA (off , 8UL );
574+ if (cmd & 0x04 ) ADD_DELTA (off , 16UL );
575+ if (cmd & 0x08 ) ADD_DELTA (off , 24UL );
576+
577+ if (cmd & 0x10 ) ADD_DELTA (len , 0UL );
578+ if (cmd & 0x20 ) ADD_DELTA (len , 8UL );
579+ if (cmd & 0x40 ) ADD_DELTA (len , 16UL );
580+ if (!len ) len = 0x10000 ;
581+ #undef ADD_DELTA
582+
583+ if (GIT_ADD_SIZET_OVERFLOW (& end , off , len ) ||
584+ base_len < end || res_sz < len )
582585 goto fail ;
586+
583587 memcpy (res_dp , base + off , len );
584588 res_dp += len ;
585589 res_sz -= len ;
586590
587- }
588- else if ( cmd ) {
589- / * cmd is a literal insert instruction; copy from
590- * the delta stream itself.
591- */
591+ } else if ( cmd ) {
592+ /*
593+ * cmd is a literal insert instruction; copy from
594+ * the delta stream itself.
595+ */
592596 if (delta_end - delta < cmd || res_sz < cmd )
593597 goto fail ;
594598 memcpy (res_dp , delta , cmd );
595599 delta += cmd ;
596600 res_dp += cmd ;
597601 res_sz -= cmd ;
598602
599- }
600- else {
601- /* cmd == 0 is reserved for future encodings.
602- */
603+ } else {
604+ /* cmd == 0 is reserved for future encodings. */
603605 goto fail ;
604606 }
605607 }
0 commit comments