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,
 
        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);
 
 
 #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);