xdiff: introduce XDL_ALLOC_ARRAY()
Add a helper to allocate an array that automatically calculates the allocation size. This is analogous to ALLOC_ARRAY() in the rest of the codebase but returns NULL if the allocation fails to accommodate other users of libxdiff such as libgit2. The helper will also return NULL if the multiplication in the allocation calculation overflows. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Phillip Wood committed
Jul 8, 2022 at 16:25 UTC
abf04bdaa845a6650d1f44b9f5914df442559d75
4 files changed
+12
-7
xdiff/xdiffi.c
+1
-1
@@ -337,7 +337,7 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
337
* One is to store the forward path and one to store the backward path.
338
*/
339
ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
340
- if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
340
+ if (!XDL_ALLOC_ARRAY(kvd, 2 * ndiags + 2)) {
341
342
xdl_free_env(xe);
343
return -1;
xdiff/xmacros.h
+5
@@ -49,5 +49,10 @@ do { \
49
((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
50
} while (0)
51
52
+/* Allocate an array of nr elements, returns NULL on failure */
53
+#define XDL_ALLOC_ARRAY(p, nr) \
54
+ ((p) = SIZE_MAX / sizeof(*(p)) >= (size_t)(nr) \
55
+ ? xdl_malloc((nr) * sizeof(*(p))) \
56
+ : NULL)
57
58
#endif /* #if !defined(XMACROS_H) */
xdiff/xpatience.c
+2
-2
@@ -200,7 +200,7 @@ static int binary_search(struct entry **sequence, int longest,
200
*/
201
static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
202
{
203
- struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
203
+ struct entry **sequence;
204
int longest = 0, i;
205
struct entry *entry;
206
@@ -211,7 +211,7 @@ static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
211
*/
212
int anchor_i = -1;
213
214
- if (!sequence)
214
+ if (!XDL_ALLOC_ARRAY(sequence, map->nr))
215
return -1;
216
217
for (entry = map->first; entry; entry = entry->next) {
xdiff/xprepare.c
+4
-4
@@ -86,7 +86,7 @@ static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
86
memset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));
87
88
cf->alloc = size;
89
- if (!(cf->rcrecs = (xdlclass_t **) xdl_malloc(cf->alloc * sizeof(xdlclass_t *)))) {
89
+ if (!XDL_ALLOC_ARRAY(cf->rcrecs, cf->alloc)) {
90
91
xdl_free(cf->rchash);
92
xdl_cha_free(&cf->ncha);
@@ -178,7 +178,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
178
179
if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)
180
goto abort;
181
- if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
181
+ if (!XDL_ALLOC_ARRAY(recs, narec))
182
goto abort;
183
184
hbits = xdl_hashbits((unsigned int) narec);
@@ -215,9 +215,9 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
215
216
if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
217
(XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)) {
218
- if (!(rindex = xdl_malloc((nrec + 1) * sizeof(*rindex))))
218
+ if (!XDL_ALLOC_ARRAY(rindex, nrec + 1))
219
goto abort;
220
- if (!(ha = xdl_malloc((nrec + 1) * sizeof(*ha))))
220
+ if (!XDL_ALLOC_ARRAY(ha, nrec + 1))
221
goto abort;
222
}
223