From 3a9fa8c026bf28bf87e20ec95327f74fd7070b74 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 10 Nov 2018 01:56:37 -0500 Subject: [PATCH] [qsort] Fix O(N^2) behavior if all array elements are the same Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11327 Reported as https://github.com/noporpoise/sort_r/issues/7 --- src/hb-dsalgs.hh | 15 +++++++++++---- ...e-minimized-hb-shape-fuzzer-5634443633491968 | Bin 0 -> 41814 bytes 2 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5634443633491968 diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 9ccd7f255..ffa438704 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -356,7 +356,12 @@ hb_bsearch_r (const void *key, const void *base, } -/* From https://github.com/noporpoise/sort_r */ +/* From https://github.com/noporpoise/sort_r + * With following modifications: + * + * 10 November 2018: + * https://github.com/noporpoise/sort_r/issues/7 + */ /* Isaac Turner 29 April 2014 Public Domain */ @@ -412,7 +417,7 @@ static inline void sort_r_simple(void *base, size_t nel, size_t w, /* Use median of first, middle and last items as pivot */ char *x, *y, *xend, ch; - char *pl, *pr; + char *pl, *pm, *pr; char *last = b+w*(nel-1), *tmp; char *l[3]; l[0] = b; @@ -434,13 +439,15 @@ static inline void sort_r_simple(void *base, size_t nel, size_t w, pr = last; while(pl < pr) { - for(; pl < pr; pl += w) { + pm = pl+((pr-pl+1)>>1); + for(; pl < pm; pl += w) { if(sort_r_cmpswap(pl, pr, w, compar, arg)) { pr -= w; /* pivot now at pl */ break; } } - for(; pl < pr; pr -= w) { + pm = pl+((pr-pl)>>1); + for(; pm < pr; pr -= w) { if(sort_r_cmpswap(pl, pr, w, compar, arg)) { pl += w; /* pivot now at pr */ break; diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5634443633491968 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5634443633491968 new file mode 100644 index 0000000000000000000000000000000000000000..c63bcc582f186d12048b84c1413c20ae14a4daad GIT binary patch literal 41814 zcmeI)+iM(U7{~G7>}+h~p{^)+K*E5Uq%~|)yYZRHZbQ>lOCV6o_YLpNJkNWW_x-$k zlZ#zBlDw=G7t6;=;ls7>C1=*MYn7(o(YpS$_*;v|YmNR}op0W?Hs^1v_l1F9Eqs09 zQ)~M%Ns?-4i35|lFD$-f_0g~y_eSgb%KCn8aiP(!_&TRgEdJf%+nau`qpn`C_yLQ( zW;^P6r<`-r$eP6;wftsq6PqU7ypK#$3-b4{kLLuK8^4ye5WY zavFPIw^?g-(8JBW>geMU9n5{0TeaN6*4=qsC1)z_Gh!rJ84MWSRu)dZq&ayCUC-8V z-qw8H+8kSBwx79)&kjm&2T|{kZQ5EUk8R4i|Iqw}Vv?jAeD<_#y!4vYtXTK7SdY?n zk6~(NJ2hvyN3y&gx7(TuwxKgd@uj^ueYW@gQn1vpo+;Q<7ANohk?2i}?$ATdD{|%J zM|H3APWO1b(~s)4Fdjeam5MV@c`L1YrCklCyc4a;(dD2UpIls8T@LF}+>gU32$q7{ zdc%))Y4NV#G(Bi4``t?Dd%4Kp2%^x}akbS^Uy-wgk>r^s%4A2vdfayntjll@@=B6bgYwFw3bziLz^J7sryz#dkXB&yE3YAq4 z%IO_bmTls$tu(Z|r}?KNyKmU5qb!piR(d!}evqEbp02*QdR_~b+Uj*Z_+EM>Hx57l zU+^<~fxm`ubxG#F4L`mUe!`CHno+~!DjeQMp2Xavo6 zoc$lY|L@}s2q1s}0tg_000IagfB*srAb