SDL: audio: Assert that all devices from device_hash are the appropriate type (71bd2)

From 71bd25a893d7c9c49c46a0717f8d3f62bd163de1 Mon Sep 17 00:00:00 2001
From: Simon McVittie <[EMAIL REDACTED]>
Date: Tue, 13 May 2025 13:09:43 +0100
Subject: [PATCH] audio: Assert that all devices from device_hash are the
 appropriate type

The keys and values of device_hash are pairs
`(SDL_AudioDeviceID devid, void *dev)` where dev can be either a
`SDL_AudioDevice *` or a `SDL_LogicalAudioDevice *`, depending on
bit 1 of devid.

We can confirm that we have got this right by looking at the
instance_id member, because logical audio devices happen to start with
the devid, whereas physical devices start with a pointer which is
unlikely to match the devid by chance.

Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 70b2d162e33a6d9b9801cd939d040fdccc856653)
---
 src/audio/SDL_audio.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index d8a6d662158d7..5ddf97876c877 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -410,6 +410,7 @@ static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid,
         SDL_LockRWLockForReading(current_audio.device_hash_lock);
         SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &logdev);
         if (logdev) {
+            SDL_assert(logdev->instance_id == devid);
             device = logdev->physical_device;
             SDL_assert(device != NULL);
             RefPhysicalAudioDevice(device);  // reference it, in case the logical device migrates to a new default.
@@ -459,6 +460,7 @@ static SDL_AudioDevice *ObtainPhysicalAudioDevice(SDL_AudioDeviceID devid)  // !
     } else {
         SDL_LockRWLockForReading(current_audio.device_hash_lock);
         SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device);
+        SDL_assert(device->instance_id == devid);
         SDL_UnlockRWLock(current_audio.device_hash_lock);
 
         if (!device) {
@@ -883,6 +885,7 @@ static bool SDLCALL FindLowestDeviceID(void *userdata, const SDL_HashTable *tabl
     if (isphysical && (devid_recording == data->recording) && (devid < data->highest)) {
         data->highest = devid;
         data->result = (SDL_AudioDevice *) value;
+        SDL_assert(data->result->instance_id == devid);
     }
     return true;  // keep iterating.
 }
@@ -1051,7 +1054,10 @@ static bool SDLCALL DestroyOnePhysicalAudioDevice(void *userdata, const SDL_Hash
     const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
     const bool isphysical = !!(devid & (1<<1));
     if (isphysical) {
-        DestroyPhysicalAudioDevice((SDL_AudioDevice *) value);
+        SDL_AudioDevice *dev = (SDL_AudioDevice *) value;
+
+        SDL_assert(dev->instance_id == devid);
+        DestroyPhysicalAudioDevice(dev);
     }
     return true;  // keep iterating.
 }
@@ -1464,6 +1470,7 @@ static bool SDLCALL FindAudioDeviceByCallback(void *userdata, const SDL_HashTabl
         SDL_AudioDevice *device = (SDL_AudioDevice *) value;
         if (data->callback(device, data->userdata)) {  // found it?
             data->retval = device;
+            SDL_assert(data->retval->instance_id == devid);
             return false;  // stop iterating, we found it.
         }
     }
@@ -1520,9 +1527,11 @@ const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
             SDL_SetError("Invalid audio device instance ID");
         } else if (islogical) {
             const SDL_LogicalAudioDevice *logdev = (const SDL_LogicalAudioDevice *) vdev;
+            SDL_assert(logdev->instance_id == devid);
             result = SDL_GetPersistentString(logdev->physical_device->name);
         } else {
             const SDL_AudioDevice *device = (const SDL_AudioDevice *) vdev;
+            SDL_assert(device->instance_id == devid);
             result = SDL_GetPersistentString(device->name);
         }
         SDL_UnlockRWLock(current_audio.device_hash_lock);