# HG changeset patch # User Augie Fackler # Date 2018-05-01 02:13:42 # Node ID 1ec4cb8cbc87004ffbeeb1b5d98acef04c38d59a # Parent faa924469635512b72868b1552a1866a0f91db20 mpatch: introduce a safeadd() helper to work around UB int overflow We're about to make extensive use of this. This change duplicates some stdbool.h portability hacks from cext/util.h. We should probably clean that up in the future, but we'll skip that for now in order to make security backports easier. diff --git a/mercurial/mpatch.c b/mercurial/mpatch.c --- a/mercurial/mpatch.c +++ b/mercurial/mpatch.c @@ -20,6 +20,7 @@ of the GNU General Public License, incorporated herein by reference. */ +#include #include #include @@ -27,6 +28,15 @@ #include "compat.h" #include "mpatch.h" +/* VC9 doesn't include bool and lacks stdbool.h based on cext/util.h */ +#if defined(_MSC_VER) || __STDC_VERSION__ < 199901L +#define true 1 +#define false 0 +typedef unsigned char bool; +#else +#include +#endif + static struct mpatch_flist *lalloc(ssize_t size) { struct mpatch_flist *a = NULL; @@ -60,6 +70,24 @@ static ssize_t lsize(struct mpatch_flist return a->tail - a->head; } +/* add helper to add src and *dest iff it won't overflow */ +static inline bool safeadd(int src, int *dest) +{ + if ((src > 0) == (*dest > 0)) { + if (*dest > 0) { + if (src > (INT_MAX - *dest)) { + return false; + } + } else { + if (src < (INT_MIN - *dest)) { + return false; + } + } + } + *dest += src; + return true; +} + /* move hunks in source that are less cut to dest, compensating for changes in offset. the last hunk may be split if necessary. */