diff options
author | Robert Adam <dev@robert-adam.de> | 2022-04-18 13:09:55 +0300 |
---|---|---|
committer | Robert Adam <dev@robert-adam.de> | 2022-04-18 13:18:37 +0300 |
commit | 06f94b4736aa5447f5195ab29cd3ab10e5e1f5e0 (patch) | |
tree | 1c828f0215c6e2e59dbae20fc0ac62b23972bf88 /src | |
parent | cdffda8f522283344329c185d60be2ee12d1dcec (diff) |
FIX(server): Crash due to dereferencing invalid iterator
1d45d991aa4d53b6c1bd7d7cae0126a21f3991e1 refactored the audio processing
on the server and introduced the new AudioReceiverBuffer class. In the
function that is responsible for obtaining the current range of
receivers that shall obtain the identical audio packet, the passed begin
iterator was always dereferenced. However, in the case in which the
receiver list is actually empty begin == end and therefore dereferencing
the begin iterator is undefined behavior.
This could lead to the entire server crashing (or could work just fine -
UB is great at this) but in any case, this is a severe problem.
The fix consists of a simple check for this specific situation and an
early return in that case.
Co-Authored-By: Irak Rigia <tarakrigia@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/murmur/AudioReceiverBuffer.h | 8 | ||||
-rw-r--r-- | src/tests/TestAudioReceiverBuffer/TestAudioReceiverBuffer.cpp | 13 |
2 files changed, 21 insertions, 0 deletions
diff --git a/src/murmur/AudioReceiverBuffer.h b/src/murmur/AudioReceiverBuffer.h index 9d2aeefc8..b5d6d9822 100644 --- a/src/murmur/AudioReceiverBuffer.h +++ b/src/murmur/AudioReceiverBuffer.h @@ -68,6 +68,14 @@ public: ReceiverRange< Iterator > range; range.begin = begin; + if (begin == end) { + // In this case, it is invalid to dereference begin (as is done further down) and thus we have to + // return early instead. + range.end = end; + + return range; + } + // Find a range, such that all receivers in [begin, end) are compatible in the sense that they will all receive // the exact same audio packet (thus: no re-encoding required between sending the packet to them). range.end = std::lower_bound(begin, end, *begin, [](const AudioReceiver &lhs, const AudioReceiver &rhs) { diff --git a/src/tests/TestAudioReceiverBuffer/TestAudioReceiverBuffer.cpp b/src/tests/TestAudioReceiverBuffer/TestAudioReceiverBuffer.cpp index 3d37c3099..c04188a34 100644 --- a/src/tests/TestAudioReceiverBuffer/TestAudioReceiverBuffer.cpp +++ b/src/tests/TestAudioReceiverBuffer/TestAudioReceiverBuffer.cpp @@ -270,6 +270,19 @@ private slots: qDebug() << "Sample receiver list required" << requiredReencodings << "encoding steps"; } + + void test_emptyRange() { + AudioReceiverBuffer buffer; + + std::vector< AudioReceiver > receivers = buffer.getReceivers(true); + + QVERIFY(receivers.empty()); + + ReceiverRange< std::vector< AudioReceiver >::iterator > range = + AudioReceiverBuffer::getReceiverRange(receivers.begin(), receivers.end()); + + QCOMPARE(range.begin, range.end); + } }; QTEST_MAIN(TestAudioReceiverBuffer) |