From 2e4df505a489b32a5cf0acef3cf45cb3d6c81d4b Mon Sep 17 00:00:00 2001 From: samuelhuang Date: Mon, 2 May 2016 15:52:09 -0400 Subject: [PATCH] Fix split() pivoting to avoid Quicksort worst case causing stack overflow. One such case is 'A' * 1048575 + 'B' + 'A' * 1048575 + 'C'. Demo: gcc -DBSDIFF_EXECUTABLE bsdiff.c -lbz2 -o bsdiff perl -e "print('A'x1048575,'B','A'x1048575,'C')" > big ./bsdiff big big patch Output before patch: 'Segmentation fault (core dumped)'. Output after patch: No crash, outputs 85 byte file 'patch'. Details: http://crbug.com/605565#c11 --- bsdiff.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/bsdiff.c b/bsdiff.c index 628f1c1..7e0e1db 100644 --- a/bsdiff.c +++ b/bsdiff.c @@ -4,7 +4,7 @@ * All rights reserved * * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions + * modification, are permitted providing that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. @@ -31,10 +31,13 @@ #include #define MIN(x,y) (((x)<(y)) ? (x) : (y)) +#define MEDIAN3(a,b,c) (((a)<(b)) ? \ + ((b)<(c) ? (b) : ((a)<(c) ? (c) : (a))) : \ + ((b)>(c) ? (b) : ((a)>(c) ? (c) : (a)))) static void split(int64_t *I,int64_t *V,int64_t start,int64_t len,int64_t h) { - int64_t i,j,k,x,tmp,jj,kk; + int64_t i,j,k,x,y,z,tmp,jj,kk; if(len<16) { for(k=start;k40) { /* Big array: Pseudomedian of 9 */ + tmp=len/8; + x=MEDIAN3(x,V[I[j-tmp]+h],V[I[j+tmp]+h]); + y=MEDIAN3(y,V[I[start+tmp]+h],V[I[start+tmp+tmp]+h]); + z=MEDIAN3(z,V[I[k-tmp]+h],V[I[k-tmp-tmp]+h]); + }; /* Else medium array: Pseudomedian of 3 */ + x=MEDIAN3(x,y,z); + jj=0;kk=0; for(i=start;ioldscore+8)) break; if((scan+lastoffset