Fix use-after-free in Browse Field handler #4862
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Transforming an item placed on a
Tile
with Browse Field open on that tile will callTile::updateThing
, which will subsequently callTile::onUpdateTileItem
, which then ensures that the Browse Field'sContainer
is in sync with theTile
, however,Tile::updateThing
passes the sameItem
pointer as both theoldItem
andnewItem
arguments toTile::onUpdateTileItem
which only coincidentally works for the majority of items whose flags do not happen to transition between being movable and not being movable. If you transform a movable item to a non-movable item, the second branch of the Browse Field handling inTile::onUpdateTileItem
will never execute, leaving theItem
that has now been deleted in the Browse FieldContainer
'sitemlist
member, any further interaction with the item, or waiting for the Browse Field to expire will then result in use-after-free. This fixes the issue by passing a properoldItem
argument to detect such item state transitions. Unfortunately, this comes at the cost ofItem::clone
call, I'm not sure if there's a more efficient way to handle this.