comparison src/list.c @ 19233:04c164c971a3 v8.2.0175

patch 8.2.0175: crash when removing list element in map() Commit: https://github.com/vim/vim/commit/db661fb95dc41b7a9438cf3cd4e77f8410bc81c0 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jan 29 22:17:16 2020 +0100 patch 8.2.0175: crash when removing list element in map() Problem: Crash when removing list element in map(). Solution: Lock the list. (closes https://github.com/vim/vim/issues/2652)
author Bram Moolenaar <Bram@vim.org>
date Wed, 29 Jan 2020 22:30:04 +0100
parents d776967d0f0d
children 293a22b677a8
comparison
equal deleted inserted replaced
19232:6d4ef257d300 19233:04c164c971a3
1780 save_did_emsg = did_emsg; 1780 save_did_emsg = did_emsg;
1781 did_emsg = FALSE; 1781 did_emsg = FALSE;
1782 1782
1783 if (argvars[0].v_type == VAR_DICT) 1783 if (argvars[0].v_type == VAR_DICT)
1784 { 1784 {
1785 int prev_lock = d->dv_lock;
1786
1787 if (map && d->dv_lock == 0)
1788 d->dv_lock = VAR_LOCKED;
1785 ht = &d->dv_hashtab; 1789 ht = &d->dv_hashtab;
1786 hash_lock(ht); 1790 hash_lock(ht);
1787 todo = (int)ht->ht_used; 1791 todo = (int)ht->ht_used;
1788 for (hi = ht->ht_array; todo > 0; ++hi) 1792 for (hi = ht->ht_array; todo > 0; ++hi)
1789 { 1793 {
1811 dictitem_remove(d, di); 1815 dictitem_remove(d, di);
1812 } 1816 }
1813 } 1817 }
1814 } 1818 }
1815 hash_unlock(ht); 1819 hash_unlock(ht);
1820 d->dv_lock = prev_lock;
1816 } 1821 }
1817 else if (argvars[0].v_type == VAR_BLOB) 1822 else if (argvars[0].v_type == VAR_BLOB)
1818 { 1823 {
1819 int i; 1824 int i;
1820 typval_T tv; 1825 typval_T tv;
1853 ++idx; 1858 ++idx;
1854 } 1859 }
1855 } 1860 }
1856 else // argvars[0].v_type == VAR_LIST 1861 else // argvars[0].v_type == VAR_LIST
1857 { 1862 {
1863 int prev_lock = l->lv_lock;
1864
1858 // set_vim_var_nr() doesn't set the type 1865 // set_vim_var_nr() doesn't set the type
1859 set_vim_var_type(VV_KEY, VAR_NUMBER); 1866 set_vim_var_type(VV_KEY, VAR_NUMBER);
1860 1867
1861 range_list_materialize(l); 1868 range_list_materialize(l);
1869 if (map && l->lv_lock == 0)
1870 l->lv_lock = VAR_LOCKED;
1862 for (li = l->lv_first; li != NULL; li = nli) 1871 for (li = l->lv_first; li != NULL; li = nli)
1863 { 1872 {
1864 if (map && var_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE)) 1873 if (map && var_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE))
1865 break; 1874 break;
1866 nli = li->li_next; 1875 nli = li->li_next;
1870 break; 1879 break;
1871 if (!map && rem) 1880 if (!map && rem)
1872 listitem_remove(l, li); 1881 listitem_remove(l, li);
1873 ++idx; 1882 ++idx;
1874 } 1883 }
1884 l->lv_lock = prev_lock;
1875 } 1885 }
1876 1886
1877 restore_vimvar(VV_KEY, &save_key); 1887 restore_vimvar(VV_KEY, &save_key);
1878 restore_vimvar(VV_VAL, &save_val); 1888 restore_vimvar(VV_VAL, &save_val);
1879 1889