diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 2c61024e84..068a2296cc 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -2257,9 +2257,10 @@ A jump table for the options with a short description can be found at |Q_op|. internal Use the internal diff library. This is ignored when 'diffexpr' is set. *E960* When running out of memory when writing a - buffer this item will be ignored for diffs - involving that buffer. Set the 'verbose' - option to see when this happens. + buffer or the diff is larger than 1 GB this + item will be ignored for diffs involving that + buffer. Set the 'verbose' option to see when + this happens. iwhite Ignore changes in amount of white space. Adds the "-b" flag to the "diff" command if diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 0d0471c671..7befc642c5 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -1874,9 +1874,10 @@ vim.go.dex = vim.go.diffexpr --- internal Use the internal diff library. This is --- ignored when 'diffexpr' is set. *E960* --- When running out of memory when writing a ---- buffer this item will be ignored for diffs ---- involving that buffer. Set the 'verbose' ---- option to see when this happens. +--- buffer or the diff is larger than 1 GB this +--- item will be ignored for diffs involving that +--- buffer. Set the 'verbose' option to see when +--- this happens. --- --- iwhite Ignore changes in amount of white space. Adds --- the "-b" flag to the "diff" command if diff --git a/src/nvim/diff.c b/src/nvim/diff.c index da04d37931..fe28b83529 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -103,6 +103,10 @@ static int linematch_lines = 40; #define LBUFLEN 50 // length of line in diff file +// Max file size xdiff is eqipped to deal with. The value (1GB - 1MB) comes +// from Git's implementation. +#define MAX_XDIFF_SIZE (1024L * 1024 * 1023) + // kTrue when "diff -a" works, kFalse when it doesn't work, // kNone when not checked yet static TriState diff_a_works = kNone; @@ -1221,10 +1225,15 @@ static int diff_file_internal(diffio_T *diffio) emit_cfg.ctxlen = 0; // don't need any diff_context here emit_cb.priv = &diffio->dio_diff; emit_cfg.hunk_func = xdiff_out; + if (diffio->dio_orig.din_mmfile.size > MAX_XDIFF_SIZE + || diffio->dio_new.din_mmfile.size > MAX_XDIFF_SIZE) { + emsg(_(e_problem_creating_internal_diff)); + return FAIL; + } if (xdl_diff(&diffio->dio_orig.din_mmfile, &diffio->dio_new.din_mmfile, ¶m, &emit_cfg, &emit_cb) < 0) { - emsg(_("E960: Problem creating the internal diff")); + emsg(_(e_problem_creating_internal_diff)); return FAIL; } return OK; diff --git a/src/nvim/errors.h b/src/nvim/errors.h index b63929a657..dd8d6871a0 100644 --- a/src/nvim/errors.h +++ b/src/nvim/errors.h @@ -165,6 +165,8 @@ EXTERN const char e_cant_find_file_str_in_path[] INIT(= N_("E345: Can't find fil EXTERN const char e_no_more_directory_str_found_in_cdpath[] INIT(= N_("E346: No more directory \"%s\" found in cdpath")); EXTERN const char e_no_more_file_str_found_in_path[] INIT(= N_("E347: No more file \"%s\" found in path")); +EXTERN const char e_problem_creating_internal_diff[] INIT(= N_("E960: Problem creating the internal diff")); + EXTERN const char e_cannot_define_autocommands_for_all_events[] INIT(= N_("E1155: Cannot define autocommands for ALL events")); EXTERN const char e_cannot_change_arglist_recursively[] INIT(= N_("E1156: Cannot change the argument list recursively")); diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 50bfd6ddbb..a21f5647dd 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2460,9 +2460,10 @@ local options = { internal Use the internal diff library. This is ignored when 'diffexpr' is set. *E960* When running out of memory when writing a - buffer this item will be ignored for diffs - involving that buffer. Set the 'verbose' - option to see when this happens. + buffer or the diff is larger than 1 GB this + item will be ignored for diffs involving that + buffer. Set the 'verbose' option to see when + this happens. iwhite Ignore changes in amount of white space. Adds the "-b" flag to the "diff" command if