Browse Source

VSTMidiEventList: Avoid UB Sanitizer warnings about out-of-bounds VLA access

v6.1.6
reuk 4 years ago
parent
commit
3a1be39cb6
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
1 changed files with 27 additions and 10 deletions
  1. +27
    -10
      modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h

+ 27
- 10
modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h View File

@@ -39,6 +39,22 @@ namespace juce
*/
class VSTMidiEventList
{
// "events" is expected to be a const- or non-const-ref to Vst2::VstEvents.
template <typename Events>
static auto& getEvent (Events& events, int index)
{
using EventType = decltype (&*events.events);
// We static cast rather than using a direct array index here to circumvent
// UB sanitizer's bounds-checks. The original struct is supposed to contain
// a variable-length array, but the declaration uses a size of "2" for this
// member.
return static_cast<EventType> (events.events)[index];
}
Vst2::VstEvent* const& getEvent (int index) const { return getEvent (*events, index); }
Vst2::VstEvent* & getEvent (int index) { return getEvent (*events, index); }
public:
//==============================================================================
VSTMidiEventList()
@@ -64,15 +80,16 @@ public:
{
ensureSize (numEventsUsed + 1);
void* const ptr = (Vst2::VstMidiEvent*) (events->events [numEventsUsed]);
auto* const e = (Vst2::VstMidiEvent*) ptr;
void* const ptr = getEvent (numEventsUsed);
events->numEvents = ++numEventsUsed;
if (numBytes <= 4)
{
auto* const e = static_cast<Vst2::VstMidiEvent*> (ptr);
if (e->type == Vst2::kVstSysExType)
{
delete[] (((Vst2::VstMidiSysexEvent*) ptr)->sysexDump);
delete[] reinterpret_cast<Vst2::VstMidiSysexEvent*> (e)->sysexDump;
e->type = Vst2::kVstMidiType;
e->byteSize = sizeof (Vst2::VstMidiEvent);
e->noteLength = 0;
@@ -86,7 +103,7 @@ public:
}
else
{
auto* const se = (Vst2::VstMidiSysexEvent*) ptr;
auto* const se = static_cast<Vst2::VstMidiSysexEvent*> (ptr);
if (se->type == Vst2::kVstSysExType)
delete[] se->sysexDump;
@@ -111,20 +128,20 @@ public:
{
for (int i = 0; i < events->numEvents; ++i)
{
const Vst2::VstEvent* const e = events->events[i];
const auto* const e = getEvent (*events, i);
if (e != nullptr)
{
const void* const ptr = events->events[i];
const void* const ptr = e;
if (e->type == Vst2::kVstMidiType)
{
dest.addEvent ((const juce::uint8*) ((const Vst2::VstMidiEvent*) ptr)->midiData,
dest.addEvent ((const juce::uint8*) static_cast<const Vst2::VstMidiEvent*> (ptr)->midiData,
4, e->deltaFrames);
}
else if (e->type == Vst2::kVstSysExType)
{
const auto* se = (const Vst2::VstMidiSysexEvent*) ptr;
const auto* se = static_cast<const Vst2::VstMidiSysexEvent*> (ptr);
dest.addEvent ((const juce::uint8*) se->sysexDump,
(int) se->dumpBytes,
e->deltaFrames);
@@ -148,7 +165,7 @@ public:
events.realloc (size, 1);
for (int i = numEventsAllocated; i < numEventsNeeded; ++i)
events->events[i] = allocateVSTEvent();
getEvent (i) = allocateVSTEvent();
numEventsAllocated = numEventsNeeded;
}
@@ -159,7 +176,7 @@ public:
if (events != nullptr)
{
for (int i = numEventsAllocated; --i >= 0;)
freeVSTEvent (events->events[i]);
freeVSTEvent (getEvent (i));
events.free();
numEventsUsed = 0;


Loading…
Cancel
Save