aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/adlmidi.cpp5
-rw-r--r--src/midi_sequencer.hpp17
-rw-r--r--src/midi_sequencer_impl.hpp109
3 files changed, 88 insertions, 43 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index 69755d3..efd716c 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -517,7 +517,10 @@ ADLMIDI_EXPORT int adl_switchEmulator(struct ADL_MIDIPlayer *device, int emulato
if(device)
{
MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
- if(play && (emulator >= 0) && (emulator < ADLMIDI_EMU_end))
+ assert(play);
+ if(!play)
+ return -1;
+ if((emulator >= 0) && (emulator < ADLMIDI_EMU_end))
{
play->m_setup.emulator = emulator;
adl_reset(device);
diff --git a/src/midi_sequencer.hpp b/src/midi_sequencer.hpp
index a8e04d0..89b4619 100644
--- a/src/midi_sequencer.hpp
+++ b/src/midi_sequencer.hpp
@@ -189,7 +189,8 @@ class BW_MidiSequencer
{
//! Was track began playing
bool began;
- char padding[7];
+ //! Reserved
+ char __padding[7];
//! Waiting time before next event in seconds
double wait;
//! Absolute time position on the track in seconds
@@ -197,15 +198,19 @@ class BW_MidiSequencer
//! Track information
struct TrackInfo
{
- size_t ptr;
//! Delay to next event in a track
uint64_t delay;
//! Last handled event type
- int lastHandledEvent;
- char padding2[4];
+ int32_t lastHandledEvent;
+ //! Reserved
+ char __padding2[4];
//! MIDI Events queue position iterator
MidiTrackQueue::iterator pos;
- TrackInfo(): ptr(0), delay(0), lastHandledEvent(0) {}
+
+ TrackInfo() :
+ delay(0),
+ lastHandledEvent(0)
+ {}
};
std::vector<TrackInfo> track;
Position(): began(false), wait(0.0), absTimePosition(0.0), track()
@@ -243,7 +248,7 @@ class BW_MidiSequencer
* @param evt MIDI event entry
* @param status Recent event type, -1 returned when end of track event was handled.
*/
- void handleEvent(size_t tk, const MidiEvent &evt, int &status);
+ void handleEvent(size_t tk, const MidiEvent &evt, int32_t &status);
public:
/**
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.