Mercurial > hg
comparison mercurial/mpatch.c @ 38190:1ec4cb8cbc87 stable
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.
author | Augie Fackler <augie@google.com> |
---|---|
date | Mon, 30 Apr 2018 22:13:42 -0400 |
parents | faa924469635 |
children | b8b253aec953 |
comparison
equal
deleted
inserted
replaced
38189:faa924469635 | 38190:1ec4cb8cbc87 |
---|---|
18 | 18 |
19 This software may be used and distributed according to the terms | 19 This software may be used and distributed according to the terms |
20 of the GNU General Public License, incorporated herein by reference. | 20 of the GNU General Public License, incorporated herein by reference. |
21 */ | 21 */ |
22 | 22 |
23 #include <limits.h> | |
23 #include <stdlib.h> | 24 #include <stdlib.h> |
24 #include <string.h> | 25 #include <string.h> |
25 | 26 |
26 #include "bitmanipulation.h" | 27 #include "bitmanipulation.h" |
27 #include "compat.h" | 28 #include "compat.h" |
28 #include "mpatch.h" | 29 #include "mpatch.h" |
30 | |
31 /* VC9 doesn't include bool and lacks stdbool.h based on cext/util.h */ | |
32 #if defined(_MSC_VER) || __STDC_VERSION__ < 199901L | |
33 #define true 1 | |
34 #define false 0 | |
35 typedef unsigned char bool; | |
36 #else | |
37 #include <stdbool.h> | |
38 #endif | |
29 | 39 |
30 static struct mpatch_flist *lalloc(ssize_t size) | 40 static struct mpatch_flist *lalloc(ssize_t size) |
31 { | 41 { |
32 struct mpatch_flist *a = NULL; | 42 struct mpatch_flist *a = NULL; |
33 | 43 |
56 } | 66 } |
57 | 67 |
58 static ssize_t lsize(struct mpatch_flist *a) | 68 static ssize_t lsize(struct mpatch_flist *a) |
59 { | 69 { |
60 return a->tail - a->head; | 70 return a->tail - a->head; |
71 } | |
72 | |
73 /* add helper to add src and *dest iff it won't overflow */ | |
74 static inline bool safeadd(int src, int *dest) | |
75 { | |
76 if ((src > 0) == (*dest > 0)) { | |
77 if (*dest > 0) { | |
78 if (src > (INT_MAX - *dest)) { | |
79 return false; | |
80 } | |
81 } else { | |
82 if (src < (INT_MIN - *dest)) { | |
83 return false; | |
84 } | |
85 } | |
86 } | |
87 *dest += src; | |
88 return true; | |
61 } | 89 } |
62 | 90 |
63 /* move hunks in source that are less cut to dest, compensating | 91 /* move hunks in source that are less cut to dest, compensating |
64 for changes in offset. the last hunk may be split if necessary. | 92 for changes in offset. the last hunk may be split if necessary. |
65 */ | 93 */ |