Fix crash entering secret level with music on, and no songs
If music is configured as built-in, and no secret songs are configured,
then BIMSecretSongs is set to a non-null pointer to a zero-element
array. This triggers a divide-by-zero when the array length is used in
a modulus operation.
Fix this by adding a special case that initializing from an empty vector
calls `reset()`, which causes the underlying unique_ptr to store
`nullptr` instead of `new bim_song_info[0]`.
Reported-by: Daniel-Leontiev <https://github.com/dxx-rebirth/dxx-rebirth/issues/465>
Fixes: c355e207fe
("Refactor song loading")
This commit is contained in:
parent
2bedba0a2c
commit
93d3793b30
|
@ -83,6 +83,20 @@ public:
|
||||||
|
|
||||||
void user_configured_level_songs::operator=(std::vector<bim_song_info> &&v)
|
void user_configured_level_songs::operator=(std::vector<bim_song_info> &&v)
|
||||||
{
|
{
|
||||||
|
if (v.empty())
|
||||||
|
{
|
||||||
|
/* If the vector is empty, use `reset` so that this object
|
||||||
|
* stores `nullptr` instead of a pointer to a zero-length array.
|
||||||
|
* Storing `nullptr` causes `operator bool()` to return false.
|
||||||
|
* Storing a zero-length array causes `operator bool()` to
|
||||||
|
* return true.
|
||||||
|
*
|
||||||
|
* A true return causes a divide-by-zero later when the object
|
||||||
|
* is considered true, but then reports a length of zero.
|
||||||
|
*/
|
||||||
|
reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
resize(v.size());
|
resize(v.size());
|
||||||
std::move(v.begin(), v.end(), &this->operator[](0u));
|
std::move(v.begin(), v.end(), &this->operator[](0u));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue