VST buffer paranoia
authorRobin Gareus <robin@gareus.org>
Fri, 11 Nov 2016 15:19:59 +0000 (16:19 +0100)
committerRobin Gareus <robin@gareus.org>
Fri, 11 Nov 2016 15:40:01 +0000 (16:40 +0100)
libs/ardour/buffer_set.cc

index 92f5272b3b2bee945c8723eb0b2188ff58518e9b..66564f3202937dbf4460bfb7c8f21266c47aff95 100644 (file)
@@ -349,6 +349,7 @@ VstEvents*
 BufferSet::get_vst_midi (size_t b)
 {
        MidiBuffer& m = get_midi (b);
+       assert (b <= _vst_buffers.size());
        VSTBuffer* vst = _vst_buffers[b];
 
        vst->clear ();
@@ -362,13 +363,24 @@ BufferSet::get_vst_midi (size_t b)
 
 BufferSet::VSTBuffer::VSTBuffer (size_t c)
   : _capacity (c)
+  , _events (0)
+  , _midi_events (0)
 {
-       _events = static_cast<VstEvents*> (malloc (sizeof (VstEvents) + _capacity * sizeof (VstEvent *)));
-       _midi_events = static_cast<VstMidiEvent*> (malloc (sizeof (VstMidiEvent) * _capacity));
+       if (_capacity > 0) {
+               /* from `man malloc`: "If size is 0, then malloc() returns either NULL, or a
+                * unique pointer value that can later be successfully passed to free()."
+                *
+                * The latter will cause trouble here.
+                */
+               _events = static_cast<VstEvents*> (malloc (sizeof (VstEvents) + _capacity * sizeof (VstEvent *)));
+               _midi_events = static_cast<VstMidiEvent*> (malloc (sizeof (VstMidiEvent) * _capacity));
+       }
 
        if (_events == 0 || _midi_events == 0) {
                free (_events);
                free (_midi_events);
+               _events = 0;
+               _midi_events = 0;
                throw failed_constructor ();
        }
 
@@ -399,6 +411,9 @@ BufferSet::VSTBuffer::push_back (Evoral::MIDIEvent<framepos_t> const & ev)
        }
        int const n = _events->numEvents;
        assert (n < (int) _capacity);
+       if (n >= _capacity) {
+               return;
+       }
 
        _events->events[n] = reinterpret_cast<VstEvent*> (_midi_events + n);
        VstMidiEvent* v = reinterpret_cast<VstMidiEvent*> (_events->events[n]);