Fix inventory caching bug causing crash when resuming craft #36762
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.
Summary
SUMMARY: Bugfixes "Fix crash related to tool usage on resumed crafts"
Purpose of change
Fixes #32786.
Fixes #32694.
Consider the following chunk of code (which is on the stacktrace from the above issues):
Cataclysm-DDA/src/requirements.cpp
Lines 969 to 997 in 764aa9f
Line 972 is using
visitable<inventory>::charges_of
, which includes the following:Cataclysm-DDA/src/visitable.cpp
Lines 816 to 827 in 764aa9f
That relies on a cache of items binned by type in
inventory
. That binned cache keepsitem*
to theinventory
contents hanging around.Back in the first snippet, line 983 calls
visitable::remove_items_with
, which (potentially) deletes some items from theinventory
. However, it doesn't invalidate the binning cache, so dangling pointers can remain.These lines are within a loop, so the next time around the loop
visitable<inventory>::charges_of
uses the cache again, and dereferences an invalid pointer in a call toitem::is_tool
here:Cataclysm-DDA/src/visitable.cpp
Line 774 in 764aa9f
Describe the solution
Invalidate the inventory binning cache in
visitable<inventory>::remove_items_with
.Add a regression test.
Testing
Ran new regression test under ASan before and after fix. It finds the use-after-free without the fix, and it's gone with the fix.