diff options
author | Wohlstand <admin@wohlnet.ru> | 2017-10-25 15:21:22 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2017-10-25 15:21:22 +0300 |
commit | 21180b02ab4146c43abc31484ab086b72104d8c5 (patch) | |
tree | 55b77e0a99c270ec766a3b2970c6604d1eeeaca4 /src/adlmidi_midiplay.cpp | |
parent | 43a4513ec794c2f5619c64f321af3cd0dd47ff4e (diff) | |
download | libADLMIDI-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.cpp | 58 |
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; } |