diff options
Diffstat (limited to 'src/midi_sequencer_impl.hpp')
-rw-r--r-- | src/midi_sequencer_impl.hpp | 109 |
1 files changed, 73 insertions, 36 deletions
diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp index 6f62e0b..b3bfefa 100644 --- a/src/midi_sequencer_impl.hpp +++ b/src/midi_sequencer_impl.hpp @@ -59,7 +59,7 @@ typedef int32_t ssize_t; * @param nbytes Count of bytes to parse integer * @return Extracted unsigned integer */ -static inline uint64_t ReadBEint(const void *buffer, size_t nbytes) +static inline uint64_t readBEint(const void *buffer, size_t nbytes) { uint64_t result = 0; const unsigned char *data = reinterpret_cast<const unsigned char *>(buffer); @@ -76,7 +76,7 @@ static inline uint64_t ReadBEint(const void *buffer, size_t nbytes) * @param nbytes Count of bytes to parse integer * @return Extracted unsigned integer */ -static inline uint64_t ReadLEint(const void *buffer, size_t nbytes) +static inline uint64_t readLEint(const void *buffer, size_t nbytes) { uint64_t result = 0; const unsigned char *data = reinterpret_cast<const unsigned char *>(buffer); @@ -573,7 +573,7 @@ bool BW_MidiSequencer::buildTrackData(const std::vector<std::vector<uint8_t> > & TempoChangePoint tempoMarker; MidiEvent &tempoPoint = tempos[tempo_change_index]; tempoMarker.absPos = tempoPoint.absPosition; - tempoMarker.tempo = m_invDeltaTicks * fraction<uint64_t>(ReadBEint(tempoPoint.data.data(), tempoPoint.data.size())); + tempoMarker.tempo = m_invDeltaTicks * fraction<uint64_t>(readBEint(tempoPoint.data.data(), tempoPoint.data.size())); points.push_back(tempoMarker); tempo_change_index++; } @@ -839,7 +839,7 @@ bool BW_MidiSequencer::processEvents(bool isSeek) #ifdef DEBUG_TIME_CALCULATION std::fprintf(stdout, " \r"); - std::fprintf(stdout, "Time: %10f; Audio: %10f\r", maxTime, CurrentPositionNew.absTimePosition); + std::fprintf(stdout, "Time: %10f; Audio: %10f\r", maxTime, m_currentPosition.absTimePosition); std::fflush(stdout); #endif @@ -1107,7 +1107,7 @@ BW_MidiSequencer::MidiEvent BW_MidiSequencer::parseEvent(const uint8_t **pptr, c return evt; } -void BW_MidiSequencer::handleEvent(size_t tk, const BW_MidiSequencer::MidiEvent &evt, int &status) +void BW_MidiSequencer::handleEvent(size_t tk, const BW_MidiSequencer::MidiEvent &evt, int32_t &status) { if(m_interface->onEvent) { @@ -1139,7 +1139,7 @@ void BW_MidiSequencer::handleEvent(size_t tk, const BW_MidiSequencer::MidiEvent if(evtype == MidiEvent::ST_TEMPOCHANGE)//Tempo change { - m_tempo = m_invDeltaTicks * fraction<uint64_t>(ReadBEint(evt.data.data(), evt.data.size())); + m_tempo = m_invDeltaTicks * fraction<uint64_t>(readBEint(evt.data.data(), evt.data.size())); return; } @@ -1463,12 +1463,17 @@ bool BW_MidiSequencer::loadMIDI(FileAndMemReader &fr) bool is_CMF = false; // Creative Music format (CMF/CTMF) bool is_RSXX = false; // RSXX, such as Cartooners - const size_t HeaderSize = 4 + 4 + 2 + 2 + 2; // 14 - char headerBuf[HeaderSize] = ""; + const size_t headerSize = 4 + 4 + 2 + 2 + 2; // 14 + char headerBuf[headerSize] = ""; size_t DeltaTicks = 192, TrackCount = 1; riffskip: - fsize = fr.read(headerBuf, 1, HeaderSize); + fsize = fr.read(headerBuf, 1, headerSize); + if(fsize < headerSize) + { + m_errorString = "Unexpected end of file at header!\n"; + return false; + } if(std::memcmp(headerBuf, "RIFF", 4) == 0) { @@ -1479,7 +1484,7 @@ riffskip: if(std::memcmp(headerBuf, "GMF\x1", 4) == 0) { // GMD/MUS files (ScummVM) - fr.seek(7 - static_cast<long>(HeaderSize), FileAndMemReader::CUR); + fr.seek(7 - static_cast<long>(headerSize), FileAndMemReader::CUR); is_GMF = true; } #ifndef BWMIDI_DISABLE_MUS_SUPPORT @@ -1494,7 +1499,14 @@ riffskip: m_errorString = "Out of memory!"; return false; } - fr.read(mus, 1, mus_len); + fsize = fr.read(mus, 1, mus_len); + if(fsize < mus_len) + { + fr.close(); + m_errorString = "Failed to read MUS file data!\n"; + return false; + } + //Close source stream fr.close(); @@ -1536,7 +1548,14 @@ riffskip: m_errorString = "Out of memory!"; return false; } - fr.read(mus, 1, mus_len); + fsize = fr.read(mus, 1, mus_len); + if(fsize < mus_len) + { + fr.close(); + m_errorString = "Failed to read XMI file data!\n"; + return false; + } + //Close source stream fr.close(); @@ -1567,23 +1586,43 @@ riffskip: is_CMF = true; m_format = Format_CMF; //unsigned version = ReadLEint(HeaderBuf+4, 2); - uint64_t ins_start = ReadLEint(headerBuf + 6, 2); - uint64_t mus_start = ReadLEint(headerBuf + 8, 2); + uint64_t ins_start = readLEint(headerBuf + 6, 2); + uint64_t mus_start = readLEint(headerBuf + 8, 2); //unsigned deltas = ReadLEint(HeaderBuf+10, 2); - uint64_t ticks = ReadLEint(headerBuf + 12, 2); + uint64_t ticks = readLEint(headerBuf + 12, 2); // Read title, author, remarks start offsets in file - fr.read(headerBuf, 1, 6); + fsize = fr.read(headerBuf, 1, 6); + if(fsize < 6) + { + fr.close(); + m_errorString = "Unexpected file ending on attempt to read CTMF header!"; + return false; + } + //unsigned long notes_starts[3] = {ReadLEint(HeaderBuf+0,2),ReadLEint(HeaderBuf+0,4),ReadLEint(HeaderBuf+0,6)}; fr.seek(16, FileAndMemReader::CUR); // Skip the channels-in-use table - fr.read(headerBuf, 1, 4); - uint64_t ins_count = ReadLEint(headerBuf + 0, 2); //, basictempo = ReadLEint(HeaderBuf+2, 2); + fsize = fr.read(headerBuf, 1, 4); + if(fsize < 4) + { + fr.close(); + m_errorString = "Unexpected file ending on attempt to read CMF instruments block header!"; + return false; + } + + uint64_t ins_count = readLEint(headerBuf + 0, 2); //, basictempo = ReadLEint(HeaderBuf+2, 2); fr.seek(static_cast<long>(ins_start), FileAndMemReader::SET); m_cmfInstruments.reserve(static_cast<size_t>(ins_count)); for(uint64_t i = 0; i < ins_count; ++i) { CmfInstrument inst; - fr.read(inst.data, 1, 16); + fsize = fr.read(inst.data, 1, 16); + if(fsize < 16) + { + fr.close(); + m_errorString = "Unexpected file ending on attempt to read CMF instruments raw data!"; + return false; + } m_cmfInstruments.push_back(inst); } @@ -1597,7 +1636,7 @@ riffskip: if(headerBuf[0] == 0x7D) { fr.seek(0x6D, FileAndMemReader::SET); - fr.read(headerBuf, 6, 1); + fr.read(headerBuf, 1, 6); if(std::memcmp(headerBuf, "rsxx}u", 6) == 0) { is_RSXX = true; @@ -1656,8 +1695,8 @@ riffskip: } /*size_t Fmt = ReadBEint(HeaderBuf + 8, 2);*/ - TrackCount = (size_t)ReadBEint(headerBuf + 10, 2); - DeltaTicks = (size_t)ReadBEint(headerBuf + 12, 2); + TrackCount = (size_t)readBEint(headerBuf + 10, 2); + DeltaTicks = (size_t)readBEint(headerBuf + 12, 2); } } @@ -1674,7 +1713,7 @@ riffskip: for(size_t tk = 0; tk < TrackCount; ++tk) { // Read track header - size_t TrackLength; + size_t trackLength; if(is_IMF) { @@ -1728,32 +1767,30 @@ riffskip: { size_t pos = fr.tell(); fr.seek(0, FileAndMemReader::END); - TrackLength = fr.tell() - pos; + trackLength = fr.tell() - pos; fr.seek(static_cast<long>(pos), FileAndMemReader::SET); } - //else if(is_MUS) // Read TrackLength from file position 4 - //{ - // size_t pos = fr.tell(); - // fr.seek(4, FileAndMemReader::SET); - // TrackLength = static_cast<size_t>(fr.getc()); - // TrackLength += static_cast<size_t>(fr.getc() << 8); - // fr.seek(static_cast<long>(pos), FileAndMemReader::SET); - //} else { fsize = fr.read(headerBuf, 1, 8); - if(std::memcmp(headerBuf, "MTrk", 4) != 0) + if((fsize < 8) || (std::memcmp(headerBuf, "MTrk", 4) != 0)) { fr.close(); m_errorString = fr.fileName() + ": Invalid format, MTrk signature is not found!\n"; return false; } - TrackLength = (size_t)ReadBEint(headerBuf + 4, 4); + trackLength = (size_t)readBEint(headerBuf + 4, 4); } // Read track data - rawTrackData[tk].resize(TrackLength); - fsize = fr.read(&rawTrackData[tk][0], 1, TrackLength); + rawTrackData[tk].resize(trackLength); + fsize = fr.read(&rawTrackData[tk][0], 1, trackLength); + if(fsize < trackLength) + { + fr.close(); + m_errorString = fr.fileName() + ": Unexpected file ending while getting raw track data!\n"; + return false; + } totalGotten += fsize; if(is_GMF/*|| is_MUS*/) // Note: CMF does include the track end tag. |