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 */