diff --git a/ll-merge.c b/ll-merge.c index 8ea03e536a56655ff48f4fa8a3050c0225d52f38..4e789f533043c78916b4281ac8113f1e75d342b4 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -88,7 +88,10 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused, xmparam_t xmp; assert(opts); - if (buffer_is_binary(orig->ptr, orig->size) || + if (orig->size > MAX_XDIFF_SIZE || + src1->size > MAX_XDIFF_SIZE || + src2->size > MAX_XDIFF_SIZE || + buffer_is_binary(orig->ptr, orig->size) || buffer_is_binary(src1->ptr, src1->size) || buffer_is_binary(src2->ptr, src2->size)) { return ll_binary_merge(drv_unused, result, diff --git a/xdiff-interface.c b/xdiff-interface.c index ecfa05f616f4b72d65bcb129c1ee2141cf3d1c47..cb67c1c42b35e412dccf9a13ad18dde727ab8ce6 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -131,6 +131,9 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co mmfile_t a = *mf1; mmfile_t b = *mf2; + if (mf1->size > MAX_XDIFF_SIZE || mf2->size > MAX_XDIFF_SIZE) + return -1; + trim_common_tail(&a, &b, xecfg->ctxlen); return xdl_diff(&a, &b, xpp, xecfg, xecb); diff --git a/xdiff-interface.h b/xdiff-interface.h index eff7762ee1a1bb0ea648c60a07389e22e9a1ac07..fbb5a1c3949b6ef6ba0dfb758723a48f3b402190 100644 --- a/xdiff-interface.h +++ b/xdiff-interface.h @@ -3,6 +3,13 @@ #include "xdiff/xdiff.h" +/* + * xdiff isn't equipped to handle content over a gigabyte; + * we make the cutoff 1GB - 1MB to give some breathing + * room for constant-sized additions (e.g., merge markers) + */ +#define MAX_XDIFF_SIZE (1024UL * 1024 * 1023) + typedef void (*xdiff_emit_consume_fn)(void *, char *, unsigned long); int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb);