mirror of
https://github.com/vim/vim.git
synced 2025-09-27 04:14:06 -04:00
patch 9.1.1792: List of changes not protected from changes
Problem: List of changes not protected from changes when processing listeners (after v9.1.1782) Solution: Fully lock changes list for listener callbacks (Paul Ollis) closes: #18385 Signed-off-by: Paul Ollis <paul@cleversheep.org> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
377339dff3
commit
35a89ce9db
10
src/change.c
10
src/change.c
@@ -297,7 +297,6 @@ may_record_change(
|
|||||||
if (curbuf->b_recorded_changes == NULL) // out of memory
|
if (curbuf->b_recorded_changes == NULL) // out of memory
|
||||||
return;
|
return;
|
||||||
++curbuf->b_recorded_changes->lv_refcount;
|
++curbuf->b_recorded_changes->lv_refcount;
|
||||||
curbuf->b_recorded_changes->lv_lock = VAR_FIXED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dict = dict_alloc();
|
dict = dict_alloc();
|
||||||
@@ -489,6 +488,7 @@ invoke_listener_set(
|
|||||||
listener_T *lnr;
|
listener_T *lnr;
|
||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
typval_T argv[6];
|
typval_T argv[6];
|
||||||
|
typval_T val;
|
||||||
|
|
||||||
argv[0].v_type = VAR_NUMBER;
|
argv[0].v_type = VAR_NUMBER;
|
||||||
argv[0].vval.v_number = buf->b_fnum; // a:bufnr
|
argv[0].vval.v_number = buf->b_fnum; // a:bufnr
|
||||||
@@ -501,6 +501,13 @@ invoke_listener_set(
|
|||||||
argv[4].v_type = VAR_LIST;
|
argv[4].v_type = VAR_LIST;
|
||||||
argv[4].vval.v_list = recorded_changes;
|
argv[4].vval.v_list = recorded_changes;
|
||||||
|
|
||||||
|
// Ensure the list of changes is locked to prevent any modifications by
|
||||||
|
// callback code..
|
||||||
|
val.v_type = VAR_LIST;
|
||||||
|
val.v_lock = 0;
|
||||||
|
val.vval.v_list = recorded_changes;
|
||||||
|
item_lock(&val, -1, TRUE, FALSE);
|
||||||
|
|
||||||
// Protect against recursive callbacks, lock the buffer against changes and
|
// Protect against recursive callbacks, lock the buffer against changes and
|
||||||
// set the updating_screen flag to prevent channel input processing, which
|
// set the updating_screen flag to prevent channel input processing, which
|
||||||
// might also try to update the buffer.
|
// might also try to update the buffer.
|
||||||
@@ -547,7 +554,6 @@ invoke_sync_listeners(
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
++recorded_changes->lv_refcount;
|
++recorded_changes->lv_refcount;
|
||||||
recorded_changes->lv_lock = VAR_FIXED;
|
|
||||||
|
|
||||||
dict = dict_alloc();
|
dict = dict_alloc();
|
||||||
if (dict == NULL)
|
if (dict == NULL)
|
||||||
|
@@ -21,8 +21,21 @@ func s:AnotherStoreList(l)
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func s:EvilStoreList(l)
|
func s:EvilStoreList(l)
|
||||||
|
func! Modify_dict_in_list(the_list, key)
|
||||||
|
let a:the_list[0][a:key] = a:the_list[0][a:key] + 1
|
||||||
|
endfunc
|
||||||
|
func! Modify_list_entry(the_list)
|
||||||
|
let a:the_list[0] = 42
|
||||||
|
endfunc
|
||||||
|
|
||||||
let s:list3 = a:l
|
let s:list3 = a:l
|
||||||
call assert_fails("call add(a:l, 'myitem')", "E742:")
|
call assert_fails("call add(a:l, 'myitem')", "E741:")
|
||||||
|
call assert_fails("call remove(a:l, 1)", "E741:")
|
||||||
|
call assert_fails("call Modify_dict_in_list(a:l, 'lnum')", "E741:")
|
||||||
|
call assert_fails("call Modify_dict_in_list(a:l, 'end')", "E741:")
|
||||||
|
call assert_fails("call Modify_dict_in_list(a:l, 'col')", "E741:")
|
||||||
|
call assert_fails("call Modify_dict_in_list(a:l, 'added')", "E741:")
|
||||||
|
call assert_fails("call Modify_list_entry(a:l)", "E741:")
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_listening()
|
func Test_listening()
|
||||||
|
@@ -729,6 +729,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1792,
|
||||||
/**/
|
/**/
|
||||||
1791,
|
1791,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user