# HG changeset patch # User Christian Brabandt # Date 1692549903 -7200 # Node ID b80d180553705ddd3ab7091dbffcafbc6f7cd3e0 # Parent cfa0ccf8d39081945c5e0a6caba6f4b923c934df patch 9.0.1763: crash when passing invalid buffer to undotree() Commit: https://github.com/vim/vim/commit/ab9f2ecfd4ecaf74eeed0e5ec41355589af3ec8f Author: zeertzjq Date: Sun Aug 20 18:35:10 2023 +0200 patch 9.0.1763: crash when passing invalid buffer to undotree() Problem: crash when passing invalid buffer to undotree() Solution: Use get_buf_arg() instead of tv_get_buf_from_arg(). closes: #12862 closes: #12830 Signed-off-by: Christian Brabandt Co-authored-by: zeertzjq diff --git a/src/testdir/test_undo.vim b/src/testdir/test_undo.vim --- a/src/testdir/test_undo.vim +++ b/src/testdir/test_undo.vim @@ -134,6 +134,18 @@ func Test_undotree_bufnr() call assert_notequal(d1, d) call assert_equal(d2, d) + " error cases + call assert_fails('call undotree(-1)', 'E158:') + call assert_fails('call undotree("nosuchbuf")', 'E158:') + + " after creating a buffer nosuchbuf, undotree('nosuchbuf') should + " not error out + new nosuchbuf + let d = {'seq_last': 0, 'entries': [], 'time_cur': 0, 'save_last': 0, 'synced': 1, 'save_cur': 0, 'seq_cur': 0} + call assert_equal(d, undotree("nosuchbuf")) + " clean up + bw nosuchbuf + " Drop created windows set ul& new diff --git a/src/undo.c b/src/undo.c --- a/src/undo.c +++ b/src/undo.c @@ -3726,23 +3726,18 @@ u_undofile_reset_and_delete(buf_T *buf) void f_undotree(typval_T *argvars UNUSED, typval_T *rettv) { - typval_T *tv = &argvars[0]; - buf_T *buf; - dict_T *dict; - list_T *list; - if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL) return; - if (tv->v_type == VAR_UNKNOWN) - buf = curbuf; - else - buf = tv_get_buf_from_arg(tv); - if (rettv_dict_alloc(rettv) == FAIL) return; - dict = rettv->vval.v_dict; + typval_T *tv = &argvars[0]; + buf_T *buf = tv->v_type == VAR_UNKNOWN ? curbuf : get_buf_arg(tv); + if (buf == NULL) + return; + + dict_T *dict = rettv->vval.v_dict; dict_add_number(dict, "synced", (long)buf->b_u_synced); dict_add_number(dict, "seq_last", buf->b_u_seq_last); @@ -3751,7 +3746,7 @@ f_undotree(typval_T *argvars UNUSED, typ dict_add_number(dict, "time_cur", (long)buf->b_u_time_cur); dict_add_number(dict, "save_cur", buf->b_u_save_nr_cur); - list = list_alloc(); + list_T *list = list_alloc(); if (list != NULL) { u_eval_tree(buf, buf->b_u_oldhead, list); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1763, +/**/ 1762, /**/ 1761,