fix CVE-2022-2343

(cherry picked from commit e025e5df622e2abf1925db04c63b09543c506b83)
This commit is contained in:
shixuantong 2022-07-20 12:44:22 +08:00 committed by openeuler-sync-bot
parent 0b1f5b7aca
commit 977c89645f
3 changed files with 481 additions and 1 deletions

View File

@ -0,0 +1,233 @@
From caea66442d86e7bbba3bf3dc202c3c0d549b9853 Mon Sep 17 00:00:00 2001
From: Bram Moolenaar <Bram@vim.org>
Date: Thu, 7 Jul 2022 19:42:04 +0100
Subject: [PATCH] patch 9.0.0045: reading past end of completion with a long
line
Problem: Reading past end of completion with a long line and 'infercase'
set.
Solution: Allocate the string if needed.
---
src/insexpand.c | 96 +++++++++++++++++++++++++++------------
src/testdir/test_ins_complete.vim | 14 ++++++
2 files changed, 81 insertions(+), 29 deletions(-)
diff --git a/src/insexpand.c b/src/insexpand.c
index 3b4d530..e8ba82e 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -408,29 +408,32 @@ ins_compl_accept_char(int c)
/*
* Get the completed text by inferring the case of the originally typed text.
+ * If the result is in allocated memory "tofree" is set to it.
*/
static char_u *
ins_compl_infercase_gettext(
char_u *str,
- int actual_len,
- int actual_compl_length,
- int min_len)
+ int char_len,
+ int compl_char_len,
+ int min_len,
+ char_u **tofree)
{
int *wca; // Wide character array.
char_u *p;
int i, c;
int has_lower = FALSE;
int was_letter = FALSE;
+ garray_T gap;
- IObuff[0] = NUL;
+ vim_memset(IObuff, NUL, IOSIZE * sizeof(char_u));
// Allocate wide character array for the completion and fill it.
- wca = ALLOC_MULT(int, actual_len);
+ wca = ALLOC_MULT(int, char_len);
if (wca == NULL)
return IObuff;
p = str;
- for (i = 0; i < actual_len; ++i)
+ for (i = 0; i < char_len; ++i)
if (has_mbyte)
wca[i] = mb_ptr2char_adv(&p);
else
@@ -450,7 +453,7 @@ ins_compl_infercase_gettext(
if (MB_ISUPPER(wca[i]))
{
// Rule 1 is satisfied.
- for (i = actual_compl_length; i < actual_len; ++i)
+ for (i = compl_char_len; i < char_len; ++i)
wca[i] = MB_TOLOWER(wca[i]);
break;
}
@@ -471,7 +474,7 @@ ins_compl_infercase_gettext(
if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i]))
{
// Rule 2 is satisfied.
- for (i = actual_compl_length; i < actual_len; ++i)
+ for (i = compl_char_len; i < char_len; ++i)
wca[i] = MB_TOUPPER(wca[i]);
break;
}
@@ -494,20 +497,52 @@ ins_compl_infercase_gettext(
}
// Generate encoding specific output from wide character array.
- // Multi-byte characters can occupy up to five bytes more than
- // ASCII characters, and we also need one byte for NUL, so stay
- // six bytes away from the edge of IObuff.
p = IObuff;
i = 0;
- while (i < actual_len && (p - IObuff + 6) < IOSIZE)
- if (has_mbyte)
+ ga_init2(&gap, 1, 500);
+ while (i < char_len)
+ {
+ if (gap.ga_data != NULL)
+ {
+ if (ga_grow(&gap, 10) == FAIL)
+ {
+ ga_clear(&gap);
+ return (char_u *)"[failed]";
+ }
+ p = (char_u *)gap.ga_data + gap.ga_len;
+ if (has_mbyte)
+ gap.ga_len += (*mb_char2bytes)(wca[i++], p);
+ else
+ {
+ *p = wca[i++];
+ ++gap.ga_len;
+ }
+ }
+ else if ((p - IObuff) + 6 >= IOSIZE)
+ {
+ // Multi-byte characters can occupy up to five bytes more than
+ // ASCII characters, and we also need one byte for NUL, so when
+ // getting to six bytes from the edge of IObuff switch to using a
+ // growarray. Add the character in the next round.
+ if (ga_grow(&gap, IOSIZE) == FAIL)
+ return (char_u *)"[failed]";
+ STRCPY(gap.ga_data, IObuff);
+ gap.ga_len = STRLEN(IObuff);
+ }
+ else if (has_mbyte)
p += (*mb_char2bytes)(wca[i++], p);
else
*(p++) = wca[i++];
- *p = NUL;
-
+ }
vim_free(wca);
+ if (gap.ga_data != NULL)
+ {
+ *tofree = gap.ga_data;
+ return gap.ga_data;
+ }
+
+ *p = NUL;
return IObuff;
}
@@ -528,10 +563,12 @@ ins_compl_add_infercase(
{
char_u *str = str_arg;
char_u *p;
- int actual_len; // Take multi-byte characters
- int actual_compl_length; // into account.
+ int char_len; // count multi-byte characters
+ int compl_char_len;
int min_len;
int flags = 0;
+ int res;
+ char_u *tofree = NULL;
if (p_ic && curbuf->b_p_inf && len > 0)
{
@@ -541,44 +578,45 @@ ins_compl_add_infercase(
if (has_mbyte)
{
p = str;
- actual_len = 0;
+ char_len = 0;
while (*p != NUL)
{
MB_PTR_ADV(p);
- ++actual_len;
+ ++char_len;
}
}
else
- actual_len = len;
+ char_len = len;
// Find actual length of original text.
if (has_mbyte)
{
p = compl_orig_text;
- actual_compl_length = 0;
+ compl_char_len = 0;
while (*p != NUL)
{
MB_PTR_ADV(p);
- ++actual_compl_length;
+ ++compl_char_len;
}
}
else
- actual_compl_length = compl_length;
+ compl_char_len = compl_length;
- // "actual_len" may be smaller than "actual_compl_length" when using
+ // "char_len" may be smaller than "compl_char_len" when using
// thesaurus, only use the minimum when comparing.
- min_len = actual_len < actual_compl_length
- ? actual_len : actual_compl_length;
+ min_len = char_len < compl_char_len ? char_len : compl_char_len;
- str = ins_compl_infercase_gettext(str, actual_len, actual_compl_length,
- min_len);
+ str = ins_compl_infercase_gettext(str, char_len,
+ compl_char_len, min_len, &tofree);
}
if (cont_s_ipos)
flags |= CP_CONT_S_IPOS;
if (icase)
flags |= CP_ICASE;
- return ins_compl_add(str, len, fname, NULL, dir, flags, FALSE);
+ res = ins_compl_add(str, len, fname, NULL, dir, flags, FALSE);
+ vim_free(tofree);
+ return res;
}
/*
diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim
index b7cfd29..aa054f2 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -397,3 +397,17 @@ func Test_complete_overrun()
bwipe!
endfunc
+func Test_infercase_very_long_line()
+ " this was truncating the line when inferring case
+ new
+ let longLine = "blah "->repeat(300)
+ let verylongLine = "blah "->repeat(400)
+ call setline(1, verylongLine)
+ call setline(2, longLine)
+ set ic infercase
+ exe "normal 2Go\<C-X>\<C-L>\<Esc>"
+ call assert_equal(longLine, getline(3))
+
+ bwipe!
+ set noic noinfercase
+endfunc
--
1.8.3.1

View File

@ -0,0 +1,239 @@
From 6ad84ab3e48d9490e4139df04f2c55b136f5501d Mon Sep 17 00:00:00 2001
From: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Fri, 31 Dec 2021 12:59:53 +0000
Subject: [PATCH] patch 8.2.3953: insert completion code is too complicated
Problem: Insert completion code is too complicated.
Solution: More refactoring. Move function arguments into a struct.
(Yegappan Lakshmanan, closes #9437)
---
src/insexpand.c | 196 +++++++++++++++++++++++++++++++-------------------------
1 file changed, 107 insertions(+), 89 deletions(-)
diff --git a/src/insexpand.c b/src/insexpand.c
index 66a836e..3b4d530 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -407,6 +407,111 @@ ins_compl_accept_char(int c)
}
/*
+ * Get the completed text by inferring the case of the originally typed text.
+ */
+ static char_u *
+ins_compl_infercase_gettext(
+ char_u *str,
+ int actual_len,
+ int actual_compl_length,
+ int min_len)
+{
+ int *wca; // Wide character array.
+ char_u *p;
+ int i, c;
+ int has_lower = FALSE;
+ int was_letter = FALSE;
+
+ IObuff[0] = NUL;
+
+ // Allocate wide character array for the completion and fill it.
+ wca = ALLOC_MULT(int, actual_len);
+ if (wca == NULL)
+ return IObuff;
+
+ p = str;
+ for (i = 0; i < actual_len; ++i)
+ if (has_mbyte)
+ wca[i] = mb_ptr2char_adv(&p);
+ else
+ wca[i] = *(p++);
+
+ // Rule 1: Were any chars converted to lower?
+ p = compl_orig_text;
+ for (i = 0; i < min_len; ++i)
+ {
+ if (has_mbyte)
+ c = mb_ptr2char_adv(&p);
+ else
+ c = *(p++);
+ if (MB_ISLOWER(c))
+ {
+ has_lower = TRUE;
+ if (MB_ISUPPER(wca[i]))
+ {
+ // Rule 1 is satisfied.
+ for (i = actual_compl_length; i < actual_len; ++i)
+ wca[i] = MB_TOLOWER(wca[i]);
+ break;
+ }
+ }
+ }
+
+ // Rule 2: No lower case, 2nd consecutive letter converted to
+ // upper case.
+ if (!has_lower)
+ {
+ p = compl_orig_text;
+ for (i = 0; i < min_len; ++i)
+ {
+ if (has_mbyte)
+ c = mb_ptr2char_adv(&p);
+ else
+ c = *(p++);
+ if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i]))
+ {
+ // Rule 2 is satisfied.
+ for (i = actual_compl_length; i < actual_len; ++i)
+ wca[i] = MB_TOUPPER(wca[i]);
+ break;
+ }
+ was_letter = MB_ISLOWER(c) || MB_ISUPPER(c);
+ }
+ }
+
+ // Copy the original case of the part we typed.
+ p = compl_orig_text;
+ for (i = 0; i < min_len; ++i)
+ {
+ if (has_mbyte)
+ c = mb_ptr2char_adv(&p);
+ else
+ c = *(p++);
+ if (MB_ISLOWER(c))
+ wca[i] = MB_TOLOWER(wca[i]);
+ else if (MB_ISUPPER(c))
+ wca[i] = MB_TOUPPER(wca[i]);
+ }
+
+ // Generate encoding specific output from wide character array.
+ // Multi-byte characters can occupy up to five bytes more than
+ // ASCII characters, and we also need one byte for NUL, so stay
+ // six bytes away from the edge of IObuff.
+ p = IObuff;
+ i = 0;
+ while (i < actual_len && (p - IObuff + 6) < IOSIZE)
+ if (has_mbyte)
+ p += (*mb_char2bytes)(wca[i++], p);
+ else
+ *(p++) = wca[i++];
+ *p = NUL;
+
+ vim_free(wca);
+
+ return IObuff;
+}
+
+/*
* This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the
* case of the originally typed text is used, and the case of the completed
* text is inferred, ie this tries to work out what case you probably wanted
@@ -423,13 +528,9 @@ ins_compl_add_infercase(
{
char_u *str = str_arg;
char_u *p;
- int i, c;
int actual_len; // Take multi-byte characters
int actual_compl_length; // into account.
int min_len;
- int *wca; // Wide character array.
- int has_lower = FALSE;
- int was_letter = FALSE;
int flags = 0;
if (p_ic && curbuf->b_p_inf && len > 0)
@@ -469,91 +570,8 @@ ins_compl_add_infercase(
min_len = actual_len < actual_compl_length
? actual_len : actual_compl_length;
- // Allocate wide character array for the completion and fill it.
- wca = ALLOC_MULT(int, actual_len);
- if (wca != NULL)
- {
- p = str;
- for (i = 0; i < actual_len; ++i)
- if (has_mbyte)
- wca[i] = mb_ptr2char_adv(&p);
- else
- wca[i] = *(p++);
-
- // Rule 1: Were any chars converted to lower?
- p = compl_orig_text;
- for (i = 0; i < min_len; ++i)
- {
- if (has_mbyte)
- c = mb_ptr2char_adv(&p);
- else
- c = *(p++);
- if (MB_ISLOWER(c))
- {
- has_lower = TRUE;
- if (MB_ISUPPER(wca[i]))
- {
- // Rule 1 is satisfied.
- for (i = actual_compl_length; i < actual_len; ++i)
- wca[i] = MB_TOLOWER(wca[i]);
- break;
- }
- }
- }
-
- // Rule 2: No lower case, 2nd consecutive letter converted to
- // upper case.
- if (!has_lower)
- {
- p = compl_orig_text;
- for (i = 0; i < min_len; ++i)
- {
- if (has_mbyte)
- c = mb_ptr2char_adv(&p);
- else
- c = *(p++);
- if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i]))
- {
- // Rule 2 is satisfied.
- for (i = actual_compl_length; i < actual_len; ++i)
- wca[i] = MB_TOUPPER(wca[i]);
- break;
- }
- was_letter = MB_ISLOWER(c) || MB_ISUPPER(c);
- }
- }
-
- // Copy the original case of the part we typed.
- p = compl_orig_text;
- for (i = 0; i < min_len; ++i)
- {
- if (has_mbyte)
- c = mb_ptr2char_adv(&p);
- else
- c = *(p++);
- if (MB_ISLOWER(c))
- wca[i] = MB_TOLOWER(wca[i]);
- else if (MB_ISUPPER(c))
- wca[i] = MB_TOUPPER(wca[i]);
- }
-
- // Generate encoding specific output from wide character array.
- // Multi-byte characters can occupy up to five bytes more than
- // ASCII characters, and we also need one byte for NUL, so stay
- // six bytes away from the edge of IObuff.
- p = IObuff;
- i = 0;
- while (i < actual_len && (p - IObuff + 6) < IOSIZE)
- if (has_mbyte)
- p += (*mb_char2bytes)(wca[i++], p);
- else
- *(p++) = wca[i++];
- *p = NUL;
-
- vim_free(wca);
- }
-
- str = IObuff;
+ str = ins_compl_infercase_gettext(str, actual_len, actual_compl_length,
+ min_len);
}
if (cont_s_ipos)
flags |= CP_CONT_S_IPOS;
--
1.8.3.1

View File

@ -12,7 +12,7 @@
Name: vim
Epoch: 2
Version: 8.2
Release: 53
Release: 54
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
@ -155,6 +155,8 @@ Patch6118: backport-CVE-2022-2287.patch
Patch6119: backport-patch-9.0.0022-spell-test-fails.patch
Patch6120: backport-CVE-2022-2210.patch
Patch6121: backport-CVE-2022-2289.patch
Patch6122: backport-patch-8.2.3953-insert-completion-code-is-too-complic.patch
Patch6123: backport-CVE-2022-2343.patch
Patch9000: bugfix-rm-modify-info-version.patch
@ -543,6 +545,12 @@ popd
%{_mandir}/man1/evim.*
%changelog
* Wed Jul 20 2022 shixuantong <shixuantong@h-partners.com> - 2:8.2-54
- Type:CVE
- ID:CVE-2022-2343
- SUG:NA
- DESC:fix CVE-2022-2343
* Fri Jul 15 2022 shangyibin <shangyibin1@h-partners.com> - 2:8.2-53
- Type:CVE
- ID:CVE-2022-2289