From 62a24b4a1c58c08b46ea7e3e7a6a114932d360c4 Mon Sep 17 00:00:00 2001 From: weiwei_tiantian Date: Thu, 7 Jul 2022 09:23:50 +0800 Subject: [PATCH 1/3] fix CVE-2022-2207 CVE-2022-2208 --- backport-CVE-2022-2207.patch | 29 + backport-CVE-2022-2208.patch | 63 ++ ...ort-cannot-list-options-one-per-line.patch | 579 ++++++++++++++++++ backport-test-for-DiffUpdated-fails.patch | 28 + vim.spec | 12 +- 5 files changed, 710 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2022-2207.patch create mode 100644 backport-CVE-2022-2208.patch create mode 100644 backport-cannot-list-options-one-per-line.patch create mode 100644 backport-test-for-DiffUpdated-fails.patch diff --git a/backport-CVE-2022-2207.patch b/backport-CVE-2022-2207.patch new file mode 100644 index 0000000..613cc38 --- /dev/null +++ b/backport-CVE-2022-2207.patch @@ -0,0 +1,29 @@ +From 0971c7a4e537ea120a6bb2195960be8d0815e97b Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sun, 26 Jun 2022 12:59:02 +0100 +Subject: [PATCH] patch 8.2.5162: reading before the start of the line with BS + in Replace mode + +Problem: Reading before the start of the line with BS in Replace mode. +Solution: Check the cursor column is more than zero. + +--- + src/edit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/edit.c b/src/edit.c +index c4ede2b..bc0b7dc 100644 +--- a/src/edit.c ++++ b/src/edit.c +@@ -4761,7 +4761,7 @@ ins_bs( + #endif + + // delete characters until we are at or before want_vcol +- while (vcol > want_vcol ++ while (vcol > want_vcol && curwin->w_cursor.col > 0 + && (cc = *(ml_get_cursor() - 1), VIM_ISWHITE(cc))) + ins_bs_one(&vcol); + +-- +2.27.0 + diff --git a/backport-CVE-2022-2208.patch b/backport-CVE-2022-2208.patch new file mode 100644 index 0000000..a426430 --- /dev/null +++ b/backport-CVE-2022-2208.patch @@ -0,0 +1,63 @@ +From cd38bb4d83c942c4bad596835c6766cbf32e5195 Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sun, 26 Jun 2022 14:04:07 +0100 +Subject: [PATCH] patch 8.2.5163: crash when deleting buffers in diff mode + +Problem: Crash when deleting buffers in diff mode. +Solution: Recompute diffs later. Skip window without a valid buffer. +--- + src/diff.c | 10 ++++++++-- + src/testdir/test_diffmode.vim | 12 ++++++++++++ + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/src/diff.c b/src/diff.c +index f996904..8569a9f 100644 +--- a/src/diff.c ++++ b/src/diff.c +@@ -107,7 +107,12 @@ diff_buf_delete(buf_T *buf) + tp->tp_diffbuf[i] = NULL; + tp->tp_diff_invalid = TRUE; + if (tp == curtab) +- diff_redraw(TRUE); ++ { ++ // don't redraw right away, more might change or buffer state ++ // is invalid right now ++ need_diff_redraw = TRUE; ++ redraw_later(VALID); ++ } + } + } + } +@@ -655,7 +660,8 @@ diff_redraw( + + need_diff_redraw = FALSE; + FOR_ALL_WINDOWS(wp) +- if (wp->w_p_diff) ++ // when closing windows or wiping buffers skip invalid window ++ if (wp->w_p_diff && buf_valid(wp->w_buffer)) + { + redraw_win_later(wp, SOME_VALID); + #ifdef FEAT_FOLDING +diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim +index 61edbe2..5b48a75 100644 +--- a/src/testdir/test_diffmode.vim ++++ b/src/testdir/test_diffmode.vim +@@ -827,3 +827,15 @@ func Test_diff_maintains_change_mark() + bwipe! + bwipe! + endfunc ++ ++" This was trying to update diffs for a buffer being closed ++func Test_diff_only() ++ silent! lfile ++ set diff ++ lopen ++ norm o ++ silent! norm o ++ ++ set nodiff ++ %bwipe! ++endfunc +-- +2.27.0 + diff --git a/backport-cannot-list-options-one-per-line.patch b/backport-cannot-list-options-one-per-line.patch new file mode 100644 index 0000000..33bc413 --- /dev/null +++ b/backport-cannot-list-options-one-per-line.patch @@ -0,0 +1,579 @@ +From 09fac0422ed8538ecace4638944e7f5b95ae2e16 Mon Sep 17 00:00:00 2001 +From: root +Date: Thu, 7 Jul 2022 19:35:57 +0800 +Subject: [PATCH] 2207-1.patch + +--- + runtime/doc/options.txt | 12 +- + src/ex_cmds.h | 6 +- + src/ex_docmd.c | 18 --- + src/option.c | 34 ++++- + src/optiondefs.h | 2 +- + src/proto/option.pro | 1 + + src/testdir/test_options.vim | 9 +- + src/version.c | 2 + + src/vim.h | 13 +- + test.patch | 285 +++++++++++++++++++++++++++++++++++ + 10 files changed, 344 insertions(+), 38 deletions(-) + create mode 100644 test.patch + +diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt +index 2fced50..8f11253 100644 +--- a/runtime/doc/options.txt ++++ b/runtime/doc/options.txt +@@ -22,9 +22,13 @@ achieve special effects. These options come in three forms: + 1. Setting options *set-option* *E764* + + *:se* *:set* +-:se[t] Show all options that differ from their default value. ++:se[t][!] Show all options that differ from their default value. ++ When [!] is present every option is on a separate ++ line. + +-:se[t] all Show all but terminal options. ++:se[t][!] all Show all but terminal options. ++ When [!] is present every option is on a separate ++ line. + + :se[t] termcap Show all terminal options. Note that in the GUI the + key codes are not shown, because they are generated +@@ -287,7 +291,7 @@ happens when the buffer is not loaded, but they are lost when the buffer is + wiped out |:bwipe|. + + *:setl* *:setlocal* +-:setl[ocal] ... Like ":set" but set only the value local to the ++:setl[ocal][!] ... Like ":set" but set only the value local to the + current buffer or window. Not all options have a + local value. If the option does not have a local + value the global value is set. +@@ -309,7 +313,7 @@ wiped out |:bwipe|. + {option}, so that the global value will be used. + + *:setg* *:setglobal* +-:setg[lobal] ... Like ":set" but set only the global value for a local ++:setg[lobal][!] ... Like ":set" but set only the global value for a local + option without changing the local value. + When displaying an option, the global value is shown. + With the "all" argument: display global values for all +diff --git a/src/ex_cmds.h b/src/ex_cmds.h +index 28ea6ee..605766a 100644 +--- a/src/ex_cmds.h ++++ b/src/ex_cmds.h +@@ -1307,16 +1307,16 @@ EXCMD(CMD_scscope, "scscope", ex_scscope, + EX_EXTRA|EX_NOTRLCOM, + ADDR_NONE), + EXCMD(CMD_set, "set", ex_set, +- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, + ADDR_NONE), + EXCMD(CMD_setfiletype, "setfiletype", ex_setfiletype, + EX_TRLBAR|EX_EXTRA|EX_NEEDARG|EX_CMDWIN, + ADDR_NONE), + EXCMD(CMD_setglobal, "setglobal", ex_set, +- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, + ADDR_NONE), + EXCMD(CMD_setlocal, "setlocal", ex_set, +- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, + ADDR_NONE), + EXCMD(CMD_sfind, "sfind", ex_splitview, + EX_BANG|EX_FILE1|EX_RANGE|EX_CMDARG|EX_ARGOPT|EX_TRLBAR|EX_NEEDARG, +diff --git a/src/ex_docmd.c b/src/ex_docmd.c +index b552440..1644573 100644 +--- a/src/ex_docmd.c ++++ b/src/ex_docmd.c +@@ -320,7 +320,6 @@ static void ex_setfiletype(exarg_T *eap); + # define ex_diffupdate ex_ni + #endif + static void ex_digraphs(exarg_T *eap); +-static void ex_set(exarg_T *eap); + #ifdef FEAT_SEARCH_EXTRA + static void ex_nohlsearch(exarg_T *eap); + #else +@@ -8499,23 +8498,6 @@ ex_digraphs(exarg_T *eap UNUSED) + #endif + } + +- static void +-ex_set(exarg_T *eap) +-{ +- int flags = 0; +- +- if (eap->cmdidx == CMD_setlocal) +- flags = OPT_LOCAL; +- else if (eap->cmdidx == CMD_setglobal) +- flags = OPT_GLOBAL; +-#if defined(FEAT_EVAL) && defined(FEAT_BROWSE) +- if (cmdmod.browse && flags == 0) +- ex_options(eap); +- else +-#endif +- (void)do_set(eap->arg, flags); +-} +- + #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) + void + set_no_hlsearch(int flag) +diff --git a/src/option.c b/src/option.c +index 382b01b..eb610dd 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -1066,6 +1066,27 @@ set_title_defaults(void) + } + #endif + ++ void ++ex_set(exarg_T *eap) ++{ ++ int flags = 0; ++ ++ if (eap->cmdidx == CMD_setlocal) ++ flags = OPT_LOCAL; ++ else if (eap->cmdidx == CMD_setglobal) ++ flags = OPT_GLOBAL; ++#if defined(FEAT_EVAL) && defined(FEAT_BROWSE) ++ if (cmdmod.browse && flags == 0) ++ ex_options(eap); ++ else ++#endif ++ { ++ if (eap->forceit) ++ flags |= OPT_ONECOLUMN; ++ (void)do_set(eap->arg, flags); ++ } ++} ++ + /* + * Parse 'arg' for option settings. + * +@@ -4354,7 +4375,7 @@ showoptions( + #define INC 20 + #define GAP 3 + +- items = ALLOC_MULT(struct vimoption *, PARAM_COUNT); ++ items = ALLOC_MULT(struct vimoption *, OPTION_COUNT); + if (items == NULL) + return; + +@@ -4369,9 +4390,10 @@ showoptions( + msg_puts_title(_("\n--- Options ---")); + + /* +- * do the loop two times: ++ * Do the loop two times: + * 1. display the short items + * 2. display the long items (only strings and numbers) ++ * When "opt_flags" has OPT_ONECOLUMN do everything in run 2. + */ + for (run = 1; run <= 2 && !got_int; ++run) + { +@@ -4382,12 +4404,12 @@ showoptions( + for (p = &options[0]; p->fullname != NULL; p++) + { + // apply :filter /pat/ +- if (message_filtered((char_u *) p->fullname)) ++ if (message_filtered((char_u *)p->fullname)) + continue; + + varp = NULL; + isterm = istermoption(p); +- if (opt_flags != 0) ++ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) != 0) + { + if (p->indir != PV_NONE && !isterm) + varp = get_varp_scope(p, opt_flags); +@@ -4399,7 +4421,9 @@ showoptions( + || (all == 1 && !isterm) + || (all == 0 && !optval_default(p, varp, p_cp)))) + { +- if (p->flags & P_BOOL) ++ if (opt_flags & OPT_ONECOLUMN) ++ len = Columns; ++ else if (p->flags & P_BOOL) + len = 1; // a toggle option fits always + else + { +diff --git a/src/optiondefs.h b/src/optiondefs.h +index 8fda8bf..3670107 100644 +--- a/src/optiondefs.h ++++ b/src/optiondefs.h +@@ -3009,7 +3009,7 @@ static struct vimoption options[] = + {NULL, NULL, 0, NULL, PV_NONE, {NULL, NULL} SCTX_INIT} + }; + +-#define PARAM_COUNT (sizeof(options) / sizeof(struct vimoption)) ++#define OPTION_COUNT (sizeof(options) / sizeof(struct vimoption)) + + // The following is needed to make the gen_opt_test.vim script work. + // {" +diff --git a/src/proto/option.pro b/src/proto/option.pro +index dc07ee6..7da2cbf 100644 +--- a/src/proto/option.pro ++++ b/src/proto/option.pro +@@ -8,6 +8,7 @@ void set_init_2(void); + void set_init_3(void); + void set_helplang_default(char_u *lang); + void set_title_defaults(void); ++void ex_set(exarg_T *eap); + int do_set(char_u *arg, int opt_flags); + void did_set_option(int opt_idx, int opt_flags, int new_value, int value_checked); + int string_to_key(char_u *arg, int multi_byte); +diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim +index d4213c1..7584465 100644 +--- a/src/testdir/test_options.vim ++++ b/src/testdir/test_options.vim +@@ -44,7 +44,7 @@ func Test_wildchar() + set wildchar& + endfunc + +-func Test_options() ++func Test_options_command() + let caught = 'ok' + try + options +@@ -383,6 +383,13 @@ func Test_set_all() + set tw& iskeyword& splitbelow& + endfunc + ++func Test_set_one_column() ++ let out_mult = execute('set all')->split("\n") ++ let out_one = execute('set! all')->split("\n") ++ " one column should be two to four times as many lines ++ call assert_inrange(len(out_mult) * 2, len(out_mult) * 4, len(out_one)) ++endfunc ++ + func Test_set_values() + if filereadable('opt_test.vim') + source opt_test.vim +diff --git a/src/version.c b/src/version.c +index bd45631..4b6cc17 100644 +--- a/src/version.c ++++ b/src/version.c +@@ -742,6 +742,8 @@ static char *(features[]) = + + static int included_patches[] = + { /* Add new patch number below this line */ ++/**/ ++ 128, + /**/ + 3741, + /**/ +diff --git a/src/vim.h b/src/vim.h +index cd917a3..171b5dc 100644 +--- a/src/vim.h ++++ b/src/vim.h +@@ -1227,12 +1227,13 @@ typedef struct { + * When OPT_GLOBAL and OPT_LOCAL are both missing, set both local and global + * values, get local value. + */ +-#define OPT_FREE 1 // free old value if it was allocated +-#define OPT_GLOBAL 2 // use global value +-#define OPT_LOCAL 4 // use local value +-#define OPT_MODELINE 8 // option in modeline +-#define OPT_WINONLY 16 // only set window-local options +-#define OPT_NOWIN 32 // don't set window-local options ++#define OPT_FREE 0x01 // free old value if it was allocated ++#define OPT_GLOBAL 0x02 // use global value ++#define OPT_LOCAL 0x04 // use local value ++#define OPT_MODELINE 0x08 // option in modeline ++#define OPT_WINONLY 0x10 // only set window-local options ++#define OPT_NOWIN 0x20 // don't set window-local options ++#define OPT_ONECOLUMN 0x40 // list options one per line + + // Magic chars used in confirm dialog strings + #define DLG_BUTTON_SEP '\n' +diff --git a/test.patch b/test.patch +new file mode 100644 +index 0000000..bb09977 +--- /dev/null ++++ b/test.patch +@@ -0,0 +1,285 @@ ++From 6b915c0c0ee7ef82f8d3d310a4345e098cb929b0 Mon Sep 17 00:00:00 2001 ++From: Bram Moolenaar ++Date: Sat, 18 Jan 2020 15:53:19 +0100 ++Subject: [PATCH] patch 8.2.0128: cannot list options one per line ++ ++Problem: Cannot list options one per line. ++Solution: Use ":set!" to list one option per line. ++--- ++ runtime/doc/options.txt | 12 ++++++++---- ++ src/ex_cmds.h | 6 +++--- ++ src/ex_docmd.c | 18 ------------------ ++ src/option.c | 34 +++++++++++++++++++++++++++++----- ++ src/optiondefs.h | 2 +- ++ src/proto/option.pro | 1 + ++ src/testdir/test_options.vim | 9 ++++++++- ++ src/version.c | 2 ++ ++ src/vim.h | 13 +++++++------ ++ 9 files changed, 59 insertions(+), 38 deletions(-) ++ ++diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt ++index b86244feaf4a..5ee2ce13ac76 100644 ++--- a/runtime/doc/options.txt +++++ b/runtime/doc/options.txt ++@@ -22,9 +22,13 @@ achieve special effects. These options come in three forms: ++ 1. Setting options *set-option* *E764* ++ ++ *:se* *:set* ++-:se[t] Show all options that differ from their default value. +++:se[t][!] Show all options that differ from their default value. +++ When [!] is present every option is on a separate +++ line. ++ ++-:se[t] all Show all but terminal options. +++:se[t][!] all Show all but terminal options. +++ When [!] is present every option is on a separate +++ line. ++ ++ :se[t] termcap Show all terminal options. Note that in the GUI the ++ key codes are not shown, because they are generated ++@@ -287,7 +291,7 @@ happens when the buffer is not loaded, but they are lost when the buffer is ++ wiped out |:bwipe|. ++ ++ *:setl* *:setlocal* ++-:setl[ocal] ... Like ":set" but set only the value local to the +++:setl[ocal][!] ... Like ":set" but set only the value local to the ++ current buffer or window. Not all options have a ++ local value. If the option does not have a local ++ value the global value is set. ++@@ -309,7 +313,7 @@ wiped out |:bwipe|. ++ {option}, so that the global value will be used. ++ ++ *:setg* *:setglobal* ++-:setg[lobal] ... Like ":set" but set only the global value for a local +++:setg[lobal][!] ... Like ":set" but set only the global value for a local ++ option without changing the local value. ++ When displaying an option, the global value is shown. ++ With the "all" argument: display global values for all ++diff --git a/src/ex_cmds.h b/src/ex_cmds.h ++index 36a8ad4c2c16..53e49d519cc6 100644 ++--- a/src/ex_cmds.h +++++ b/src/ex_cmds.h ++@@ -1307,16 +1307,16 @@ EXCMD(CMD_scscope, "scscope", ex_scscope, ++ EX_EXTRA|EX_NOTRLCOM, ++ ADDR_NONE), ++ EXCMD(CMD_set, "set", ex_set, ++- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, +++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ ADDR_NONE), ++ EXCMD(CMD_setfiletype, "setfiletype", ex_setfiletype, ++ EX_TRLBAR|EX_EXTRA|EX_NEEDARG|EX_CMDWIN, ++ ADDR_NONE), ++ EXCMD(CMD_setglobal, "setglobal", ex_set, ++- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, +++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ ADDR_NONE), ++ EXCMD(CMD_setlocal, "setlocal", ex_set, ++- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, +++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ ADDR_NONE), ++ EXCMD(CMD_sfind, "sfind", ex_splitview, ++ EX_BANG|EX_FILE1|EX_RANGE|EX_CMDARG|EX_ARGOPT|EX_TRLBAR, ++diff --git a/src/ex_docmd.c b/src/ex_docmd.c ++index 51d85c3a2a0d..193cfcfdffab 100644 ++--- a/src/ex_docmd.c +++++ b/src/ex_docmd.c ++@@ -320,7 +320,6 @@ static void ex_setfiletype(exarg_T *eap); ++ # define ex_diffupdate ex_ni ++ #endif ++ static void ex_digraphs(exarg_T *eap); ++-static void ex_set(exarg_T *eap); ++ #ifdef FEAT_SEARCH_EXTRA ++ static void ex_nohlsearch(exarg_T *eap); ++ #else ++@@ -8488,23 +8487,6 @@ ex_digraphs(exarg_T *eap UNUSED) ++ #endif ++ } ++ ++- static void ++-ex_set(exarg_T *eap) ++-{ ++- int flags = 0; ++- ++- if (eap->cmdidx == CMD_setlocal) ++- flags = OPT_LOCAL; ++- else if (eap->cmdidx == CMD_setglobal) ++- flags = OPT_GLOBAL; ++-#if defined(FEAT_EVAL) && defined(FEAT_BROWSE) ++- if (cmdmod.browse && flags == 0) ++- ex_options(eap); ++- else ++-#endif ++- (void)do_set(eap->arg, flags); ++-} ++- ++ #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) ++ void ++ set_no_hlsearch(int flag) ++diff --git a/src/option.c b/src/option.c ++index 7c37326f931b..e24181af10ee 100644 ++--- a/src/option.c +++++ b/src/option.c ++@@ -1066,6 +1066,27 @@ set_title_defaults(void) ++ } ++ #endif ++ +++ void +++ex_set(exarg_T *eap) +++{ +++ int flags = 0; +++ +++ if (eap->cmdidx == CMD_setlocal) +++ flags = OPT_LOCAL; +++ else if (eap->cmdidx == CMD_setglobal) +++ flags = OPT_GLOBAL; +++#if defined(FEAT_EVAL) && defined(FEAT_BROWSE) +++ if (cmdmod.browse && flags == 0) +++ ex_options(eap); +++ else +++#endif +++ { +++ if (eap->forceit) +++ flags |= OPT_ONECOLUMN; +++ (void)do_set(eap->arg, flags); +++ } +++} +++ ++ /* ++ * Parse 'arg' for option settings. ++ * ++@@ -4349,7 +4370,7 @@ showoptions( ++ #define INC 20 ++ #define GAP 3 ++ ++- items = ALLOC_MULT(struct vimoption *, PARAM_COUNT); +++ items = ALLOC_MULT(struct vimoption *, OPTION_COUNT); ++ if (items == NULL) ++ return; ++ ++@@ -4364,9 +4385,10 @@ showoptions( ++ msg_puts_title(_("\n--- Options ---")); ++ ++ /* ++- * do the loop two times: +++ * Do the loop two times: ++ * 1. display the short items ++ * 2. display the long items (only strings and numbers) +++ * When "opt_flags" has OPT_ONECOLUMN do everything in run 2. ++ */ ++ for (run = 1; run <= 2 && !got_int; ++run) ++ { ++@@ -4377,12 +4399,12 @@ showoptions( ++ for (p = &options[0]; p->fullname != NULL; p++) ++ { ++ // apply :filter /pat/ ++- if (message_filtered((char_u *) p->fullname)) +++ if (message_filtered((char_u *)p->fullname)) ++ continue; ++ ++ varp = NULL; ++ isterm = istermoption(p); ++- if (opt_flags != 0) +++ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) != 0) ++ { ++ if (p->indir != PV_NONE && !isterm) ++ varp = get_varp_scope(p, opt_flags); ++@@ -4394,7 +4416,9 @@ showoptions( ++ || (all == 1 && !isterm) ++ || (all == 0 && !optval_default(p, varp, p_cp)))) ++ { ++- if (p->flags & P_BOOL) +++ if (opt_flags & OPT_ONECOLUMN) +++ len = Columns; +++ else if (p->flags & P_BOOL) ++ len = 1; // a toggle option fits always ++ else ++ { ++diff --git a/src/optiondefs.h b/src/optiondefs.h ++index 8fda8bff8cae..36701070dd11 100644 ++--- a/src/optiondefs.h +++++ b/src/optiondefs.h ++@@ -3009,7 +3009,7 @@ static struct vimoption options[] = ++ {NULL, NULL, 0, NULL, PV_NONE, {NULL, NULL} SCTX_INIT} ++ }; ++ ++-#define PARAM_COUNT (sizeof(options) / sizeof(struct vimoption)) +++#define OPTION_COUNT (sizeof(options) / sizeof(struct vimoption)) ++ ++ // The following is needed to make the gen_opt_test.vim script work. ++ // {" ++diff --git a/src/proto/option.pro b/src/proto/option.pro ++index dc07ee6b830f..7da2cbf982d8 100644 ++--- a/src/proto/option.pro +++++ b/src/proto/option.pro ++@@ -8,6 +8,7 @@ void set_init_2(void); ++ void set_init_3(void); ++ void set_helplang_default(char_u *lang); ++ void set_title_defaults(void); +++void ex_set(exarg_T *eap); ++ int do_set(char_u *arg, int opt_flags); ++ void did_set_option(int opt_idx, int opt_flags, int new_value, int value_checked); ++ int string_to_key(char_u *arg, int multi_byte); ++diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim ++index 636a24d6e9a0..7a74af652acb 100644 ++--- a/src/testdir/test_options.vim +++++ b/src/testdir/test_options.vim ++@@ -44,7 +44,7 @@ func Test_wildchar() ++ set wildchar& ++ endfunc ++ ++-func Test_options() +++func Test_options_command() ++ let caught = 'ok' ++ try ++ options ++@@ -388,6 +388,13 @@ func Test_set_all() ++ set tw& iskeyword& splitbelow& ++ endfunc ++ +++func Test_set_one_column() +++ let out_mult = execute('set all')->split("\n") +++ let out_one = execute('set! all')->split("\n") +++ " one column should be two to four times as many lines +++ call assert_inrange(len(out_mult) * 2, len(out_mult) * 4, len(out_one)) +++endfunc +++ ++ func Test_set_values() ++ if filereadable('opt_test.vim') ++ source opt_test.vim ++diff --git a/src/version.c b/src/version.c ++index d6fa59c9e773..cae650837a61 100644 ++--- a/src/version.c +++++ b/src/version.c ++@@ -742,6 +742,8 @@ static char *(features[]) = ++ ++ static int included_patches[] = ++ { /* Add new patch number below this line */ +++/**/ +++ 128, ++ /**/ ++ 127, ++ /**/ ++diff --git a/src/vim.h b/src/vim.h ++index 16949ae291dd..d41db143990b 100644 ++--- a/src/vim.h +++++ b/src/vim.h ++@@ -1229,12 +1229,13 @@ typedef struct { ++ * When OPT_GLOBAL and OPT_LOCAL are both missing, set both local and global ++ * values, get local value. ++ */ ++-#define OPT_FREE 1 // free old value if it was allocated ++-#define OPT_GLOBAL 2 // use global value ++-#define OPT_LOCAL 4 // use local value ++-#define OPT_MODELINE 8 // option in modeline ++-#define OPT_WINONLY 16 // only set window-local options ++-#define OPT_NOWIN 32 // don't set window-local options +++#define OPT_FREE 0x01 // free old value if it was allocated +++#define OPT_GLOBAL 0x02 // use global value +++#define OPT_LOCAL 0x04 // use local value +++#define OPT_MODELINE 0x08 // option in modeline +++#define OPT_WINONLY 0x10 // only set window-local options +++#define OPT_NOWIN 0x20 // don't set window-local options +++#define OPT_ONECOLUMN 0x40 // list options one per line ++ ++ // Magic chars used in confirm dialog strings ++ #define DLG_BUTTON_SEP '\n' +-- +2.27.0 + diff --git a/backport-test-for-DiffUpdated-fails.patch b/backport-test-for-DiffUpdated-fails.patch new file mode 100644 index 0000000..93e5bf4 --- /dev/null +++ b/backport-test-for-DiffUpdated-fails.patch @@ -0,0 +1,28 @@ +From f65cc665fa751bad3ffe75f58ce1251d6695949f Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sun, 26 Jun 2022 18:17:50 +0100 +Subject: [PATCH] patch 8.2.5166: test for DiffUpdated fails + +Problem: Test for DiffUpdated fails. +Solution: Also accept a count of two. +--- + src/testdir/test_diffmode.vim | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim +index 61edbe2..4ec9556 100644 +--- a/src/testdir/test_diffmode.vim ++++ b/src/testdir/test_diffmode.vim +@@ -33,7 +33,8 @@ func Test_diff_fold_sync() + call win_gotoid(winone) + call assert_equal(23, getcurpos()[1]) + +- call assert_equal(1, g:update_count) ++ " depending on how redraw is done DiffUpdated may be triggered once or twice ++ call assert_inrange(1, 2, g:update_count) + au! DiffUpdated + + windo diffoff +-- +2.27.0 + diff --git a/vim.spec b/vim.spec index 4b60cdc..201fe9c 100644 --- a/vim.spec +++ b/vim.spec @@ -12,7 +12,7 @@ Name: vim Epoch: 2 Version: 8.2 -Release: 48 +Release: 49 Summary: Vim is a highly configurable text editor for efficiently creating and changing any kind of text. License: Vim and MIT URL: http://www.vim.org @@ -135,6 +135,10 @@ Patch6098: backport-CVE-2022-2206.patch Patch6099: backport-patch-8.2.5161-might-still-access-invalid-memory.patch Patch6100: backport-CVE-2022-1720.patch Patch6101: backport-CVE-2022-2183.patch +Patch6102: backport-cannot-list-options-one-per-line.patch +Patch6103: backport-CVE-2022-2207.patch +Patch6104: backport-CVE-2022-2208.patch +Patch6105: backport-test-for-DiffUpdated-fails.patch Patch9000: bugfix-rm-modify-info-version.patch @@ -523,6 +527,12 @@ popd %{_mandir}/man1/evim.* %changelog +* Thu Jul 07 2022 tianwei - 2:8.2-49 +- Type:CVE +- ID:CVE-2022-2207 CVE-2022-2208 +- SUG:NA +- DESC:fix CVE-2022-2207 CVE-2022-2208 + * Tue Jul 05 2022 renhongxun - 2:8.2-48 - Type:CVE - ID:CVE-2022-1720,CVE-2022-2183 -- Gitee From 8cea7326510b928743f2b0d4fc3240779f02b34e Mon Sep 17 00:00:00 2001 From: tianwei Date: Fri, 8 Jul 2022 01:04:32 +0000 Subject: [PATCH 2/3] update backport-cannot-list-options-one-per-line.patch. --- backport-cannot-list-options-one-per-line.patch | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/backport-cannot-list-options-one-per-line.patch b/backport-cannot-list-options-one-per-line.patch index 33bc413..0671cbc 100644 --- a/backport-cannot-list-options-one-per-line.patch +++ b/backport-cannot-list-options-one-per-line.patch @@ -1,7 +1,10 @@ -From 09fac0422ed8538ecace4638944e7f5b95ae2e16 Mon Sep 17 00:00:00 2001 -From: root -Date: Thu, 7 Jul 2022 19:35:57 +0800 -Subject: [PATCH] 2207-1.patch +From 6b915c0c0ee7ef82f8d3d310a4345e098cb929b0 Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sat, 18 Jan 2020 15:53:19 +0100 +Subject: [PATCH] patch 8.2.0128: cannot list options one per line + +Problem: Cannot list options one per line. +Solution: Use ":set!" to list one option per line. --- runtime/doc/options.txt | 12 +- -- Gitee From dd49ccec36863adc75578273de3f5130e3b93560 Mon Sep 17 00:00:00 2001 From: rwx403335 Date: Tue, 5 Jul 2022 16:31:19 +0800 Subject: [PATCH 3/3] Fix CVE-2022-1720,CVE-2022-2183 --- backport-CVE-2022-1720.patch | 66 ++ backport-CVE-2022-2183.patch | 59 ++ backport-CVE-2022-2207.patch | 29 + backport-CVE-2022-2208.patch | 63 ++ ...ort-cannot-list-options-one-per-line.patch | 579 ++++++++++++++++++ backport-test-for-DiffUpdated-fails.patch | 28 + vim.spec | 20 +- 7 files changed, 843 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2022-1720.patch create mode 100644 backport-CVE-2022-2183.patch create mode 100644 backport-CVE-2022-2207.patch create mode 100644 backport-CVE-2022-2208.patch create mode 100644 backport-cannot-list-options-one-per-line.patch create mode 100644 backport-test-for-DiffUpdated-fails.patch diff --git a/backport-CVE-2022-1720.patch b/backport-CVE-2022-1720.patch new file mode 100644 index 0000000..7a05911 --- /dev/null +++ b/backport-CVE-2022-1720.patch @@ -0,0 +1,66 @@ +From 395bd1f6d3edc9f7edb5d1f2d7deaf5a9e3ab93c Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sat, 14 May 2022 21:29:44 +0100 +Subject: [PATCH] patch 8.2.4956: reading past end of line with "gf" in Visual + block mode + +Problem: Reading past end of line with "gf" in Visual block mode. +Solution: Do not include the NUL in the length. +--- + src/normal.c | 13 ++++++++++--- + src/testdir/test_gf.vim | 15 +++++++++++++++ + 2 files changed, 25 insertions(+), 3 deletions(-) + +diff --git a/src/normal.c b/src/normal.c +index d33a56a..898c836 100644 +--- a/src/normal.c ++++ b/src/normal.c +@@ -3791,9 +3791,16 @@ get_visual_text( + } + if (**pp == NUL) + *lenp = 0; +- if (has_mbyte && *lenp > 0) +- // Correct the length to include all bytes of the last character. +- *lenp += (*mb_ptr2len)(*pp + (*lenp - 1)) - 1; ++ if (*lenp > 0) ++ { ++ if (has_mbyte) ++ // Correct the length to include all bytes of the last ++ // character. ++ *lenp += (*mb_ptr2len)(*pp + (*lenp - 1)) - 1; ++ else if ((*pp)[*lenp - 1] == NUL) ++ // Do not include a trailing NUL. ++ *lenp -= 1; ++ } + } + reset_VIsual_and_resel(); + return OK; +diff --git a/src/testdir/test_gf.vim b/src/testdir/test_gf.vim +index d301874..596f3e8 100644 +--- a/src/testdir/test_gf.vim ++++ b/src/testdir/test_gf.vim +@@ -106,6 +106,21 @@ func Test_gf_visual() + call setline(1, 'XXXtest_gf_visualXXX') + set hidden + ++ " do not include the NUL at the end ++ call writefile(['x'], 'X') ++ let save_enc = &enc ++ for enc in ['latin1', 'utf-8'] ++ exe "set enc=" .. enc ++ new ++ call setline(1, 'X') ++ set nomodified ++ exe "normal \$gf" ++ call assert_equal('X', bufname()) ++ bwipe! ++ endfor ++ let &enc = save_enc ++ call delete('X') ++ + " Visually select Xtest_gf_visual and use gf to go to that file + norm! ttvtXgf + call assert_equal('Xtest_gf_visual', bufname('%')) +-- +1.8.3.1 + diff --git a/backport-CVE-2022-2183.patch b/backport-CVE-2022-2183.patch new file mode 100644 index 0000000..03ddcc4 --- /dev/null +++ b/backport-CVE-2022-2183.patch @@ -0,0 +1,59 @@ +From 8eba2bd291b347e3008aa9e565652d51ad638cfa Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Wed, 22 Jun 2022 19:59:28 +0100 +Subject: [PATCH] patch 8.2.5151: reading beyond the end of the line with lisp + indenting + +Problem: Reading beyond the end of the line with lisp indenting. +Solution: Avoid going over the NUL at the end of the line. +--- + src/indent.c | 7 +++++-- + src/testdir/test_lispwords.vim | 12 +++++++++++- + 2 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/src/indent.c b/src/indent.c +index 2d07e2e..a58d6ea 100644 +--- a/src/indent.c ++++ b/src/indent.c +@@ -1967,8 +1967,11 @@ get_lisp_indent(void) + amount += 2; + else + { +- that++; +- amount++; ++ if (*that != NUL) ++ { ++ that++; ++ amount++; ++ } + firsttry = amount; + + while (VIM_ISWHITE(*that)) +diff --git a/src/testdir/test_lispwords.vim b/src/testdir/test_lispwords.vim +index ff710b2..4144fb0 100644 +--- a/src/testdir/test_lispwords.vim ++++ b/src/testdir/test_lispwords.vim +@@ -1,4 +1,5 @@ +-" Tests for 'lispwords' settings being global-local ++" Tests for 'lispwords' settings being global-local. ++" And other lisp indent stuff. + + set nocompatible viminfo+=nviminfo + +@@ -85,4 +86,13 @@ func Test_lisp_indent() + set nolisp + endfunc + ++func Test_lisp_indent_works() ++ " This was reading beyond the end of the line ++ new ++ exe "norm a\tü(\=" ++ set lisp ++ norm == ++ bwipe! ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +-- +2.27.0 + diff --git a/backport-CVE-2022-2207.patch b/backport-CVE-2022-2207.patch new file mode 100644 index 0000000..613cc38 --- /dev/null +++ b/backport-CVE-2022-2207.patch @@ -0,0 +1,29 @@ +From 0971c7a4e537ea120a6bb2195960be8d0815e97b Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sun, 26 Jun 2022 12:59:02 +0100 +Subject: [PATCH] patch 8.2.5162: reading before the start of the line with BS + in Replace mode + +Problem: Reading before the start of the line with BS in Replace mode. +Solution: Check the cursor column is more than zero. + +--- + src/edit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/edit.c b/src/edit.c +index c4ede2b..bc0b7dc 100644 +--- a/src/edit.c ++++ b/src/edit.c +@@ -4761,7 +4761,7 @@ ins_bs( + #endif + + // delete characters until we are at or before want_vcol +- while (vcol > want_vcol ++ while (vcol > want_vcol && curwin->w_cursor.col > 0 + && (cc = *(ml_get_cursor() - 1), VIM_ISWHITE(cc))) + ins_bs_one(&vcol); + +-- +2.27.0 + diff --git a/backport-CVE-2022-2208.patch b/backport-CVE-2022-2208.patch new file mode 100644 index 0000000..a426430 --- /dev/null +++ b/backport-CVE-2022-2208.patch @@ -0,0 +1,63 @@ +From cd38bb4d83c942c4bad596835c6766cbf32e5195 Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sun, 26 Jun 2022 14:04:07 +0100 +Subject: [PATCH] patch 8.2.5163: crash when deleting buffers in diff mode + +Problem: Crash when deleting buffers in diff mode. +Solution: Recompute diffs later. Skip window without a valid buffer. +--- + src/diff.c | 10 ++++++++-- + src/testdir/test_diffmode.vim | 12 ++++++++++++ + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/src/diff.c b/src/diff.c +index f996904..8569a9f 100644 +--- a/src/diff.c ++++ b/src/diff.c +@@ -107,7 +107,12 @@ diff_buf_delete(buf_T *buf) + tp->tp_diffbuf[i] = NULL; + tp->tp_diff_invalid = TRUE; + if (tp == curtab) +- diff_redraw(TRUE); ++ { ++ // don't redraw right away, more might change or buffer state ++ // is invalid right now ++ need_diff_redraw = TRUE; ++ redraw_later(VALID); ++ } + } + } + } +@@ -655,7 +660,8 @@ diff_redraw( + + need_diff_redraw = FALSE; + FOR_ALL_WINDOWS(wp) +- if (wp->w_p_diff) ++ // when closing windows or wiping buffers skip invalid window ++ if (wp->w_p_diff && buf_valid(wp->w_buffer)) + { + redraw_win_later(wp, SOME_VALID); + #ifdef FEAT_FOLDING +diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim +index 61edbe2..5b48a75 100644 +--- a/src/testdir/test_diffmode.vim ++++ b/src/testdir/test_diffmode.vim +@@ -827,3 +827,15 @@ func Test_diff_maintains_change_mark() + bwipe! + bwipe! + endfunc ++ ++" This was trying to update diffs for a buffer being closed ++func Test_diff_only() ++ silent! lfile ++ set diff ++ lopen ++ norm o ++ silent! norm o ++ ++ set nodiff ++ %bwipe! ++endfunc +-- +2.27.0 + diff --git a/backport-cannot-list-options-one-per-line.patch b/backport-cannot-list-options-one-per-line.patch new file mode 100644 index 0000000..33bc413 --- /dev/null +++ b/backport-cannot-list-options-one-per-line.patch @@ -0,0 +1,579 @@ +From 09fac0422ed8538ecace4638944e7f5b95ae2e16 Mon Sep 17 00:00:00 2001 +From: root +Date: Thu, 7 Jul 2022 19:35:57 +0800 +Subject: [PATCH] 2207-1.patch + +--- + runtime/doc/options.txt | 12 +- + src/ex_cmds.h | 6 +- + src/ex_docmd.c | 18 --- + src/option.c | 34 ++++- + src/optiondefs.h | 2 +- + src/proto/option.pro | 1 + + src/testdir/test_options.vim | 9 +- + src/version.c | 2 + + src/vim.h | 13 +- + test.patch | 285 +++++++++++++++++++++++++++++++++++ + 10 files changed, 344 insertions(+), 38 deletions(-) + create mode 100644 test.patch + +diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt +index 2fced50..8f11253 100644 +--- a/runtime/doc/options.txt ++++ b/runtime/doc/options.txt +@@ -22,9 +22,13 @@ achieve special effects. These options come in three forms: + 1. Setting options *set-option* *E764* + + *:se* *:set* +-:se[t] Show all options that differ from their default value. ++:se[t][!] Show all options that differ from their default value. ++ When [!] is present every option is on a separate ++ line. + +-:se[t] all Show all but terminal options. ++:se[t][!] all Show all but terminal options. ++ When [!] is present every option is on a separate ++ line. + + :se[t] termcap Show all terminal options. Note that in the GUI the + key codes are not shown, because they are generated +@@ -287,7 +291,7 @@ happens when the buffer is not loaded, but they are lost when the buffer is + wiped out |:bwipe|. + + *:setl* *:setlocal* +-:setl[ocal] ... Like ":set" but set only the value local to the ++:setl[ocal][!] ... Like ":set" but set only the value local to the + current buffer or window. Not all options have a + local value. If the option does not have a local + value the global value is set. +@@ -309,7 +313,7 @@ wiped out |:bwipe|. + {option}, so that the global value will be used. + + *:setg* *:setglobal* +-:setg[lobal] ... Like ":set" but set only the global value for a local ++:setg[lobal][!] ... Like ":set" but set only the global value for a local + option without changing the local value. + When displaying an option, the global value is shown. + With the "all" argument: display global values for all +diff --git a/src/ex_cmds.h b/src/ex_cmds.h +index 28ea6ee..605766a 100644 +--- a/src/ex_cmds.h ++++ b/src/ex_cmds.h +@@ -1307,16 +1307,16 @@ EXCMD(CMD_scscope, "scscope", ex_scscope, + EX_EXTRA|EX_NOTRLCOM, + ADDR_NONE), + EXCMD(CMD_set, "set", ex_set, +- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, + ADDR_NONE), + EXCMD(CMD_setfiletype, "setfiletype", ex_setfiletype, + EX_TRLBAR|EX_EXTRA|EX_NEEDARG|EX_CMDWIN, + ADDR_NONE), + EXCMD(CMD_setglobal, "setglobal", ex_set, +- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, + ADDR_NONE), + EXCMD(CMD_setlocal, "setlocal", ex_set, +- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, + ADDR_NONE), + EXCMD(CMD_sfind, "sfind", ex_splitview, + EX_BANG|EX_FILE1|EX_RANGE|EX_CMDARG|EX_ARGOPT|EX_TRLBAR|EX_NEEDARG, +diff --git a/src/ex_docmd.c b/src/ex_docmd.c +index b552440..1644573 100644 +--- a/src/ex_docmd.c ++++ b/src/ex_docmd.c +@@ -320,7 +320,6 @@ static void ex_setfiletype(exarg_T *eap); + # define ex_diffupdate ex_ni + #endif + static void ex_digraphs(exarg_T *eap); +-static void ex_set(exarg_T *eap); + #ifdef FEAT_SEARCH_EXTRA + static void ex_nohlsearch(exarg_T *eap); + #else +@@ -8499,23 +8498,6 @@ ex_digraphs(exarg_T *eap UNUSED) + #endif + } + +- static void +-ex_set(exarg_T *eap) +-{ +- int flags = 0; +- +- if (eap->cmdidx == CMD_setlocal) +- flags = OPT_LOCAL; +- else if (eap->cmdidx == CMD_setglobal) +- flags = OPT_GLOBAL; +-#if defined(FEAT_EVAL) && defined(FEAT_BROWSE) +- if (cmdmod.browse && flags == 0) +- ex_options(eap); +- else +-#endif +- (void)do_set(eap->arg, flags); +-} +- + #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) + void + set_no_hlsearch(int flag) +diff --git a/src/option.c b/src/option.c +index 382b01b..eb610dd 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -1066,6 +1066,27 @@ set_title_defaults(void) + } + #endif + ++ void ++ex_set(exarg_T *eap) ++{ ++ int flags = 0; ++ ++ if (eap->cmdidx == CMD_setlocal) ++ flags = OPT_LOCAL; ++ else if (eap->cmdidx == CMD_setglobal) ++ flags = OPT_GLOBAL; ++#if defined(FEAT_EVAL) && defined(FEAT_BROWSE) ++ if (cmdmod.browse && flags == 0) ++ ex_options(eap); ++ else ++#endif ++ { ++ if (eap->forceit) ++ flags |= OPT_ONECOLUMN; ++ (void)do_set(eap->arg, flags); ++ } ++} ++ + /* + * Parse 'arg' for option settings. + * +@@ -4354,7 +4375,7 @@ showoptions( + #define INC 20 + #define GAP 3 + +- items = ALLOC_MULT(struct vimoption *, PARAM_COUNT); ++ items = ALLOC_MULT(struct vimoption *, OPTION_COUNT); + if (items == NULL) + return; + +@@ -4369,9 +4390,10 @@ showoptions( + msg_puts_title(_("\n--- Options ---")); + + /* +- * do the loop two times: ++ * Do the loop two times: + * 1. display the short items + * 2. display the long items (only strings and numbers) ++ * When "opt_flags" has OPT_ONECOLUMN do everything in run 2. + */ + for (run = 1; run <= 2 && !got_int; ++run) + { +@@ -4382,12 +4404,12 @@ showoptions( + for (p = &options[0]; p->fullname != NULL; p++) + { + // apply :filter /pat/ +- if (message_filtered((char_u *) p->fullname)) ++ if (message_filtered((char_u *)p->fullname)) + continue; + + varp = NULL; + isterm = istermoption(p); +- if (opt_flags != 0) ++ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) != 0) + { + if (p->indir != PV_NONE && !isterm) + varp = get_varp_scope(p, opt_flags); +@@ -4399,7 +4421,9 @@ showoptions( + || (all == 1 && !isterm) + || (all == 0 && !optval_default(p, varp, p_cp)))) + { +- if (p->flags & P_BOOL) ++ if (opt_flags & OPT_ONECOLUMN) ++ len = Columns; ++ else if (p->flags & P_BOOL) + len = 1; // a toggle option fits always + else + { +diff --git a/src/optiondefs.h b/src/optiondefs.h +index 8fda8bf..3670107 100644 +--- a/src/optiondefs.h ++++ b/src/optiondefs.h +@@ -3009,7 +3009,7 @@ static struct vimoption options[] = + {NULL, NULL, 0, NULL, PV_NONE, {NULL, NULL} SCTX_INIT} + }; + +-#define PARAM_COUNT (sizeof(options) / sizeof(struct vimoption)) ++#define OPTION_COUNT (sizeof(options) / sizeof(struct vimoption)) + + // The following is needed to make the gen_opt_test.vim script work. + // {" +diff --git a/src/proto/option.pro b/src/proto/option.pro +index dc07ee6..7da2cbf 100644 +--- a/src/proto/option.pro ++++ b/src/proto/option.pro +@@ -8,6 +8,7 @@ void set_init_2(void); + void set_init_3(void); + void set_helplang_default(char_u *lang); + void set_title_defaults(void); ++void ex_set(exarg_T *eap); + int do_set(char_u *arg, int opt_flags); + void did_set_option(int opt_idx, int opt_flags, int new_value, int value_checked); + int string_to_key(char_u *arg, int multi_byte); +diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim +index d4213c1..7584465 100644 +--- a/src/testdir/test_options.vim ++++ b/src/testdir/test_options.vim +@@ -44,7 +44,7 @@ func Test_wildchar() + set wildchar& + endfunc + +-func Test_options() ++func Test_options_command() + let caught = 'ok' + try + options +@@ -383,6 +383,13 @@ func Test_set_all() + set tw& iskeyword& splitbelow& + endfunc + ++func Test_set_one_column() ++ let out_mult = execute('set all')->split("\n") ++ let out_one = execute('set! all')->split("\n") ++ " one column should be two to four times as many lines ++ call assert_inrange(len(out_mult) * 2, len(out_mult) * 4, len(out_one)) ++endfunc ++ + func Test_set_values() + if filereadable('opt_test.vim') + source opt_test.vim +diff --git a/src/version.c b/src/version.c +index bd45631..4b6cc17 100644 +--- a/src/version.c ++++ b/src/version.c +@@ -742,6 +742,8 @@ static char *(features[]) = + + static int included_patches[] = + { /* Add new patch number below this line */ ++/**/ ++ 128, + /**/ + 3741, + /**/ +diff --git a/src/vim.h b/src/vim.h +index cd917a3..171b5dc 100644 +--- a/src/vim.h ++++ b/src/vim.h +@@ -1227,12 +1227,13 @@ typedef struct { + * When OPT_GLOBAL and OPT_LOCAL are both missing, set both local and global + * values, get local value. + */ +-#define OPT_FREE 1 // free old value if it was allocated +-#define OPT_GLOBAL 2 // use global value +-#define OPT_LOCAL 4 // use local value +-#define OPT_MODELINE 8 // option in modeline +-#define OPT_WINONLY 16 // only set window-local options +-#define OPT_NOWIN 32 // don't set window-local options ++#define OPT_FREE 0x01 // free old value if it was allocated ++#define OPT_GLOBAL 0x02 // use global value ++#define OPT_LOCAL 0x04 // use local value ++#define OPT_MODELINE 0x08 // option in modeline ++#define OPT_WINONLY 0x10 // only set window-local options ++#define OPT_NOWIN 0x20 // don't set window-local options ++#define OPT_ONECOLUMN 0x40 // list options one per line + + // Magic chars used in confirm dialog strings + #define DLG_BUTTON_SEP '\n' +diff --git a/test.patch b/test.patch +new file mode 100644 +index 0000000..bb09977 +--- /dev/null ++++ b/test.patch +@@ -0,0 +1,285 @@ ++From 6b915c0c0ee7ef82f8d3d310a4345e098cb929b0 Mon Sep 17 00:00:00 2001 ++From: Bram Moolenaar ++Date: Sat, 18 Jan 2020 15:53:19 +0100 ++Subject: [PATCH] patch 8.2.0128: cannot list options one per line ++ ++Problem: Cannot list options one per line. ++Solution: Use ":set!" to list one option per line. ++--- ++ runtime/doc/options.txt | 12 ++++++++---- ++ src/ex_cmds.h | 6 +++--- ++ src/ex_docmd.c | 18 ------------------ ++ src/option.c | 34 +++++++++++++++++++++++++++++----- ++ src/optiondefs.h | 2 +- ++ src/proto/option.pro | 1 + ++ src/testdir/test_options.vim | 9 ++++++++- ++ src/version.c | 2 ++ ++ src/vim.h | 13 +++++++------ ++ 9 files changed, 59 insertions(+), 38 deletions(-) ++ ++diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt ++index b86244feaf4a..5ee2ce13ac76 100644 ++--- a/runtime/doc/options.txt +++++ b/runtime/doc/options.txt ++@@ -22,9 +22,13 @@ achieve special effects. These options come in three forms: ++ 1. Setting options *set-option* *E764* ++ ++ *:se* *:set* ++-:se[t] Show all options that differ from their default value. +++:se[t][!] Show all options that differ from their default value. +++ When [!] is present every option is on a separate +++ line. ++ ++-:se[t] all Show all but terminal options. +++:se[t][!] all Show all but terminal options. +++ When [!] is present every option is on a separate +++ line. ++ ++ :se[t] termcap Show all terminal options. Note that in the GUI the ++ key codes are not shown, because they are generated ++@@ -287,7 +291,7 @@ happens when the buffer is not loaded, but they are lost when the buffer is ++ wiped out |:bwipe|. ++ ++ *:setl* *:setlocal* ++-:setl[ocal] ... Like ":set" but set only the value local to the +++:setl[ocal][!] ... Like ":set" but set only the value local to the ++ current buffer or window. Not all options have a ++ local value. If the option does not have a local ++ value the global value is set. ++@@ -309,7 +313,7 @@ wiped out |:bwipe|. ++ {option}, so that the global value will be used. ++ ++ *:setg* *:setglobal* ++-:setg[lobal] ... Like ":set" but set only the global value for a local +++:setg[lobal][!] ... Like ":set" but set only the global value for a local ++ option without changing the local value. ++ When displaying an option, the global value is shown. ++ With the "all" argument: display global values for all ++diff --git a/src/ex_cmds.h b/src/ex_cmds.h ++index 36a8ad4c2c16..53e49d519cc6 100644 ++--- a/src/ex_cmds.h +++++ b/src/ex_cmds.h ++@@ -1307,16 +1307,16 @@ EXCMD(CMD_scscope, "scscope", ex_scscope, ++ EX_EXTRA|EX_NOTRLCOM, ++ ADDR_NONE), ++ EXCMD(CMD_set, "set", ex_set, ++- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, +++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ ADDR_NONE), ++ EXCMD(CMD_setfiletype, "setfiletype", ex_setfiletype, ++ EX_TRLBAR|EX_EXTRA|EX_NEEDARG|EX_CMDWIN, ++ ADDR_NONE), ++ EXCMD(CMD_setglobal, "setglobal", ex_set, ++- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, +++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ ADDR_NONE), ++ EXCMD(CMD_setlocal, "setlocal", ex_set, ++- EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, +++ EX_BANG|EX_TRLBAR|EX_EXTRA|EX_CMDWIN|EX_SBOXOK, ++ ADDR_NONE), ++ EXCMD(CMD_sfind, "sfind", ex_splitview, ++ EX_BANG|EX_FILE1|EX_RANGE|EX_CMDARG|EX_ARGOPT|EX_TRLBAR, ++diff --git a/src/ex_docmd.c b/src/ex_docmd.c ++index 51d85c3a2a0d..193cfcfdffab 100644 ++--- a/src/ex_docmd.c +++++ b/src/ex_docmd.c ++@@ -320,7 +320,6 @@ static void ex_setfiletype(exarg_T *eap); ++ # define ex_diffupdate ex_ni ++ #endif ++ static void ex_digraphs(exarg_T *eap); ++-static void ex_set(exarg_T *eap); ++ #ifdef FEAT_SEARCH_EXTRA ++ static void ex_nohlsearch(exarg_T *eap); ++ #else ++@@ -8488,23 +8487,6 @@ ex_digraphs(exarg_T *eap UNUSED) ++ #endif ++ } ++ ++- static void ++-ex_set(exarg_T *eap) ++-{ ++- int flags = 0; ++- ++- if (eap->cmdidx == CMD_setlocal) ++- flags = OPT_LOCAL; ++- else if (eap->cmdidx == CMD_setglobal) ++- flags = OPT_GLOBAL; ++-#if defined(FEAT_EVAL) && defined(FEAT_BROWSE) ++- if (cmdmod.browse && flags == 0) ++- ex_options(eap); ++- else ++-#endif ++- (void)do_set(eap->arg, flags); ++-} ++- ++ #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) ++ void ++ set_no_hlsearch(int flag) ++diff --git a/src/option.c b/src/option.c ++index 7c37326f931b..e24181af10ee 100644 ++--- a/src/option.c +++++ b/src/option.c ++@@ -1066,6 +1066,27 @@ set_title_defaults(void) ++ } ++ #endif ++ +++ void +++ex_set(exarg_T *eap) +++{ +++ int flags = 0; +++ +++ if (eap->cmdidx == CMD_setlocal) +++ flags = OPT_LOCAL; +++ else if (eap->cmdidx == CMD_setglobal) +++ flags = OPT_GLOBAL; +++#if defined(FEAT_EVAL) && defined(FEAT_BROWSE) +++ if (cmdmod.browse && flags == 0) +++ ex_options(eap); +++ else +++#endif +++ { +++ if (eap->forceit) +++ flags |= OPT_ONECOLUMN; +++ (void)do_set(eap->arg, flags); +++ } +++} +++ ++ /* ++ * Parse 'arg' for option settings. ++ * ++@@ -4349,7 +4370,7 @@ showoptions( ++ #define INC 20 ++ #define GAP 3 ++ ++- items = ALLOC_MULT(struct vimoption *, PARAM_COUNT); +++ items = ALLOC_MULT(struct vimoption *, OPTION_COUNT); ++ if (items == NULL) ++ return; ++ ++@@ -4364,9 +4385,10 @@ showoptions( ++ msg_puts_title(_("\n--- Options ---")); ++ ++ /* ++- * do the loop two times: +++ * Do the loop two times: ++ * 1. display the short items ++ * 2. display the long items (only strings and numbers) +++ * When "opt_flags" has OPT_ONECOLUMN do everything in run 2. ++ */ ++ for (run = 1; run <= 2 && !got_int; ++run) ++ { ++@@ -4377,12 +4399,12 @@ showoptions( ++ for (p = &options[0]; p->fullname != NULL; p++) ++ { ++ // apply :filter /pat/ ++- if (message_filtered((char_u *) p->fullname)) +++ if (message_filtered((char_u *)p->fullname)) ++ continue; ++ ++ varp = NULL; ++ isterm = istermoption(p); ++- if (opt_flags != 0) +++ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) != 0) ++ { ++ if (p->indir != PV_NONE && !isterm) ++ varp = get_varp_scope(p, opt_flags); ++@@ -4394,7 +4416,9 @@ showoptions( ++ || (all == 1 && !isterm) ++ || (all == 0 && !optval_default(p, varp, p_cp)))) ++ { ++- if (p->flags & P_BOOL) +++ if (opt_flags & OPT_ONECOLUMN) +++ len = Columns; +++ else if (p->flags & P_BOOL) ++ len = 1; // a toggle option fits always ++ else ++ { ++diff --git a/src/optiondefs.h b/src/optiondefs.h ++index 8fda8bff8cae..36701070dd11 100644 ++--- a/src/optiondefs.h +++++ b/src/optiondefs.h ++@@ -3009,7 +3009,7 @@ static struct vimoption options[] = ++ {NULL, NULL, 0, NULL, PV_NONE, {NULL, NULL} SCTX_INIT} ++ }; ++ ++-#define PARAM_COUNT (sizeof(options) / sizeof(struct vimoption)) +++#define OPTION_COUNT (sizeof(options) / sizeof(struct vimoption)) ++ ++ // The following is needed to make the gen_opt_test.vim script work. ++ // {" ++diff --git a/src/proto/option.pro b/src/proto/option.pro ++index dc07ee6b830f..7da2cbf982d8 100644 ++--- a/src/proto/option.pro +++++ b/src/proto/option.pro ++@@ -8,6 +8,7 @@ void set_init_2(void); ++ void set_init_3(void); ++ void set_helplang_default(char_u *lang); ++ void set_title_defaults(void); +++void ex_set(exarg_T *eap); ++ int do_set(char_u *arg, int opt_flags); ++ void did_set_option(int opt_idx, int opt_flags, int new_value, int value_checked); ++ int string_to_key(char_u *arg, int multi_byte); ++diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim ++index 636a24d6e9a0..7a74af652acb 100644 ++--- a/src/testdir/test_options.vim +++++ b/src/testdir/test_options.vim ++@@ -44,7 +44,7 @@ func Test_wildchar() ++ set wildchar& ++ endfunc ++ ++-func Test_options() +++func Test_options_command() ++ let caught = 'ok' ++ try ++ options ++@@ -388,6 +388,13 @@ func Test_set_all() ++ set tw& iskeyword& splitbelow& ++ endfunc ++ +++func Test_set_one_column() +++ let out_mult = execute('set all')->split("\n") +++ let out_one = execute('set! all')->split("\n") +++ " one column should be two to four times as many lines +++ call assert_inrange(len(out_mult) * 2, len(out_mult) * 4, len(out_one)) +++endfunc +++ ++ func Test_set_values() ++ if filereadable('opt_test.vim') ++ source opt_test.vim ++diff --git a/src/version.c b/src/version.c ++index d6fa59c9e773..cae650837a61 100644 ++--- a/src/version.c +++++ b/src/version.c ++@@ -742,6 +742,8 @@ static char *(features[]) = ++ ++ static int included_patches[] = ++ { /* Add new patch number below this line */ +++/**/ +++ 128, ++ /**/ ++ 127, ++ /**/ ++diff --git a/src/vim.h b/src/vim.h ++index 16949ae291dd..d41db143990b 100644 ++--- a/src/vim.h +++++ b/src/vim.h ++@@ -1229,12 +1229,13 @@ typedef struct { ++ * When OPT_GLOBAL and OPT_LOCAL are both missing, set both local and global ++ * values, get local value. ++ */ ++-#define OPT_FREE 1 // free old value if it was allocated ++-#define OPT_GLOBAL 2 // use global value ++-#define OPT_LOCAL 4 // use local value ++-#define OPT_MODELINE 8 // option in modeline ++-#define OPT_WINONLY 16 // only set window-local options ++-#define OPT_NOWIN 32 // don't set window-local options +++#define OPT_FREE 0x01 // free old value if it was allocated +++#define OPT_GLOBAL 0x02 // use global value +++#define OPT_LOCAL 0x04 // use local value +++#define OPT_MODELINE 0x08 // option in modeline +++#define OPT_WINONLY 0x10 // only set window-local options +++#define OPT_NOWIN 0x20 // don't set window-local options +++#define OPT_ONECOLUMN 0x40 // list options one per line ++ ++ // Magic chars used in confirm dialog strings ++ #define DLG_BUTTON_SEP '\n' +-- +2.27.0 + diff --git a/backport-test-for-DiffUpdated-fails.patch b/backport-test-for-DiffUpdated-fails.patch new file mode 100644 index 0000000..93e5bf4 --- /dev/null +++ b/backport-test-for-DiffUpdated-fails.patch @@ -0,0 +1,28 @@ +From f65cc665fa751bad3ffe75f58ce1251d6695949f Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sun, 26 Jun 2022 18:17:50 +0100 +Subject: [PATCH] patch 8.2.5166: test for DiffUpdated fails + +Problem: Test for DiffUpdated fails. +Solution: Also accept a count of two. +--- + src/testdir/test_diffmode.vim | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim +index 61edbe2..4ec9556 100644 +--- a/src/testdir/test_diffmode.vim ++++ b/src/testdir/test_diffmode.vim +@@ -33,7 +33,8 @@ func Test_diff_fold_sync() + call win_gotoid(winone) + call assert_equal(23, getcurpos()[1]) + +- call assert_equal(1, g:update_count) ++ " depending on how redraw is done DiffUpdated may be triggered once or twice ++ call assert_inrange(1, 2, g:update_count) + au! DiffUpdated + + windo diffoff +-- +2.27.0 + diff --git a/vim.spec b/vim.spec index cbc151b..201fe9c 100644 --- a/vim.spec +++ b/vim.spec @@ -12,7 +12,7 @@ Name: vim Epoch: 2 Version: 8.2 -Release: 47 +Release: 49 Summary: Vim is a highly configurable text editor for efficiently creating and changing any kind of text. License: Vim and MIT URL: http://www.vim.org @@ -133,6 +133,12 @@ Patch6096: backport-patch-8.2.0358-insufficient-testing-for-indent.c.patch Patch6097: backport-CVE-2022-2125.patch Patch6098: backport-CVE-2022-2206.patch Patch6099: backport-patch-8.2.5161-might-still-access-invalid-memory.patch +Patch6100: backport-CVE-2022-1720.patch +Patch6101: backport-CVE-2022-2183.patch +Patch6102: backport-cannot-list-options-one-per-line.patch +Patch6103: backport-CVE-2022-2207.patch +Patch6104: backport-CVE-2022-2208.patch +Patch6105: backport-test-for-DiffUpdated-fails.patch Patch9000: bugfix-rm-modify-info-version.patch @@ -521,6 +527,18 @@ popd %{_mandir}/man1/evim.* %changelog +* Thu Jul 07 2022 tianwei - 2:8.2-49 +- Type:CVE +- ID:CVE-2022-2207 CVE-2022-2208 +- SUG:NA +- DESC:fix CVE-2022-2207 CVE-2022-2208 + +* Tue Jul 05 2022 renhongxun - 2:8.2-48 +- Type:CVE +- ID:CVE-2022-1720,CVE-2022-2183 +- SUG:NA +- DESC:fix CVE-2022-1720,CVE-2022-2183 + * Tue Jul 05 2022 shixuantong - 2:8.2-47 - Type:CVE - ID:CVE-2022-2125,CVE-2022-2206 -- Gitee