[vim/vim] stringifying a list or dict can free the item being iterated (PR #21001)

4 views
Skip to first unread message

Samuel Schlesinger

unread,
Aug 10, 2026, 8:53:03 PM (15 hours ago) Aug 10
to vim/vim, Subscribed

Problem

match(), matchstr(), matchend(), matchlist() and matchstrpos()
over a list, join() of a list, and string() or :echo of a list or
dict stringify each item while iterating over the container. When an item
is an object this runs its user-defined string() method, which can remove
the item the loop is standing on, or grow a dict so that its hash table is
reallocated. Either leaves the loop reading freed memory.

find_some_match() in evalfunc.c, list_join_inner() in list.c and
dict2string() in dict.c each iterate a container while calling
echo_string(). A minimal reproducer for each crashes an unpatched Vim:

vim9script
class C
  def string(): string
    if len(g:l) > 0
      remove(g:l, 0)
    endif
    return 'x'
  enddef
endclass
g:l = [C.new(), C.new(), C.new()]
echo match(g:l, 'y')   " also: join(g:l), string(g:l)

Solution

Lock the container while iterating, so a change from the string() method
fails with E741 instead of corrupting the iterator, the same way
filter(), map(), sort() and reduce() already do. For a dict also
hash_lock() it, so a grow cannot reallocate the hash table mid-iteration,
mirroring the dict path of filter()/map(). list_reduce() was the
existing pattern these three were missing.

Adds tests for match() and matchstr() over a list, join() and
string() of a list, and string() of a dict, each with an object whose
string() method mutates the container; every one crashes an unpatched
Vim.

AI assistance is acknowledged with Co-Authored-By trailers on the commit,
per AGENTS.md.


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/21001

Commit Summary

  • b939038 stringifying a list or dict can free the item being iterated

File Changes

(4 files)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/21001@github.com>

Reply all
Reply to author
Forward
0 new messages