diff --git a/lib/bsdiff/bsdiff_align.c b/lib/bsdiff/bsdiff_align.c index bfb5e6f..93216a4 100644 --- a/lib/bsdiff/bsdiff_align.c +++ b/lib/bsdiff/bsdiff_align.c @@ -29,6 +29,8 @@ #include #include +#include "warnp.h" + #include "bsdiff_alignment.h" #include "sufsort_qsufsort.h" @@ -283,7 +285,7 @@ bsdiff_align(const uint8_t * new, size_t newsize, if (old[i - 1 + (asegp2->opos - asegp2->npos)] == new[i - 1]) s++; i--; - if (i + s >= asegp->npos + asegp->alen) { + if ((i + s >= asegp->npos + asegp->alen) && (i >= asegp->npos)) { asegp->alen = i - asegp->npos; s = 0; } @@ -294,7 +296,7 @@ bsdiff_align(const uint8_t * new, size_t newsize, } /* Delete any alignment segments which are now empty. */ - for (k = j = 1; j + 1< bsdiff_alignment_getsize(A); j++) { + for (k = j = 0; j + 1< bsdiff_alignment_getsize(A); j++) { asegp = bsdiff_alignment_get(A, k); asegp2 = bsdiff_alignment_get(A, j + 1); @@ -307,6 +309,17 @@ bsdiff_align(const uint8_t * new, size_t newsize, } bsdiff_alignment_shrink(A, j - k); + /* Warn about any bad alignment lengths */ + for (j = 0; j < bsdiff_alignment_getsize(A); j++) { + asegp = bsdiff_alignment_get(A, j); + if (asegp->alen == 0) + warnp("bsdiff_align: A[%lu] asegp->alen is zero"); + else if (asegp->alen > (0x8000000000000000L)) + /* Larger than 2^63 */ + warnp("bsdiff_align: A[%lu] huge segment asegp->alen %lu", + j, asegp->alen); + } + /* Free the suffix array. */ free(I); diff --git a/lib/bsdiff/bsdiff_align_multi.c b/lib/bsdiff/bsdiff_align_multi.c index 85c74e5..49b7fd8 100644 --- a/lib/bsdiff/bsdiff_align_multi.c +++ b/lib/bsdiff/bsdiff_align_multi.c @@ -133,6 +133,7 @@ bsdiff_align_multi(const uint8_t * new, size_t newsize, const uint8_t * old, size_t i, j; BSDIFF_ALIGNMENT * BA; BSDIFF_ALIGNMENT A; + struct bsdiff_alignseg * asegp; /* Index the old file. */ printf("Indexing old file...\n"); @@ -184,10 +185,19 @@ bsdiff_align_multi(const uint8_t * new, size_t newsize, const uint8_t * old, for (i = 0; i < nblocks; i++) { /* Add these alignment segments to the whole-file alignment. */ for (j = 0; j < bsdiff_alignment_getsize(BA[i]); j++) { - if (bsdiff_alignment_append(A, - bsdiff_alignment_get(BA[i], j), 1)) { - warnp("bsdiff_alignment_append"); - goto err3; + asegp = bsdiff_alignment_get(BA[i], j); + if (asegp->alen) { + if (asegp->alen > 0x8000000000000000L) + /* Larger than 2^63 */ + warnp("bsdiff_alignment_append: BA[%lu] segment size %lu", + i, asegp->alen); + if (bsdiff_alignment_append(A, + bsdiff_alignment_get(BA[i], j), 1)) { + warnp("bsdiff_alignment_append"); + goto err3; + } + } else { + warnp("bsdiff_alignment_append: skipped zero length alignment at BA[%lu]", i); } } }