Migrate legacy wheels and fix memory corruption in vehicle deserialization #49589
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
Bugfixes "Migrate legacy wheels and fix memory corruption in vehicle deserialization"
Purpose of change
This is the long-term fix for #49540. It reverts and replaces the short term fix #49568.
This PR migrates the deprecated steerable wheel vparts found in 0.E saves to their non-deprecated counterparts.
It also prevents memory corruption that can happen when vehicle deserialization fails, the error is silently ignored, and the game continues with a partially-initialized vehicle object.
Describe the solution
deprecated
replacement map invehicle_part::deserialize()
. (I also tidied up the code a bit)With this change any future errors that occur when deserializing a vehicle will be prominently displayed and if the user chooses to ignore them we'll do the best we can to recover (removing bad vparts or removing the problematic vehicles).
Describe alternatives you've considered
Testing
Load one of the problematic 0.E saves from #49540. Observe no errors or mangled vehicles. Drive a problematic vehicle.
Check the debug.log for vpart migration messages.[actually they don't show up there because of severity filtering]Save the game and search the map json files for "wheel_armor_steerable" (present in the original save), find none.
Additional context
We probably need a templatized function for "deserialize a vector of Foo from a json array one at a time and if any of them fails display an error message and skip it".
I think we also need a clang_tidy check for calls to JsonIn::read() that don't set throw_on_error to true and also don't check the return value for success. These calls silently ignore errors and may end up using partially-initialized objects, which leads to undefined behavior such as memory corruption. The vehicle deserialization call was one instance of this, but there are others (and I'm not going to fix them in this PR).
Some of the older vpart migrations from
vehicle_part::deserialize
can probably be removed (any of them that were present in the last 0.E release or to be extra safe just those present in the first 0.E release), because those vparts should not appear in supported save files.Here's what a vehicle part error would look like: