summaryrefslogtreecommitdiffstats
path: root/debian/patches/upstream
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/upstream')
-rw-r--r--debian/patches/upstream/Support-defining-compilation-date-in-SOURCE_DATE_EPOCH.patch89
-rw-r--r--debian/patches/upstream/deb-release-names.patch58
-rw-r--r--debian/patches/upstream/patch-8.1.0881-can-execute-shell-commands-in-rvim-through.patch378
-rw-r--r--debian/patches/upstream/patch-8.1.0883-missing-some-changes-for-Ex-commands.patch150
-rw-r--r--debian/patches/upstream/patch-8.1.0936-may-leak-memory-when-using-vartabstop.patch95
-rw-r--r--debian/patches/upstream/patch-8.2.3402-invalid-memory-access-when-using-retab-wit.patch196
-rw-r--r--debian/patches/upstream/patch-8.2.3403-memory-leak-for-retab-with-invalid-argumen.patch67
-rw-r--r--debian/patches/upstream/patch-8.2.3409-reading-beyond-end-of-line-with-invalid-ut.patch58
-rw-r--r--debian/patches/upstream/patch-8.2.3428-using-freed-memory-when-replacing.patch78
9 files changed, 1169 insertions, 0 deletions
diff --git a/debian/patches/upstream/Support-defining-compilation-date-in-SOURCE_DATE_EPOCH.patch b/debian/patches/upstream/Support-defining-compilation-date-in-SOURCE_DATE_EPOCH.patch
new file mode 100644
index 0000000..f26c02a
--- /dev/null
+++ b/debian/patches/upstream/Support-defining-compilation-date-in-SOURCE_DATE_EPOCH.patch
@@ -0,0 +1,89 @@
+From: James McCoy <jamessan@jamessan.com>
+Date: Thu, 28 Jan 2016 10:55:11 -0500
+Subject: Support defining compilation date in $SOURCE_DATE_EPOCH
+
+There is an ongoing effort[0] to make FOSS software reproducibly
+buildable. In order to make Vim build reproducibly, it is necessary to
+allow defining the date/time that is part of VIM_VERSION_LONG as part of
+the build process.
+
+This commit enables that by adding support for the SOURCE_DATE_EPOCH
+spec[1]. When the $SOURCE_DATE_EPOCH environment variable is defined,
+it will be used to populate the BUILD_DATE preprocessor define.
+
+If BUILD_DATE is not defined, the existing behavior of relying on the
+preprocessor's __DATE__/__TIME__ symbols will be used.
+
+[0]: https://reproducible-builds.org/
+[1]: https://reproducible-builds.org/specs/source-date-epoch/
+---
+ src/config.h.in | 3 +++
+ src/configure.ac | 10 ++++++++++
+ src/version.c | 8 ++++++++
+ 3 files changed, 21 insertions(+)
+
+diff --git a/src/config.h.in b/src/config.h.in
+index d1aaf70..78cf319 100644
+--- a/src/config.h.in
++++ b/src/config.h.in
+@@ -30,6 +30,9 @@
+ /* Define when __DATE__ " " __TIME__ can be used */
+ #undef HAVE_DATE_TIME
+
++/* Defined as the date of last modification */
++#undef BUILD_DATE
++
+ /* Define when __attribute__((unused)) can be used */
+ #undef HAVE_ATTRIBUTE_UNUSED
+
+diff --git a/src/configure.ac b/src/configure.ac
+index 2b7725b..21ca7a1 100644
+--- a/src/configure.ac
++++ b/src/configure.ac
+@@ -62,6 +62,16 @@ if test x"$ac_cv_prog_cc_c99" != xno; then
+ fi
+ fi
+
++dnl If $SOURCE_DATE_EPOCH is present in the environment, use that as the
++dnl "compiled" timestamp in :version's output. Attempt to get the formatted
++dnl date using GNU date syntax, BSD date syntax, and finally falling back to
++dnl just using the current time.
++if test -n "$SOURCE_DATE_EPOCH"; then
++ DATE_FMT="%b %d %Y %H:%M:%S"
++ BUILD_DATE=$(LC_ALL=C date -u -d "@$SOURCE_DATE_EPOCH" "+$DATE_FMT" 2>/dev/null || LC_ALL=C date -u -r "$SOURCE_DATE_EPOCH" "+$DATE_FMT" 2>/dev/null || LC_ALL=C date -u "+$DATE_FMT")
++ AC_DEFINE_UNQUOTED(BUILD_DATE, ["$BUILD_DATE"])
++fi
++
+ dnl Check for the flag that fails if stuff are missing.
+
+ AC_MSG_CHECKING(--enable-fail-if-missing argument)
+diff --git a/src/version.c b/src/version.c
+index 9b2e7c9..0b86826 100644
+--- a/src/version.c
++++ b/src/version.c
+@@ -44,9 +44,13 @@ init_longVersion(void)
+ * VAX C can't catenate strings in the preprocessor.
+ */
+ strcpy(longVersion, VIM_VERSION_LONG_DATE);
++#ifdef BUILD_DATE
++ strcat(longVersion, BUILD_DATE);
++#else
+ strcat(longVersion, __DATE__);
+ strcat(longVersion, " ");
+ strcat(longVersion, __TIME__);
++#endif
+ strcat(longVersion, ")");
+ }
+
+@@ -54,7 +58,11 @@ init_longVersion(void)
+ void
+ init_longVersion(void)
+ {
++#ifdef BUILD_DATE
++ char *date_time = BUILD_DATE;
++#else
+ char *date_time = __DATE__ " " __TIME__;
++#endif
+ char *msg = _("%s (%s, compiled %s)");
+ size_t len = strlen(msg)
+ + strlen(VIM_VERSION_LONG_ONLY)
diff --git a/debian/patches/upstream/deb-release-names.patch b/debian/patches/upstream/deb-release-names.patch
new file mode 100644
index 0000000..42b72dd
--- /dev/null
+++ b/debian/patches/upstream/deb-release-names.patch
@@ -0,0 +1,58 @@
+From: James McCoy <jamessan@debian.org>
+Date: Sun, 21 Apr 2019 23:12:18 -0400
+Subject: Add Ubuntu's eoan and Debian's buster, bullseye, bookworm releases
+
+Signed-off-by: James McCoy <jamessan@debian.org>
+---
+ runtime/syntax/debchangelog.vim | 4 ++--
+ runtime/syntax/debsources.vim | 7 ++++---
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/runtime/syntax/debchangelog.vim b/runtime/syntax/debchangelog.vim
+index 4ca4c29..9d6dfe9 100644
+--- a/runtime/syntax/debchangelog.vim
++++ b/runtime/syntax/debchangelog.vim
+@@ -3,7 +3,7 @@
+ " Maintainer: Debian Vim Maintainers
+ " Former Maintainers: Gerfried Fuchs <alfie@ist.org>
+ " Wichert Akkerman <wakkerma@debian.org>
+-" Last Change: 2019 Jan 26
++" Last Change: 2019 Apr 21
+ " URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/syntax/debchangelog.vim
+
+ " Standard syntax initialization
+@@ -21,7 +21,7 @@ let s:binNMU='binary-only=yes'
+ syn match debchangelogName contained "^[[:alnum:]][[:alnum:].+-]\+ "
+ exe 'syn match debchangelogFirstKV contained "; \('.s:urgency.'\|'.s:binNMU.'\)"'
+ exe 'syn match debchangelogOtherKV contained ", \('.s:urgency.'\|'.s:binNMU.'\)"'
+-syn match debchangelogTarget contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|squeeze-%(backports%(-sloppy)=|volatile|lts|security)|%(wheezy|jessie)%(-backports%(-sloppy)=|-security)=|stretch%(-backports|-security)=|%(devel|precise|trusty|vivid|wily|xenial|yakkety|zesty|artful|bionic|cosmic|disco)%(-%(security|proposed|updates|backports|commercial|partner))=)+"
++syn match debchangelogTarget contained "\v %(frozen|unstable|sid|%(testing|%(old)=stable)%(-proposed-updates|-security)=|experimental|%(squeeze|wheezy|jessie)-%(backports%(-sloppy)=|lts|security)|stretch%(-backports%(-sloppy)=|-security)=|buster%(-backports|-security)=|bullseye|%(devel|precise|trusty|vivid|wily|xenial|yakkety|zesty|artful|bionic|cosmic|disco|eoan)%(-%(security|proposed|updates|backports|commercial|partner))=)+"
+ syn match debchangelogVersion contained "(.\{-})"
+ syn match debchangelogCloses contained "closes:\_s*\(bug\)\=#\=\_s\=\d\+\(,\_s*\(bug\)\=#\=\_s\=\d\+\)*"
+ syn match debchangelogLP contained "\clp:\s\+#\d\+\(,\s*#\d\+\)*"
+diff --git a/runtime/syntax/debsources.vim b/runtime/syntax/debsources.vim
+index 4b21941..f90476f 100644
+--- a/runtime/syntax/debsources.vim
++++ b/runtime/syntax/debsources.vim
+@@ -2,7 +2,7 @@
+ " Language: Debian sources.list
+ " Maintainer: Debian Vim Maintainers
+ " Former Maintainer: Matthijs Mohlmann <matthijs@cacholong.nl>
+-" Last Change: 2018 Oct 30
++" Last Change: 2019 Apr 21
+ " URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/syntax/debsources.vim
+
+ " Standard syntax initialization
+@@ -23,9 +23,10 @@ let s:cpo = &cpo
+ set cpo-=C
+ let s:supported = [
+ \ 'oldstable', 'stable', 'testing', 'unstable', 'experimental',
+- \ 'wheezy', 'jessie', 'stretch', 'sid', 'rc-buggy',
++ \ 'wheezy', 'jessie', 'stretch', 'buster', 'bullseye', 'bookworm',
++ \ 'sid', 'rc-buggy',
+ \
+- \ 'trusty', 'xenial', 'bionic', 'cosmic', 'disco', 'devel'
++ \ 'trusty', 'xenial', 'bionic', 'cosmic', 'disco', 'eoan', 'devel'
+ \ ]
+ let s:unsupported = [
+ \ 'buzz', 'rex', 'bo', 'hamm', 'slink', 'potato',
diff --git a/debian/patches/upstream/patch-8.1.0881-can-execute-shell-commands-in-rvim-through.patch b/debian/patches/upstream/patch-8.1.0881-can-execute-shell-commands-in-rvim-through.patch
new file mode 100644
index 0000000..01e9ad7
--- /dev/null
+++ b/debian/patches/upstream/patch-8.1.0881-can-execute-shell-commands-in-rvim-through.patch
@@ -0,0 +1,378 @@
+From: Bram Moolenaar <Bram@vim.org>
+Date: Fri, 8 Feb 2019 14:34:10 +0100
+Subject: patch 8.1.0881: can execute shell commands in rvim through
+ interfaces
+
+Problem: Can execute shell commands in rvim through interfaces.
+Solution: Disable using interfaces in restricted mode. Allow for writing
+ file with writefile(), histadd() and a few others.
+(cherry picked from commit 8c62a08faf89663e5633dc5036cd8695c80f1075)
+---
+ runtime/doc/starting.txt | 14 ++++--
+ src/evalfunc.c | 22 +++++++--
+ src/ex_cmds.c | 2 +-
+ src/ex_docmd.c | 7 ++-
+ src/if_perl.xs | 13 ++---
+ src/testdir/Make_all.mak | 2 +
+ src/testdir/test_restricted.vim | 107 ++++++++++++++++++++++++++++++++++++++++
+ src/version.c | 2 +
+ 8 files changed, 151 insertions(+), 18 deletions(-)
+ create mode 100644 src/testdir/test_restricted.vim
+
+diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
+index 711a487..6289e9c 100644
+--- a/runtime/doc/starting.txt
++++ b/runtime/doc/starting.txt
+@@ -248,12 +248,18 @@ a slash. Thus "-R" means recovery and "-/R" readonly.
+ changes and writing.
+ {not in Vi}
+
+- *-Z* *restricted-mode* *E145*
++ *-Z* *restricted-mode* *E145* *E981*
+ -Z Restricted mode. All commands that make use of an external
+ shell are disabled. This includes suspending with CTRL-Z,
+- ":sh", filtering, the system() function, backtick expansion,
+- delete(), rename(), mkdir(), writefile(), libcall(),
+- job_start(), etc.
++ ":sh", filtering, the system() function, backtick expansion
++ and libcall().
++ Also disallowed are delete(), rename(), mkdir(), job_start(),
++ etc.
++ Interfaces, such as Python, Ruby and Lua, are also disabled,
++ since they could be used to execute shell commands. Perl uses
++ the Safe module.
++ Note that the user may still find a loophole to execute a
++ shell command, it has only been made difficult.
+ {not in Vi}
+
+ *-g*
+diff --git a/src/evalfunc.c b/src/evalfunc.c
+index fa7ed9b..eb082b7 100644
+--- a/src/evalfunc.c
++++ b/src/evalfunc.c
+@@ -6817,7 +6817,7 @@ f_histadd(typval_T *argvars UNUSED, typval_T *rettv)
+ #endif
+
+ rettv->vval.v_number = FALSE;
+- if (check_restricted() || check_secure())
++ if (check_secure())
+ return;
+ #ifdef FEAT_CMDHIST
+ str = tv_get_string_chk(&argvars[0]); /* NULL on type error */
+@@ -7898,6 +7898,9 @@ f_luaeval(typval_T *argvars, typval_T *rettv)
+ char_u *str;
+ char_u buf[NUMBUFLEN];
+
++ if (check_restricted() || check_secure())
++ return;
++
+ str = tv_get_string_buf(&argvars[0], buf);
+ do_luaeval(str, argvars + 1, rettv);
+ }
+@@ -8644,6 +8647,8 @@ f_mzeval(typval_T *argvars, typval_T *rettv)
+ char_u *str;
+ char_u buf[NUMBUFLEN];
+
++ if (check_restricted() || check_secure())
++ return;
+ str = tv_get_string_buf(&argvars[0], buf);
+ do_mzeval(str, rettv);
+ }
+@@ -8932,6 +8937,9 @@ f_py3eval(typval_T *argvars, typval_T *rettv)
+ char_u *str;
+ char_u buf[NUMBUFLEN];
+
++ if (check_restricted() || check_secure())
++ return;
++
+ if (p_pyx == 0)
+ p_pyx = 3;
+
+@@ -8950,6 +8958,9 @@ f_pyeval(typval_T *argvars, typval_T *rettv)
+ char_u *str;
+ char_u buf[NUMBUFLEN];
+
++ if (check_restricted() || check_secure())
++ return;
++
+ if (p_pyx == 0)
+ p_pyx = 2;
+
+@@ -8965,6 +8976,9 @@ f_pyeval(typval_T *argvars, typval_T *rettv)
+ static void
+ f_pyxeval(typval_T *argvars, typval_T *rettv)
+ {
++ if (check_restricted() || check_secure())
++ return;
++
+ # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
+ init_pyxversion();
+ if (p_pyx == 2)
+@@ -10819,7 +10833,7 @@ f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
+ typval_T *varp;
+ char_u nbuf[NUMBUFLEN];
+
+- if (check_restricted() || check_secure())
++ if (check_secure())
+ return;
+ (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */
+ varname = tv_get_string_chk(&argvars[1]);
+@@ -11341,7 +11355,7 @@ f_settabvar(typval_T *argvars, typval_T *rettv)
+
+ rettv->vval.v_number = 0;
+
+- if (check_restricted() || check_secure())
++ if (check_secure())
+ return;
+
+ tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
+@@ -14714,7 +14728,7 @@ f_writefile(typval_T *argvars, typval_T *rettv)
+ blob_T *blob = NULL;
+
+ rettv->vval.v_number = -1;
+- if (check_restricted() || check_secure())
++ if (check_secure())
+ return;
+
+ if (argvars[0].v_type == VAR_LIST)
+diff --git a/src/ex_cmds.c b/src/ex_cmds.c
+index a3974c1..681ef42 100644
+--- a/src/ex_cmds.c
++++ b/src/ex_cmds.c
+@@ -4775,7 +4775,7 @@ check_restricted(void)
+ {
+ if (restricted)
+ {
+- emsg(_("E145: Shell commands not allowed in rvim"));
++ emsg(_("E145: Shell commands and some functionality not allowed in rvim"));
+ return TRUE;
+ }
+ return FALSE;
+diff --git a/src/ex_docmd.c b/src/ex_docmd.c
+index b90ea7b..ccca2f9 100644
+--- a/src/ex_docmd.c
++++ b/src/ex_docmd.c
+@@ -2007,11 +2007,16 @@ do_one_cmd(
+ #ifdef HAVE_SANDBOX
+ if (sandbox != 0 && !(ea.argt & SBOXOK))
+ {
+- /* Command not allowed in sandbox. */
++ // Command not allowed in sandbox.
+ errormsg = _(e_sandbox);
+ goto doend;
+ }
+ #endif
++ if (restricted != 0 && (ea.argt & RESTRICT))
++ {
++ errormsg = _("E981: Command not allowed in rvim");
++ goto doend;
++ }
+ if (!curbuf->b_p_ma && (ea.argt & MODIFY))
+ {
+ /* Command not allowed in non-'modifiable' buffer */
+diff --git a/src/if_perl.xs b/src/if_perl.xs
+index 203bb6a..67d0b94 100644
+--- a/src/if_perl.xs
++++ b/src/if_perl.xs
+@@ -971,6 +971,7 @@ VIM_init(void)
+ #ifdef DYNAMIC_PERL
+ static char *e_noperl = N_("Sorry, this command is disabled: the Perl library could not be loaded.");
+ #endif
++static char *e_perlsandbox = N_("E299: Perl evaluation forbidden in sandbox without the Safe module");
+
+ /*
+ * ":perl"
+@@ -1019,13 +1020,12 @@ ex_perl(exarg_T *eap)
+ vim_free(script);
+ }
+
+-#ifdef HAVE_SANDBOX
+- if (sandbox)
++ if (sandbox || secure)
+ {
+ safe = perl_get_sv("VIM::safe", FALSE);
+ # ifndef MAKE_TEST /* avoid a warning for unreachable code */
+ if (safe == NULL || !SvTRUE(safe))
+- emsg(_("E299: Perl evaluation forbidden in sandbox without the Safe module"));
++ emsg(_(e_perlsandbox));
+ else
+ # endif
+ {
+@@ -1037,7 +1037,6 @@ ex_perl(exarg_T *eap)
+ }
+ }
+ else
+-#endif
+ perl_eval_sv(sv, G_DISCARD | G_NOARGS);
+
+ SvREFCNT_dec(sv);
+@@ -1298,13 +1297,12 @@ do_perleval(char_u *str, typval_T *rettv)
+ ENTER;
+ SAVETMPS;
+
+-#ifdef HAVE_SANDBOX
+- if (sandbox)
++ if (sandbox || secure)
+ {
+ safe = get_sv("VIM::safe", FALSE);
+ # ifndef MAKE_TEST /* avoid a warning for unreachable code */
+ if (safe == NULL || !SvTRUE(safe))
+- emsg(_("E299: Perl evaluation forbidden in sandbox without the Safe module"));
++ emsg(_(e_perlsandbox));
+ else
+ # endif
+ {
+@@ -1320,7 +1318,6 @@ do_perleval(char_u *str, typval_T *rettv)
+ }
+ }
+ else
+-#endif /* HAVE_SANDBOX */
+ sv = eval_pv((char *)str, 0);
+
+ if (sv) {
+diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
+index 5857a22..2ca5f2b 100644
+--- a/src/testdir/Make_all.mak
++++ b/src/testdir/Make_all.mak
+@@ -213,6 +213,7 @@ NEW_TESTS = \
+ test_regexp_utf8 \
+ test_registers \
+ test_reltime \
++ test_restricted \
+ test_retab \
+ test_ruby \
+ test_scriptnames \
+@@ -375,6 +376,7 @@ NEW_TESTS_RES = \
+ test_quotestar.res \
+ test_regex_char_classes.res \
+ test_registers.res \
++ test_restricted.res \
+ test_retab.res \
+ test_ruby.res \
+ test_scriptnames.res \
+diff --git a/src/testdir/test_restricted.vim b/src/testdir/test_restricted.vim
+new file mode 100644
+index 0000000..9dd937c
+--- /dev/null
++++ b/src/testdir/test_restricted.vim
+@@ -0,0 +1,107 @@
++" Test for "rvim" or "vim -Z"
++
++source shared.vim
++
++func Test_restricted()
++ let cmd = GetVimCommand('Xrestricted')
++ if cmd == ''
++ return
++ endif
++
++ call writefile([
++ \ "silent !ls",
++ \ "call writefile([v:errmsg], 'Xrestrout')",
++ \ "qa!",
++ \ ], 'Xrestricted')
++ call system(cmd . ' -Z')
++ call assert_match('E145:', join(readfile('Xrestrout')))
++
++ call delete('Xrestricted')
++ call delete('Xrestrout')
++endfunc
++
++func Run_restricted_test(ex_cmd, error)
++ let cmd = GetVimCommand('Xrestricted')
++ if cmd == ''
++ return
++ endif
++
++ call writefile([
++ \ a:ex_cmd,
++ \ "call writefile([v:errmsg], 'Xrestrout')",
++ \ "qa!",
++ \ ], 'Xrestricted')
++ call system(cmd . ' -Z')
++ call assert_match(a:error, join(readfile('Xrestrout')))
++
++ call delete('Xrestricted')
++ call delete('Xrestrout')
++endfunc
++
++func Test_restricted_lua()
++ if !has('lua')
++ throw 'Skipped: Lua is not supported'
++ endif
++ call Run_restricted_test('lua print("Hello, Vim!")', 'E981:')
++ call Run_restricted_test('luado return "hello"', 'E981:')
++ call Run_restricted_test('luafile somefile', 'E981:')
++ call Run_restricted_test('call luaeval("expression")', 'E145:')
++endfunc
++
++func Test_restricted_mzscheme()
++ if !has('mzscheme')
++ throw 'Skipped: MzScheme is not supported'
++ endif
++ call Run_restricted_test('mzscheme statement', 'E981:')
++ call Run_restricted_test('mzfile somefile', 'E981:')
++ call Run_restricted_test('call mzeval("expression")', 'E145:')
++endfunc
++
++func Test_restricted_perl()
++ if !has('perl')
++ throw 'Skipped: Perl is not supported'
++ endif
++ " TODO: how to make Safe mode fail?
++ " call Run_restricted_test('perl system("ls")', 'E981:')
++ " call Run_restricted_test('perldo system("hello")', 'E981:')
++ " call Run_restricted_test('perlfile somefile', 'E981:')
++ " call Run_restricted_test('call perleval("system(\"ls\")")', 'E145:')
++endfunc
++
++func Test_restricted_python()
++ if !has('python')
++ throw 'Skipped: Python is not supported'
++ endif
++ call Run_restricted_test('python print "hello"', 'E981:')
++ call Run_restricted_test('pydo return "hello"', 'E981:')
++ call Run_restricted_test('pyfile somefile', 'E981:')
++ call Run_restricted_test('call pyeval("expression")', 'E145:')
++endfunc
++
++func Test_restricted_python3()
++ if !has('python3')
++ throw 'Skipped: Python3 is not supported'
++ endif
++ call Run_restricted_test('py3 print "hello"', 'E981:')
++ call Run_restricted_test('py3do return "hello"', 'E981:')
++ call Run_restricted_test('py3file somefile', 'E981:')
++ call Run_restricted_test('call py3eval("expression")', 'E145:')
++endfunc
++
++func Test_restricted_ruby()
++ if !has('ruby')
++ throw 'Skipped: Ruby is not supported'
++ endif
++ call Run_restricted_test('ruby print "Hello"', 'E981:')
++ call Run_restricted_test('rubydo print "Hello"', 'E981:')
++ call Run_restricted_test('rubyfile somefile', 'E981:')
++endfunc
++
++func Test_restricted_tcl()
++ if !has('tcl')
++ throw 'Skipped: Tcl is not supported'
++ endif
++ call Run_restricted_test('tcl puts "Hello"', 'E981:')
++ call Run_restricted_test('tcldo puts "Hello"', 'E981:')
++ call Run_restricted_test('tclfile somefile', 'E981:')
++endfunc
+diff --git a/src/version.c b/src/version.c
+index 1b5d863..adb3441 100644
+--- a/src/version.c
++++ b/src/version.c
+@@ -809,6 +809,8 @@ static int included_patches[] =
+ 948,
+ /**/
+ 884,
++/**/
++ 881,
+ /**/
+ 878,
+ /**/
diff --git a/debian/patches/upstream/patch-8.1.0883-missing-some-changes-for-Ex-commands.patch b/debian/patches/upstream/patch-8.1.0883-missing-some-changes-for-Ex-commands.patch
new file mode 100644
index 0000000..6f2d6eb
--- /dev/null
+++ b/debian/patches/upstream/patch-8.1.0883-missing-some-changes-for-Ex-commands.patch
@@ -0,0 +1,150 @@
+From: Bram Moolenaar <Bram@vim.org>
+Date: Fri, 8 Feb 2019 16:50:26 +0100
+Subject: patch 8.1.0883: missing some changes for Ex commands
+
+Problem: Missing some changes for Ex commands.
+Solution: Add mising changes in header file.
+(cherry picked from commit 54d6fe5e60c0c488a424c078963ead40ae7dc397)
+---
+ src/ex_cmds.h | 45 +++++++++++++++++++++++----------------------
+ src/version.c | 2 ++
+ 2 files changed, 25 insertions(+), 22 deletions(-)
+
+diff --git a/src/ex_cmds.h b/src/ex_cmds.h
+index 07afb00..eed4ce2 100644
+--- a/src/ex_cmds.h
++++ b/src/ex_cmds.h
+@@ -57,6 +57,7 @@
+ * curbuf_lock is set */
+ #define MODIFY 0x200000L /* forbidden in non-'modifiable' buffer */
+ #define EXFLAGS 0x400000L /* allow flags after count in argument */
++#define RESTRICT 0x800000L /* forbidden in restricted mode */
+ #define FILES (XFILE | EXTRA) /* multiple extra files allowed */
+ #define WORD1 (EXTRA | NOSPC) /* one extra word allowed */
+ #define FILE1 (FILES | NOSPC) /* 1 file allowed, defaults to current file */
+@@ -861,13 +862,13 @@ EX(CMD_lunmap, "lunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN,
+ ADDR_LINES),
+ EX(CMD_lua, "lua", ex_lua,
+- RANGE|EXTRA|NEEDARG|CMDWIN,
++ RANGE|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_luado, "luado", ex_luado,
+- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN,
++ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_luafile, "luafile", ex_luafile,
+- RANGE|FILE1|NEEDARG|CMDWIN,
++ RANGE|FILE1|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_lvimgrep, "lvimgrep", ex_vimgrep,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE,
+@@ -930,10 +931,10 @@ EX(CMD_mode, "mode", ex_mode,
+ WORD1|TRLBAR|CMDWIN,
+ ADDR_LINES),
+ EX(CMD_mzscheme, "mzscheme", ex_mzscheme,
+- RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|SBOXOK,
++ RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|SBOXOK|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_mzfile, "mzfile", ex_mzfile,
+- RANGE|FILE1|NEEDARG|CMDWIN,
++ RANGE|FILE1|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_next, "next", ex_next,
+ RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR,
+@@ -1116,37 +1117,37 @@ EX(CMD_pwd, "pwd", ex_pwd,
+ TRLBAR|CMDWIN,
+ ADDR_LINES),
+ EX(CMD_python, "python", ex_python,
+- RANGE|EXTRA|NEEDARG|CMDWIN,
++ RANGE|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_pydo, "pydo", ex_pydo,
+- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN,
++ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_pyfile, "pyfile", ex_pyfile,
+- RANGE|FILE1|NEEDARG|CMDWIN,
++ RANGE|FILE1|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_py3, "py3", ex_py3,
+- RANGE|EXTRA|NEEDARG|CMDWIN,
++ RANGE|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_py3do, "py3do", ex_py3do,
+- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN,
++ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_python3, "python3", ex_py3,
+- RANGE|EXTRA|NEEDARG|CMDWIN,
++ RANGE|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_py3file, "py3file", ex_py3file,
+- RANGE|FILE1|NEEDARG|CMDWIN,
++ RANGE|FILE1|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_pyx, "pyx", ex_pyx,
+- RANGE|EXTRA|NEEDARG|CMDWIN,
++ RANGE|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_pyxdo, "pyxdo", ex_pyxdo,
+- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN,
++ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_pythonx, "pythonx", ex_pyx,
+- RANGE|EXTRA|NEEDARG|CMDWIN,
++ RANGE|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_pyxfile, "pyxfile", ex_pyxfile,
+- RANGE|FILE1|NEEDARG|CMDWIN,
++ RANGE|FILE1|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_quit, "quit", ex_quit,
+ BANG|RANGE|COUNT|NOTADR|TRLBAR|CMDWIN,
+@@ -1203,13 +1204,13 @@ EX(CMD_runtime, "runtime", ex_runtime,
+ BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN,
+ ADDR_LINES),
+ EX(CMD_ruby, "ruby", ex_ruby,
+- RANGE|EXTRA|NEEDARG|CMDWIN,
++ RANGE|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_rubydo, "rubydo", ex_rubydo,
+- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN,
++ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_rubyfile, "rubyfile", ex_rubyfile,
+- RANGE|FILE1|NEEDARG|CMDWIN,
++ RANGE|FILE1|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_rundo, "rundo", ex_rundo,
+ NEEDARG|FILE1,
+@@ -1476,13 +1477,13 @@ EX(CMD_tabs, "tabs", ex_tabs,
+ TRLBAR|CMDWIN,
+ ADDR_TABS),
+ EX(CMD_tcl, "tcl", ex_tcl,
+- RANGE|EXTRA|NEEDARG|CMDWIN,
++ RANGE|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_tcldo, "tcldo", ex_tcldo,
+- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN,
++ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_tclfile, "tclfile", ex_tclfile,
+- RANGE|FILE1|NEEDARG|CMDWIN,
++ RANGE|FILE1|NEEDARG|CMDWIN|RESTRICT,
+ ADDR_LINES),
+ EX(CMD_tearoff, "tearoff", ex_tearoff,
+ NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN,
+diff --git a/src/version.c b/src/version.c
+index adb3441..6d29f39 100644
+--- a/src/version.c
++++ b/src/version.c
+@@ -809,6 +809,8 @@ static int included_patches[] =
+ 948,
+ /**/
+ 884,
++/**/
++ 883,
+ /**/
+ 881,
+ /**/
diff --git a/debian/patches/upstream/patch-8.1.0936-may-leak-memory-when-using-vartabstop.patch b/debian/patches/upstream/patch-8.1.0936-may-leak-memory-when-using-vartabstop.patch
new file mode 100644
index 0000000..8d1eebc
--- /dev/null
+++ b/debian/patches/upstream/patch-8.1.0936-may-leak-memory-when-using-vartabstop.patch
@@ -0,0 +1,95 @@
+From: Bram Moolenaar <Bram@vim.org>
+Date: Sat, 16 Feb 2019 19:05:11 +0100
+Subject: patch 8.1.0936: may leak memory when using 'vartabstop'
+
+Problem: May leak memory when using 'vartabstop'. (Kuang-che Wu)
+Solution: Fix handling allocated memory for 'vartabstop'. (closes #3976)
+(cherry picked from commit 55c77cf2ea9c15e1ec75d1faf702ec3c9e325271)
+---
+ src/buffer.c | 4 +---
+ src/option.c | 13 +++++++++----
+ src/version.c | 2 ++
+ 3 files changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/src/buffer.c b/src/buffer.c
+index 2c5c282..590a63c 100644
+--- a/src/buffer.c
++++ b/src/buffer.c
+@@ -2170,9 +2170,7 @@ free_buf_options(
+ vim_free(buf->b_p_vsts_array);
+ buf->b_p_vsts_array = NULL;
+ clear_string_option(&buf->b_p_vts);
+- if (buf->b_p_vts_array)
+- vim_free(buf->b_p_vts_array);
+- buf->b_p_vts_array = NULL;
++ VIM_CLEAR(buf->b_p_vts_array);
+ #endif
+ #ifdef FEAT_KEYMAP
+ clear_string_option(&buf->b_p_keymap);
+diff --git a/src/option.c b/src/option.c
+index e3f5f5d..4d067c0 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -5611,7 +5611,9 @@ didset_options2(void)
+ (void)check_clipboard_option();
+ #endif
+ #ifdef FEAT_VARTABS
++ vim_free(curbuf->b_p_vsts_array);
+ tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
++ vim_free(curbuf->b_p_vts_array);
+ tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array);
+ #endif
+ }
+@@ -7587,14 +7589,14 @@ did_set_string_option(
+ if (errmsg == NULL)
+ {
+ int *oldarray = curbuf->b_p_vts_array;
++
+ if (tabstop_set(*varp, &(curbuf->b_p_vts_array)))
+ {
+- if (oldarray)
+- vim_free(oldarray);
++ vim_free(oldarray);
+ #ifdef FEAT_FOLDING
+ if (foldmethodIsIndent(curwin))
+ foldUpdateAll(curwin);
+-#endif /* FEAT_FOLDING */
++#endif
+ }
+ else
+ errmsg = e_invarg;
+@@ -12800,10 +12802,11 @@ check_ff_value(char_u *p)
+ return check_opt_strings(p, p_ff_values, FALSE);
+ }
+
+-#ifdef FEAT_VARTABS
++#if defined(FEAT_VARTABS) || defined(PROTO)
+
+ /*
+ * Set the integer values corresponding to the string setting of 'vartabstop'.
++ * "array" will be set, caller must free it if needed.
+ */
+ int
+ tabstop_set(char_u *var, int **array)
+@@ -12846,6 +12849,8 @@ tabstop_set(char_u *var, int **array)
+ }
+
+ *array = (int *)alloc((unsigned) ((valcount + 1) * sizeof(int)));
++ if (*array == NULL)
++ return FALSE;
+ (*array)[0] = valcount;
+
+ t = 1;
+diff --git a/src/version.c b/src/version.c
+index 6d29f39..6bac28e 100644
+--- a/src/version.c
++++ b/src/version.c
+@@ -807,6 +807,8 @@ static int included_patches[] =
+ 1046,
+ /**/
+ 948,
++/**/
++ 936,
+ /**/
+ 884,
+ /**/
diff --git a/debian/patches/upstream/patch-8.2.3402-invalid-memory-access-when-using-retab-wit.patch b/debian/patches/upstream/patch-8.2.3402-invalid-memory-access-when-using-retab-wit.patch
new file mode 100644
index 0000000..ca826e0
--- /dev/null
+++ b/debian/patches/upstream/patch-8.2.3402-invalid-memory-access-when-using-retab-wit.patch
@@ -0,0 +1,196 @@
+From: Bram Moolenaar <Bram@vim.org>
+Date: Sat, 4 Sep 2021 18:47:28 +0200
+Subject: patch 8.2.3402: invalid memory access when using :retab with large
+ value
+
+Problem: Invalid memory access when using :retab with large value.
+Solution: Check the number is positive.
+(cherry picked from commit b7081e135a16091c93f6f5f7525a5c58fb7ca9f9)
+---
+ src/ex_cmds.c | 2 +-
+ src/option.c | 46 +++++++++++++++++++++++++++-------------------
+ src/testdir/test_retab.vim | 3 +++
+ src/version.c | 1 +
+ 4 files changed, 32 insertions(+), 20 deletions(-)
+
+diff --git a/src/ex_cmds.c b/src/ex_cmds.c
+index 681ef42..08d71e4 100644
+--- a/src/ex_cmds.c
++++ b/src/ex_cmds.c
+@@ -698,7 +698,7 @@ ex_retab(exarg_T *eap)
+
+ #ifdef FEAT_VARTABS
+ new_ts_str = eap->arg;
+- if (!tabstop_set(eap->arg, &new_vts_array))
++ if (tabstop_set(eap->arg, &new_vts_array) == FAIL)
+ return;
+ while (vim_isdigit(*(eap->arg)) || *(eap->arg) == ',')
+ ++(eap->arg);
+diff --git a/src/option.c b/src/option.c
+index 4d067c0..3ebd443 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -5612,9 +5612,9 @@ didset_options2(void)
+ #endif
+ #ifdef FEAT_VARTABS
+ vim_free(curbuf->b_p_vsts_array);
+- tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
++ (void)tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
+ vim_free(curbuf->b_p_vts_array);
+- tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array);
++ (void)tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array);
+ #endif
+ }
+
+@@ -7551,7 +7551,7 @@ did_set_string_option(
+ if (errmsg == NULL)
+ {
+ int *oldarray = curbuf->b_p_vsts_array;
+- if (tabstop_set(*varp, &(curbuf->b_p_vsts_array)))
++ if (tabstop_set(*varp, &(curbuf->b_p_vsts_array)) == OK)
+ {
+ if (oldarray)
+ vim_free(oldarray);
+@@ -7590,7 +7590,7 @@ did_set_string_option(
+ {
+ int *oldarray = curbuf->b_p_vts_array;
+
+- if (tabstop_set(*varp, &(curbuf->b_p_vts_array)))
++ if (tabstop_set(*varp, &(curbuf->b_p_vts_array)) == OK)
+ {
+ vim_free(oldarray);
+ #ifdef FEAT_FOLDING
+@@ -11395,7 +11395,7 @@ buf_copy_options(buf_T *buf, int flags)
+ #ifdef FEAT_VARTABS
+ buf->b_p_vsts = vim_strsave(p_vsts);
+ if (p_vsts && p_vsts != empty_option)
+- tabstop_set(p_vsts, &buf->b_p_vsts_array);
++ (void)tabstop_set(p_vsts, &buf->b_p_vsts_array);
+ else
+ buf->b_p_vsts_array = 0;
+ buf->b_p_vsts_nopaste = p_vsts_nopaste
+@@ -11524,7 +11524,7 @@ buf_copy_options(buf_T *buf, int flags)
+ buf->b_p_isk = save_p_isk;
+ #ifdef FEAT_VARTABS
+ if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
+- tabstop_set(p_vts, &buf->b_p_vts_array);
++ (void)tabstop_set(p_vts, &buf->b_p_vts_array);
+ else
+ buf->b_p_vts_array = NULL;
+ #endif
+@@ -11537,7 +11537,7 @@ buf_copy_options(buf_T *buf, int flags)
+ #ifdef FEAT_VARTABS
+ buf->b_p_vts = vim_strsave(p_vts);
+ if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
+- tabstop_set(p_vts, &buf->b_p_vts_array);
++ (void)tabstop_set(p_vts, &buf->b_p_vts_array);
+ else
+ buf->b_p_vts_array = NULL;
+ #endif
+@@ -12435,7 +12435,7 @@ paste_option_changed(void)
+ if (buf->b_p_vsts_array)
+ vim_free(buf->b_p_vsts_array);
+ if (buf->b_p_vsts && buf->b_p_vsts != empty_option)
+- tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
++ (void)tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
+ else
+ buf->b_p_vsts_array = 0;
+ #endif
+@@ -12807,18 +12807,19 @@ check_ff_value(char_u *p)
+ /*
+ * Set the integer values corresponding to the string setting of 'vartabstop'.
+ * "array" will be set, caller must free it if needed.
++ * Return FAIL for an error.
+ */
+ int
+ tabstop_set(char_u *var, int **array)
+ {
+- int valcount = 1;
+- int t;
+- char_u *cp;
++ int valcount = 1;
++ int t;
++ char_u *cp;
+
+ if (var[0] == NUL || (var[0] == '0' && var[1] == NUL))
+ {
+ *array = NULL;
+- return TRUE;
++ return OK;
+ }
+
+ for (cp = var; *cp != NUL; ++cp)
+@@ -12832,8 +12833,8 @@ tabstop_set(char_u *var, int **array)
+ if (cp != end)
+ emsg(_(e_positive));
+ else
+- emsg(_(e_invarg));
+- return FALSE;
++ semsg(_(e_invarg2), cp);
++ return FAIL;
+ }
+ }
+
+@@ -12844,26 +12845,33 @@ tabstop_set(char_u *var, int **array)
+ ++valcount;
+ continue;
+ }
+- emsg(_(e_invarg));
+- return FALSE;
++ semsg(_(e_invarg2), var);
++ return FAIL;
+ }
+
+ *array = (int *)alloc((unsigned) ((valcount + 1) * sizeof(int)));
+ if (*array == NULL)
+- return FALSE;
++ return FAIL;
+ (*array)[0] = valcount;
+
+ t = 1;
+ for (cp = var; *cp != NUL;)
+ {
+- (*array)[t++] = atoi((char *)cp);
++ int n = atoi((char *)cp);
++
++ if (n < 0 || n > 9999)
++ {
++ semsg(_(e_invarg2), cp);
++ return FAIL;
++ }
++ (*array)[t++] = n;
+ while (*cp != NUL && *cp != ',')
+ ++cp;
+ if (*cp != NUL)
+ ++cp;
+ }
+
+- return TRUE;
++ return OK;
+ }
+
+ /*
+diff --git a/src/testdir/test_retab.vim b/src/testdir/test_retab.vim
+index f11a32b..e7b8946 100644
+--- a/src/testdir/test_retab.vim
++++ b/src/testdir/test_retab.vim
+@@ -74,4 +74,7 @@ endfunc
+ func Test_retab_error()
+ call assert_fails('retab -1', 'E487:')
+ call assert_fails('retab! -1', 'E487:')
++ call assert_fails('ret -1000', 'E487:')
++ call assert_fails('ret 10000', 'E475:')
++ call assert_fails('ret 80000000000000000000', 'E475:')
+ endfunc
+diff --git a/src/version.c b/src/version.c
+index 6bac28e..bd19aac 100644
+--- a/src/version.c
++++ b/src/version.c
+@@ -2580,6 +2580,7 @@ static int included_patches[] =
+ */
+ static char *(extra_patches[]) =
+ { /* Add your patch description below this line */
++ "8.2.3402",
+ /**/
+ NULL
+ };
diff --git a/debian/patches/upstream/patch-8.2.3403-memory-leak-for-retab-with-invalid-argumen.patch b/debian/patches/upstream/patch-8.2.3403-memory-leak-for-retab-with-invalid-argumen.patch
new file mode 100644
index 0000000..18f205c
--- /dev/null
+++ b/debian/patches/upstream/patch-8.2.3403-memory-leak-for-retab-with-invalid-argumen.patch
@@ -0,0 +1,67 @@
+From: Bram Moolenaar <Bram@vim.org>
+Date: Sat, 4 Sep 2021 21:20:41 +0200
+Subject: patch 8.2.3403: memory leak for :retab with invalid argument
+
+Problem: Memory leak for :retab with invalid argument.
+Solution: Free the memory. Make error messages consistent.
+(cherry picked from commit 2ddb89f8a94425cda1e5491efc80c1ccccb6e08e)
+---
+ src/ex_cmds.c | 10 ++++++++--
+ src/option.c | 3 +++
+ src/version.c | 1 +
+ 3 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/src/ex_cmds.c b/src/ex_cmds.c
+index 08d71e4..3200173 100644
+--- a/src/ex_cmds.c
++++ b/src/ex_cmds.c
+@@ -714,12 +714,18 @@ ex_retab(exarg_T *eap)
+ else
+ new_ts_str = vim_strnsave(new_ts_str, eap->arg - new_ts_str);
+ #else
+- new_ts = getdigits(&(eap->arg));
+- if (new_ts < 0)
++ ptr = eap->arg;
++ new_ts = getdigits(&ptr);
++ if (new_ts < 0 && *eap->arg == '-')
+ {
+ emsg(_(e_positive));
+ return;
+ }
++ if (new_ts < 0 || new_ts > 9999)
++ {
++ semsg(_(e_invarg2), eap->arg);
++ return;
++ }
+ if (new_ts == 0)
+ new_ts = curbuf->b_p_ts;
+ #endif
+diff --git a/src/option.c b/src/option.c
+index 3ebd443..12d903f 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -12859,9 +12859,12 @@ tabstop_set(char_u *var, int **array)
+ {
+ int n = atoi((char *)cp);
+
++ // Catch negative values, overflow and ridiculous big values.
+ if (n < 0 || n > 9999)
+ {
+ semsg(_(e_invarg2), cp);
++ vim_free(*array);
++ *array = NULL;
+ return FAIL;
+ }
+ (*array)[t++] = n;
+diff --git a/src/version.c b/src/version.c
+index bd19aac..cfe1486 100644
+--- a/src/version.c
++++ b/src/version.c
+@@ -2581,6 +2581,7 @@ static int included_patches[] =
+ static char *(extra_patches[]) =
+ { /* Add your patch description below this line */
+ "8.2.3402",
++ "8.2.3403",
+ /**/
+ NULL
+ };
diff --git a/debian/patches/upstream/patch-8.2.3409-reading-beyond-end-of-line-with-invalid-ut.patch b/debian/patches/upstream/patch-8.2.3409-reading-beyond-end-of-line-with-invalid-ut.patch
new file mode 100644
index 0000000..0ad00be
--- /dev/null
+++ b/debian/patches/upstream/patch-8.2.3409-reading-beyond-end-of-line-with-invalid-ut.patch
@@ -0,0 +1,58 @@
+From: Bram Moolenaar <Bram@vim.org>
+Date: Tue, 7 Sep 2021 19:26:53 +0200
+Subject: patch 8.2.3409: reading beyond end of line with invalid utf-8
+ character
+
+Problem: Reading beyond end of line with invalid utf-8 character.
+Solution: Check for NUL when advancing.
+(cherry picked from commit 65b605665997fad54ef39a93199e305af2fe4d7f)
+---
+ src/regexp_nfa.c | 3 ++-
+ src/testdir/test_regexp_utf8.vim | 10 ++++++++++
+ src/version.c | 1 +
+ 3 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
+index 031a6cf..b9562c6 100644
+--- a/src/regexp_nfa.c
++++ b/src/regexp_nfa.c
+@@ -5414,7 +5414,8 @@ find_match_text(colnr_T startcol, int regstart, char_u *match_text)
+ match = FALSE;
+ break;
+ }
+- len2 += MB_CHAR2LEN(c2);
++ len2 += enc_utf8 ? utf_ptr2len(rex.line + col + len2)
++ : MB_CHAR2LEN(c2);
+ }
+ if (match
+ /* check that no composing char follows */
+diff --git a/src/testdir/test_regexp_utf8.vim b/src/testdir/test_regexp_utf8.vim
+index 98b9e73..75485dc 100644
+--- a/src/testdir/test_regexp_utf8.vim
++++ b/src/testdir/test_regexp_utf8.vim
+@@ -206,3 +206,13 @@ func Test_large_class()
+ call assert_equal(1, "\u3042" =~# '[\u3000-\u4000]')
+ set re=0
+ endfunc
++
++func Test_match_invalid_byte()
++ call writefile(0z630a.765d30aa0a.2e0a.790a.4030, 'Xinvalid')
++ new
++ source Xinvalid
++ bwipe!
++ call delete('Xinvalid')
++endfunc
++
++" vim: shiftwidth=2 sts=2 expandtab
+diff --git a/src/version.c b/src/version.c
+index cfe1486..a3eca1e 100644
+--- a/src/version.c
++++ b/src/version.c
+@@ -2582,6 +2582,7 @@ static char *(extra_patches[]) =
+ { /* Add your patch description below this line */
+ "8.2.3402",
+ "8.2.3403",
++ "8.2.3409",
+ /**/
+ NULL
+ };
diff --git a/debian/patches/upstream/patch-8.2.3428-using-freed-memory-when-replacing.patch b/debian/patches/upstream/patch-8.2.3428-using-freed-memory-when-replacing.patch
new file mode 100644
index 0000000..16832ad
--- /dev/null
+++ b/debian/patches/upstream/patch-8.2.3428-using-freed-memory-when-replacing.patch
@@ -0,0 +1,78 @@
+From: Bram Moolenaar <Bram@vim.org>
+Date: Sat, 11 Sep 2021 21:14:20 +0200
+Subject: patch 8.2.3428: using freed memory when replacing
+
+Problem: Using freed memory when replacing. (Dhiraj Mishra)
+Solution: Get the line pointer after calling ins_copychar().
+(cherry picked from commit 35a9a00afcb20897d462a766793ff45534810dc3)
+---
+ src/normal.c | 10 +++++++---
+ src/testdir/test_edit.vim | 14 ++++++++++++++
+ src/version.c | 1 +
+ 3 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/src/normal.c b/src/normal.c
+index 41af966..2c36c15 100644
+--- a/src/normal.c
++++ b/src/normal.c
+@@ -7056,19 +7056,23 @@ nv_replace(cmdarg_T *cap)
+ {
+ /*
+ * Get ptr again, because u_save and/or showmatch() will have
+- * released the line. At the same time we let know that the
+- * line will be changed.
++ * released the line. This may also happen in ins_copychar().
++ * At the same time we let know that the line will be changed.
+ */
+- ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
+ if (cap->nchar == Ctrl_E || cap->nchar == Ctrl_Y)
+ {
+ int c = ins_copychar(curwin->w_cursor.lnum
+ + (cap->nchar == Ctrl_Y ? -1 : 1));
++
++ ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
+ if (c != NUL)
+ ptr[curwin->w_cursor.col] = c;
+ }
+ else
++ {
++ ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
+ ptr[curwin->w_cursor.col] = cap->nchar;
++ }
+ if (p_sm && msg_silent == 0)
+ showmatch(cap->nchar);
+ ++curwin->w_cursor.col;
+diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
+index 9a60d01..2e050c2 100644
+--- a/src/testdir/test_edit.vim
++++ b/src/testdir/test_edit.vim
+@@ -1436,3 +1436,17 @@ func Test_leave_insert_autocmd()
+ au! InsertLeave
+ iunmap x
+ endfunc
++
++" Test for getting the character of the line below after "p"
++func Test_edit_put_CTRL_E()
++ set encoding=latin1
++ new
++ let @" = ''
++ sil! norm orggRx
++ sil! norm pr
++ call assert_equal(['r', 'r'], getline(1, 2))
++ bwipe!
++ set encoding=utf-8
++endfunc
++
++" vim: shiftwidth=2 sts=2 expandtab
+diff --git a/src/version.c b/src/version.c
+index a3eca1e..c4a502f 100644
+--- a/src/version.c
++++ b/src/version.c
+@@ -2583,6 +2583,7 @@ static char *(extra_patches[]) =
+ "8.2.3402",
+ "8.2.3403",
+ "8.2.3409",
++ "8.2.3428",
+ /**/
+ NULL
+ };