aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-11-17 10:19:56 +0800
committerGitHub <noreply@github.com>2023-11-17 10:19:56 +0800
commitdc9f7b814517045b5354364655f660aae0989710 (patch)
treead5cc30e6ddb2202fb7e15aa081d9a7c7efb06d4
parent86c2213b5e451b0c80c2d7adc356c7cebe4bb7f8 (diff)
parent790bd4d5858713e8503825892c7d08340d189370 (diff)
downloadrneovim-dc9f7b814517045b5354364655f660aae0989710.tar.gz
rneovim-dc9f7b814517045b5354364655f660aae0989710.tar.bz2
rneovim-dc9f7b814517045b5354364655f660aae0989710.zip
Merge pull request #26083 from zeertzjq/vim-9.0.1854
vim-patch:9.0.{1854,1857,1858,partial:1859,1860,1864,1868,1872,1873,1878,1881,1882,1969,1992,2004,2010,2106}
-rw-r--r--src/nvim/buffer.c6
-rw-r--r--src/nvim/insexpand.c2
-rw-r--r--src/nvim/main.c2
-rw-r--r--src/nvim/message.c2
-rw-r--r--src/nvim/quickfix.c6
-rw-r--r--src/nvim/window.c9
-rw-r--r--test/functional/legacy/messages_spec.lua6
-rw-r--r--test/old/testdir/crash/bt_quickfix1_poc5
-rw-r--r--test/old/testdir/crash/bt_quickfix_poc9
-rw-r--r--test/old/testdir/crash/crash_scrollbar2
-rw-r--r--test/old/testdir/crash/editing_arg_idx_POC_1bin0 -> 398 bytes
-rw-r--r--test/old/testdir/crash/poc1bin0 -> 3264 bytes
-rw-r--r--test/old/testdir/crash/poc_huaf1bin0 -> 1541 bytes
-rw-r--r--test/old/testdir/crash/poc_huaf2bin0 -> 3238 bytes
-rw-r--r--test/old/testdir/crash/poc_huaf3bin0 -> 4053 bytes
-rw-r--r--test/old/testdir/crash/poc_tagfunc.vim6
-rw-r--r--test/old/testdir/crash/vim_msg_trunc_poc1
-rw-r--r--test/old/testdir/crash/vim_regsub_both_pocbin0 -> 244 bytes
-rw-r--r--test/old/testdir/test_crash.vim139
19 files changed, 178 insertions, 17 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 6617907f8f..6d5c7a1766 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -4223,6 +4223,10 @@ bool buf_contents_changed(buf_T *buf)
aco_save_T aco;
aucmd_prepbuf(&aco, newbuf);
+ // We don't want to trigger autocommands now, they may have nasty
+ // side-effects like wiping buffers
+ block_autocmds();
+
if (ml_open(curbuf) == OK
&& readfile(buf->b_ffname, buf->b_fname,
0, 0, (linenr_T)MAXLNUM,
@@ -4247,6 +4251,8 @@ bool buf_contents_changed(buf_T *buf)
wipe_buffer(newbuf, false);
}
+ unblock_autocmds();
+
return differ;
}
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index 28d1c8216e..f565d5b9e8 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -3435,7 +3435,7 @@ static int ins_compl_get_exp(pos_T *ini)
compl_started = true;
} else {
// Mark a buffer scanned when it has been scanned completely
- if (type == 0 || type == CTRL_X_PATH_PATTERNS) {
+ if (buf_valid(st.ins_buf) && (type == 0 || type == CTRL_X_PATH_PATTERNS)) {
assert(st.ins_buf);
st.ins_buf->b_scanned = true;
}
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 818a1313d7..5c0fc758b9 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -698,7 +698,7 @@ void getout(int exitval)
for (const tabpage_T *tp = first_tabpage; tp != NULL; tp = next_tp) {
next_tp = tp->tp_next;
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
- if (wp->w_buffer == NULL) {
+ if (wp->w_buffer == NULL || !buf_valid(wp->w_buffer)) {
// Autocmd must have close the buffer already, skip.
continue;
}
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 8be8581537..ee1a9e60b0 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -468,7 +468,7 @@ void trunc_string(const char *s, char *buf, int room_in, int buflen)
buf[e + 3 + len - 1] = NUL;
} else {
// can't fit in the "...", just truncate it
- buf[e - 1] = NUL;
+ buf[buflen - 1] = NUL;
}
}
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 19b34b52b4..2ddee313a3 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -262,10 +262,8 @@ static const char *e_current_location_list_was_changed =
#define IS_QF_LIST(qfl) ((qfl)->qfl_type == QFLT_QUICKFIX)
#define IS_LL_LIST(qfl) ((qfl)->qfl_type == QFLT_LOCATION)
-//
// Return location list for window 'wp'
// For location list window, return the referenced location list
-//
#define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? (wp)->w_llist_ref : (wp)->w_llist)
// Macro to loop through all the items in a quickfix list
@@ -3863,13 +3861,11 @@ static bool qf_win_pos_update(qf_info_T *qi, int old_qf_index)
static int is_qf_win(const win_T *win, const qf_info_T *qi)
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- //
// A window displaying the quickfix buffer will have the w_llist_ref field
// set to NULL.
// A window displaying a location list buffer will have the w_llist_ref
// pointing to the location list.
- //
- if (bt_quickfix(win->w_buffer)) {
+ if (buf_valid(win->w_buffer) && bt_quickfix(win->w_buffer)) {
if ((IS_QF_STACK(qi) && win->w_llist_ref == NULL)
|| (IS_LL_STACK(qi) && win->w_llist_ref == qi)) {
return true;
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 8ff8053118..00524b2f56 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -2661,6 +2661,9 @@ int win_close(win_T *win, bool free_buf, bool force)
reset_VIsual_and_resel(); // stop Visual mode
other_buffer = true;
+ if (!win_valid(win)) {
+ return FAIL;
+ }
win->w_closing = true;
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
if (!win_valid(win)) {
@@ -3776,6 +3779,12 @@ void close_others(int message, int forceit)
continue;
}
+ // autoccommands messed this one up
+ if (!buf_valid(wp->w_buffer) && win_valid(wp)) {
+ wp->w_buffer = NULL;
+ win_close(wp, false, false);
+ continue;
+ }
// Check if it's allowed to abandon this window
int r = can_abandon(wp->w_buffer, forceit);
if (!win_valid(wp)) { // autocommands messed wp up
diff --git a/test/functional/legacy/messages_spec.lua b/test/functional/legacy/messages_spec.lua
index a604e68822..7536506aa3 100644
--- a/test/functional/legacy/messages_spec.lua
+++ b/test/functional/legacy/messages_spec.lua
@@ -6,6 +6,7 @@ local exec = helpers.exec
local feed = helpers.feed
local meths = helpers.meths
local nvim_dir = helpers.nvim_dir
+local assert_alive = helpers.assert_alive
before_each(clear)
@@ -758,4 +759,9 @@ describe('messages', function()
]])
os.remove('b.txt')
end)
+
+ it('no crash when truncating overlong message', function()
+ pcall(command, 'source test/old/testdir/crash/vim_msg_trunc_poc')
+ assert_alive()
+ end)
end)
diff --git a/test/old/testdir/crash/bt_quickfix1_poc b/test/old/testdir/crash/bt_quickfix1_poc
new file mode 100644
index 0000000000..97993fde52
--- /dev/null
+++ b/test/old/testdir/crash/bt_quickfix1_poc
@@ -0,0 +1,5 @@
+au BufReadPre * exe 'sn' .. expand("<abuf>")
+call writefile([''],'X')
+sil! e X
+call writefile([''],'X')
+sil! e X
diff --git a/test/old/testdir/crash/bt_quickfix_poc b/test/old/testdir/crash/bt_quickfix_poc
new file mode 100644
index 0000000000..bf02b4dcb8
--- /dev/null
+++ b/test/old/testdir/crash/bt_quickfix_poc
@@ -0,0 +1,9 @@
+comman!-narg=* Xexpr <mods>lex<args>
+auto BufReadPre * exe"sn" ..expand("<abuf>")
+fu Xautocmd_changelist()
+cal writefile(['Xtestfile2:4:4'],'Xerr')
+ sil! edi Xerr
+Xexpr 'Xtestfile:4:4'
+endf
+call Xautocmd_changelist()
+call Xautocmd_changelist() \ No newline at end of file
diff --git a/test/old/testdir/crash/crash_scrollbar b/test/old/testdir/crash/crash_scrollbar
new file mode 100644
index 0000000000..1de5905228
--- /dev/null
+++ b/test/old/testdir/crash/crash_scrollbar
@@ -0,0 +1,2 @@
+" this goes to insert mode and presses key k_VerScrollbar which may cause a redraw in exmode, which used ot crash Vim
+norm o€ùX
diff --git a/test/old/testdir/crash/editing_arg_idx_POC_1 b/test/old/testdir/crash/editing_arg_idx_POC_1
new file mode 100644
index 0000000000..5d048d0340
--- /dev/null
+++ b/test/old/testdir/crash/editing_arg_idx_POC_1
Binary files differ
diff --git a/test/old/testdir/crash/poc1 b/test/old/testdir/crash/poc1
new file mode 100644
index 0000000000..ec223f16b8
--- /dev/null
+++ b/test/old/testdir/crash/poc1
Binary files differ
diff --git a/test/old/testdir/crash/poc_huaf1 b/test/old/testdir/crash/poc_huaf1
new file mode 100644
index 0000000000..0d0ea475c1
--- /dev/null
+++ b/test/old/testdir/crash/poc_huaf1
Binary files differ
diff --git a/test/old/testdir/crash/poc_huaf2 b/test/old/testdir/crash/poc_huaf2
new file mode 100644
index 0000000000..4867e0f956
--- /dev/null
+++ b/test/old/testdir/crash/poc_huaf2
Binary files differ
diff --git a/test/old/testdir/crash/poc_huaf3 b/test/old/testdir/crash/poc_huaf3
new file mode 100644
index 0000000000..7e38a9a17c
--- /dev/null
+++ b/test/old/testdir/crash/poc_huaf3
Binary files differ
diff --git a/test/old/testdir/crash/poc_tagfunc.vim b/test/old/testdir/crash/poc_tagfunc.vim
new file mode 100644
index 0000000000..49d9b6f719
--- /dev/null
+++ b/test/old/testdir/crash/poc_tagfunc.vim
@@ -0,0 +1,6 @@
+fu Tagfunc(t,f,o)
+ bw
+endf
+set tagfunc=Tagfunc
+n0
+sil0norm0i
diff --git a/test/old/testdir/crash/vim_msg_trunc_poc b/test/old/testdir/crash/vim_msg_trunc_poc
new file mode 100644
index 0000000000..73b04bec35
--- /dev/null
+++ b/test/old/testdir/crash/vim_msg_trunc_poc
@@ -0,0 +1 @@
+lv\ngggggi;norm:᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌áŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒó ²ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒá Œá ŒŒá Œá ŒŒá Œá ŒŒá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá 
diff --git a/test/old/testdir/crash/vim_regsub_both_poc b/test/old/testdir/crash/vim_regsub_both_poc
new file mode 100644
index 0000000000..19a57114be
--- /dev/null
+++ b/test/old/testdir/crash/vim_regsub_both_poc
Binary files differ
diff --git a/test/old/testdir/test_crash.vim b/test/old/testdir/test_crash.vim
index 445fe8d5a7..b093b053c5 100644
--- a/test/old/testdir/test_crash.vim
+++ b/test/old/testdir/test_crash.vim
@@ -5,21 +5,142 @@ source screendump.vim
CheckScreendump
func Test_crash1()
+ CheckNotBSD
+ CheckExecutable dash
+ " Test 7 fails on Mac ...
+ CheckNotMac
+
" The following used to crash Vim
- let opts = #{wait_for_ruler: 0, rows: 20}
- let args = ' -u NONE -i NONE -n -e -s -S '
- let buf = RunVimInTerminal(args .. ' crash/poc_huaf1', opts)
- call VerifyScreenDump(buf, 'Test_crash_01', {})
- exe buf .. "bw!"
+ let opts = #{cmd: 'sh'}
+ let vim = GetVimProg()
- let buf = RunVimInTerminal(args .. ' crash/poc_huaf2', opts)
- call VerifyScreenDump(buf, 'Test_crash_01', {})
+ let buf = RunVimInTerminal('sh', opts)
+
+ let file = 'crash/poc_huaf1'
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 1: [OK]" > X_crash1_result.txt' .. "\<cr>")
+ call TermWait(buf, 50)
+
+ let file = 'crash/poc_huaf2'
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 2: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ call TermWait(buf, 50)
+
+ let file = 'crash/poc_huaf3'
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 3: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ call TermWait(buf, 100)
+
+ let file = 'crash/bt_quickfix_poc'
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 4: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ " clean up
+ call delete('Xerr')
+ " This test takes a bit longer
+ call TermWait(buf, 1000)
+
+ let file = 'crash/poc_tagfunc.vim'
+ let args = printf(cmn_args, vim, file)
+ " using || because this poc causes vim to exit with exitstatus != 0
+ call term_sendkeys(buf, args ..
+ \ ' || echo "crash 5: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+
+ call TermWait(buf, 100)
+
+ let file = 'crash/bt_quickfix1_poc'
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 6: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ " clean up
+ call delete('X')
+ call TermWait(buf, 3000)
+
+ let file = 'crash/vim_regsub_both_poc'
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 7: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ call TermWait(buf, 3000)
+
+ let file = 'crash/vim_msg_trunc_poc'
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' || echo "crash 8: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ call TermWait(buf, 3000)
+
+ let file = 'crash/crash_scrollbar'
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 9: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ call TermWait(buf, 1000)
+
+ let file = 'crash/editing_arg_idx_POC_1'
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' || echo "crash 10: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+ call TermWait(buf, 1000)
+ call delete('Xerr')
+ call delete('@')
+
+ " clean up
exe buf .. "bw!"
- let buf = RunVimInTerminal(args .. ' crash/poc_huaf3', opts)
- call VerifyScreenDump(buf, 'Test_crash_01', {})
+ sp X_crash1_result.txt
+
+ let expected = [
+ \ 'crash 1: [OK]',
+ \ 'crash 2: [OK]',
+ \ 'crash 3: [OK]',
+ \ 'crash 4: [OK]',
+ \ 'crash 5: [OK]',
+ \ 'crash 6: [OK]',
+ \ 'crash 7: [OK]',
+ \ 'crash 8: [OK]',
+ \ 'crash 9: [OK]',
+ \ 'crash 10: [OK]',
+ \ ]
+
+ call assert_equal(expected, getline(1, '$'))
+ bw!
+
+ call delete('X_crash1_result.txt')
+endfunc
+
+func Test_crash1_2()
+ CheckNotBSD
+ CheckExecutable dash
+
+ " The following used to crash Vim
+ let opts = #{cmd: 'sh'}
+ let vim = GetVimProg()
+ let result = 'X_crash1_1_result.txt'
+
+ let buf = RunVimInTerminal('sh', opts)
+
+ let file = 'crash/poc1'
+ let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
+ let args = printf(cmn_args, vim, file)
+ call term_sendkeys(buf, args ..
+ \ ' && echo "crash 1: [OK]" > '.. result .. "\<cr>")
+ call TermWait(buf, 150)
+
+ " clean up
exe buf .. "bw!"
+ exe "sp " .. result
+
+ let expected = [
+ \ 'crash 1: [OK]',
+ \ ]
+
+ call assert_equal(expected, getline(1, '$'))
+ bw!
+
+ call delete(result)
endfunc
func Test_crash2()