From cea8d752b5d587c7a67c7998c18313eb10649629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=BF=97=E5=BC=BA?= Date: Wed, 6 Sep 2023 23:06:15 +0800 Subject: [PATCH] Fix incorrect binary search logic which would cause the longest matching string to be missed When memcmp returns 0 and cmpsize < newsize, it means that `old + I[x]` is smaller than `new`, then `search(..., x, en, pos)` should be performed instead of `search(..., st, x, pos)` --- bsdiff.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bsdiff.c b/bsdiff.c index 628f1c1..b75b63f 100644 --- a/bsdiff.c +++ b/bsdiff.c @@ -144,7 +144,8 @@ static int64_t matchlen(const uint8_t *old,int64_t oldsize,const uint8_t *new,in static int64_t search(const int64_t *I,const uint8_t *old,int64_t oldsize, const uint8_t *new,int64_t newsize,int64_t st,int64_t en,int64_t *pos) { - int64_t x,y; + int64_t x,y,cmpsize; + int32_t res; if(en-st<2) { x=matchlen(old+I[st],oldsize-I[st],new,newsize); @@ -160,7 +161,9 @@ static int64_t search(const int64_t *I,const uint8_t *old,int64_t oldsize, }; x=st+(en-st)/2; - if(memcmp(old+I[x],new,MIN(oldsize-I[x],newsize))<0) { + cmpsize=MIN(oldsize-I[x],newsize); + res=memcmp(old+I[x],new,cmpsize); + if((res<0) || ((res==0) && (cmpsize