Mercurial > vim
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 |