aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi_midiplay.cpp
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2017-10-25 15:21:22 +0300
committerWohlstand <admin@wohlnet.ru>2017-10-25 15:21:22 +0300
commit21180b02ab4146c43abc31484ab086b72104d8c5 (patch)
tree55b77e0a99c270ec766a3b2970c6604d1eeeaca4 /src/adlmidi_midiplay.cpp
parent43a4513ec794c2f5619c64f321af3cd0dd47ff4e (diff)
downloadlibADLMIDI-21180b02ab4146c43abc31484ab086b72104d8c5.tar.gz
libADLMIDI-21180b02ab4146c43abc31484ab086b72104d8c5.tar.bz2
libADLMIDI-21180b02ab4146c43abc31484ab086b72104d8c5.zip
Prevent possible going far far away after end of track memory block
This will prevent possible crash on attempt to parse wrong or damaged MIDI file
Diffstat (limited to 'src/adlmidi_midiplay.cpp')
-rw-r--r--src/adlmidi_midiplay.cpp58
1 files changed, 52 insertions, 6 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 071497c..84ff275 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -132,6 +132,7 @@ MIDIplay::MidiEvent::MidiEvent() :
type(T_UNKNOWN),
subtype(T_UNKNOWN),
channel(0),
+ isValid(1),
absPosition(0)
{}
@@ -232,7 +233,12 @@ bool MIDIplay::buildTrackData()
MidiTrackPos evtPos;
do
{
- event = parseEvent(&trackPtr, status);
+ event = parseEvent(&trackPtr, end, status);
+ if(!event.isValid)
+ {
+ //TODO: Implement file parsing error here
+ return false;
+ }
evtPos.events.push_back(event);
if(event.type == MidiEvent::T_SPECIAL && event.subtype == MidiEvent::ST_TEMPOCHANGE)
{
@@ -258,7 +264,7 @@ bool MIDIplay::buildTrackData()
trackDataNew[tk].push_back(evtPos);
evtPos.reset();
}
- } while(event.subtype != MidiEvent::ST_ENDTRACK);
+ } while((trackPtr <= end) && (event.subtype != MidiEvent::ST_ENDTRACK));
// Build the chain of events
//for(size_t i = 0, j = 1; i < trackDataNew[tk].size() && j < trackDataNew[tk].size(); i++, j++)
@@ -1420,15 +1426,28 @@ bool MIDIplay::ProcessEventsNew(bool isSeek)
return true;//Has events in queue
}
-MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t**pptr, int &status)
+MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t**pptr, uint8_t *end, int &status)
{
uint8_t *&ptr = *pptr;
MIDIplay::MidiEvent evt;
+
+ if(ptr + 1 > end)
+ {
+ evt.isValid = 0;
+ return evt;
+ }
+
unsigned char byte = *(ptr++);
+ bool ok = false;
if(byte == MidiEvent::T_SYSEX || byte == MidiEvent::T_SYSEX2)// Ignore SysEx
{
- uint64_t length = ReadVarLen(pptr);
+ uint64_t length = ReadVarLenEx(pptr, end, ok);
+ if(!ok || (ptr + length > end))
+ {
+ evt.isValid = 0;
+ return evt;
+ }
ptr += (size_t)length;
return evt;
}
@@ -1437,7 +1456,12 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t**pptr, int &status)
{
// Special event FF
uint8_t evtype = *(ptr++);
- uint64_t length = ReadVarLen(pptr);
+ uint64_t length = ReadVarLenEx(pptr, end, ok);
+ if(!ok || (ptr + length > end))
+ {
+ evt.isValid = 0;
+ return evt;
+ }
std::string data(length ? (const char *)ptr : 0, (size_t)length);
ptr += (size_t)length;
@@ -1489,6 +1513,11 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t**pptr, int &status)
//Sys Com Song Select(Song #) [0-127]
if(byte == MidiEvent::T_SYSCOMSNGSEL)
{
+ if(ptr + 1 > end)
+ {
+ evt.isValid = 0;
+ return evt;
+ }
evt.type = byte;
evt.data.push_back(*(ptr++));
return evt;
@@ -1497,6 +1526,11 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t**pptr, int &status)
//Sys Com Song Position Pntr [LSB, MSB]
if(byte == MidiEvent::T_SYSCOMSPOSPTR)
{
+ if(ptr + 2 > end)
+ {
+ evt.isValid = 0;
+ return evt;
+ }
evt.type = byte;
evt.data.push_back(*(ptr++));
evt.data.push_back(*(ptr++));
@@ -1515,9 +1549,21 @@ MIDIplay::MidiEvent MIDIplay::parseEvent(uint8_t**pptr, int &status)
case MidiEvent::T_NOTETOUCH:
case MidiEvent::T_CTRLCHANGE:
case MidiEvent::T_WHEEL:
- evt.data.push_back(*(ptr++)); /* fallthrough */
+ if(ptr + 2 > end)
+ {
+ evt.isValid = 0;
+ return evt;
+ }
+ evt.data.push_back(*(ptr++));
+ evt.data.push_back(*(ptr++));
+ return evt;
case MidiEvent::T_PATCHCHANGE://1 byte length
case MidiEvent::T_CHANAFTTOUCH:
+ if(ptr + 1 > end)
+ {
+ evt.isValid = 0;
+ return evt;
+ }
evt.data.push_back(*(ptr++));
return evt;
}