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:
Kp 2019-11-02 04:36:15 +00:00
parent 2bedba0a2c
commit 93d3793b30

View file

@ -83,6 +83,20 @@ public:
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());
std::move(v.begin(), v.end(), &this->operator[](0u));
}