mirror of
https://github.com/AxioDL/amuse.git
synced 2025-07-06 13:16:15 +00:00
Add bounds checking to SoundMacro execution loop
This commit is contained in:
parent
c886bfd7d2
commit
eb948dfd63
@ -103,7 +103,7 @@ if (APPLE AND (NOT CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET VE
|
|||||||
)
|
)
|
||||||
|
|
||||||
else()
|
else()
|
||||||
message(WARNING "Unable to find developer provision profile; skipping Amuse-AU")
|
message(WARNING "Unable to find developer provisioning profile; skipping Amuse-AU")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "Entity.hpp"
|
#include "Entity.hpp"
|
||||||
|
#include "Common.hpp"
|
||||||
|
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
@ -119,6 +120,17 @@ class SoundMacroState
|
|||||||
/** 'program counter' stack for the active SoundMacro */
|
/** 'program counter' stack for the active SoundMacro */
|
||||||
std::vector<std::pair<const unsigned char*, int>> m_pc;
|
std::vector<std::pair<const unsigned char*, int>> m_pc;
|
||||||
|
|
||||||
|
static int _assertPC(int pc, uint32_t size);
|
||||||
|
static int _assertPC(int pc, uint32_t size, bool swapSize)
|
||||||
|
{
|
||||||
|
return _assertPC(pc, swapSize ? SBig(size) : size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setPC(int pc)
|
||||||
|
{
|
||||||
|
m_pc.back().second = _assertPC(pc, m_header.m_size);
|
||||||
|
}
|
||||||
|
|
||||||
double m_ticksPerSec; /**< ratio for resolving ticks in commands that use them */
|
double m_ticksPerSec; /**< ratio for resolving ticks in commands that use them */
|
||||||
uint8_t m_initVel; /**< Velocity played for this macro invocation */
|
uint8_t m_initVel; /**< Velocity played for this macro invocation */
|
||||||
uint8_t m_initMod; /**< Modulation played for this macro invocation */
|
uint8_t m_initMod; /**< Modulation played for this macro invocation */
|
||||||
|
@ -13,6 +13,19 @@
|
|||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int SoundMacroState::_assertPC(int pc, uint32_t size)
|
||||||
|
{
|
||||||
|
if (pc == -1)
|
||||||
|
return -1;
|
||||||
|
int cmdCount = (size - sizeof(Header)) / sizeof(Command);
|
||||||
|
if (pc >= cmdCount)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "SoundMacro PC bounds exceeded [%d/%d]\n", pc, cmdCount);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
void SoundMacroState::Header::swapBig()
|
void SoundMacroState::Header::swapBig()
|
||||||
{
|
{
|
||||||
m_size = SBig(m_size);
|
m_size = SBig(m_size);
|
||||||
@ -133,7 +146,8 @@ void SoundMacroState::initialize(const unsigned char* ptr, int step, double tick
|
|||||||
m_curMod = midiMod;
|
m_curMod = midiMod;
|
||||||
m_curPitch = midiKey * 100;
|
m_curPitch = midiKey * 100;
|
||||||
m_pc.clear();
|
m_pc.clear();
|
||||||
m_pc.push_back({ptr, step});
|
const Header& header = reinterpret_cast<const Header&>(ptr);
|
||||||
|
m_pc.push_back({ptr, _assertPC(step, header.m_size, swapData)});
|
||||||
m_inWait = false;
|
m_inWait = false;
|
||||||
m_execTime = 0.f;
|
m_execTime = 0.f;
|
||||||
m_keyoff = false;
|
m_keyoff = false;
|
||||||
@ -143,7 +157,7 @@ void SoundMacroState::initialize(const unsigned char* ptr, int step, double tick
|
|||||||
m_useAdsrControllers = false;
|
m_useAdsrControllers = false;
|
||||||
m_portamentoMode = 2;
|
m_portamentoMode = 2;
|
||||||
m_portamentoTime = 0.5f;
|
m_portamentoTime = 0.5f;
|
||||||
m_header = *reinterpret_cast<const Header*>(ptr);
|
m_header = header;
|
||||||
if (swapData)
|
if (swapData)
|
||||||
m_header.swapBig();
|
m_header.swapBig();
|
||||||
}
|
}
|
||||||
@ -180,6 +194,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
|
|
||||||
/* Load next command based on counter */
|
/* Load next command based on counter */
|
||||||
const Command* commands = reinterpret_cast<const Command*>(m_pc.back().first + sizeof(Header));
|
const Command* commands = reinterpret_cast<const Command*>(m_pc.back().first + sizeof(Header));
|
||||||
|
_assertPC(m_pc.back().second, m_header.m_size);
|
||||||
Command cmd = commands[m_pc.back().second++];
|
Command cmd = commands[m_pc.back().second++];
|
||||||
if (vox.getAudioGroup().getDataFormat() != DataFormat::PC)
|
if (vox.getAudioGroup().getDataFormat() != DataFormat::PC)
|
||||||
cmd.swapBig();
|
cmd.swapBig();
|
||||||
@ -189,7 +204,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
{
|
{
|
||||||
case Op::End:
|
case Op::End:
|
||||||
case Op::Stop:
|
case Op::Stop:
|
||||||
m_pc.back().second = -1;
|
_setPC(-1);
|
||||||
return true;
|
return true;
|
||||||
case Op::SplitKey:
|
case Op::SplitKey:
|
||||||
{
|
{
|
||||||
@ -201,7 +216,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
{
|
{
|
||||||
/* Do Branch */
|
/* Do Branch */
|
||||||
if (macroId == m_header.m_macroId)
|
if (macroId == m_header.m_macroId)
|
||||||
m_pc.back().second = macroStep;
|
_setPC(macroStep);
|
||||||
else
|
else
|
||||||
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
||||||
}
|
}
|
||||||
@ -218,7 +233,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
{
|
{
|
||||||
/* Do Branch */
|
/* Do Branch */
|
||||||
if (macroId == m_header.m_macroId)
|
if (macroId == m_header.m_macroId)
|
||||||
m_pc.back().second = macroStep;
|
_setPC(macroStep);
|
||||||
else
|
else
|
||||||
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
||||||
}
|
}
|
||||||
@ -287,7 +302,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
{
|
{
|
||||||
/* Loop back to step */
|
/* Loop back to step */
|
||||||
--m_loopCountdown;
|
--m_loopCountdown;
|
||||||
m_pc.back().second = step;
|
_setPC(step);
|
||||||
}
|
}
|
||||||
else /* Break out of loop */
|
else /* Break out of loop */
|
||||||
m_loopCountdown = -1;
|
m_loopCountdown = -1;
|
||||||
@ -301,7 +316,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
|
|
||||||
/* Do Branch */
|
/* Do Branch */
|
||||||
if (macroId == m_header.m_macroId)
|
if (macroId == m_header.m_macroId)
|
||||||
m_pc.back().second = macroStep;
|
_setPC(macroStep);
|
||||||
else
|
else
|
||||||
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
||||||
|
|
||||||
@ -389,7 +404,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
{
|
{
|
||||||
/* Do Branch */
|
/* Do Branch */
|
||||||
if (macroId == m_header.m_macroId)
|
if (macroId == m_header.m_macroId)
|
||||||
m_pc.back().second = macroStep;
|
_setPC(macroStep);
|
||||||
else
|
else
|
||||||
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
||||||
}
|
}
|
||||||
@ -511,7 +526,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
{
|
{
|
||||||
/* Do branch */
|
/* Do branch */
|
||||||
if (macroId == m_header.m_macroId)
|
if (macroId == m_header.m_macroId)
|
||||||
m_pc.back().second = macroStep;
|
_setPC(macroStep);
|
||||||
else
|
else
|
||||||
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod);
|
||||||
}
|
}
|
||||||
@ -776,7 +791,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
int16_t macroStep = *reinterpret_cast<int16_t*>(&cmd.m_data[3]);
|
int16_t macroStep = *reinterpret_cast<int16_t*>(&cmd.m_data[3]);
|
||||||
|
|
||||||
if (macroId == m_header.m_macroId)
|
if (macroId == m_header.m_macroId)
|
||||||
m_pc.push_back({m_pc.back().first, macroStep});
|
m_pc.push_back({m_pc.back().first, _assertPC(macroStep, m_header.m_size)});
|
||||||
else
|
else
|
||||||
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod, true);
|
vox.loadSoundObject(macroId, macroStep, m_ticksPerSec, m_initKey, m_initVel, m_initMod, true);
|
||||||
|
|
||||||
@ -1205,7 +1220,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
b = m_variables[b];
|
b = m_variables[b];
|
||||||
|
|
||||||
if ((a == b) ^ lnot)
|
if ((a == b) ^ lnot)
|
||||||
m_pc.back().second = macroStep;
|
_setPC(macroStep);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1229,7 +1244,7 @@ bool SoundMacroState::advance(Voice& vox, double dt)
|
|||||||
b = m_variables[b];
|
b = m_variables[b];
|
||||||
|
|
||||||
if ((a < b) ^ lnot)
|
if ((a < b) ^ lnot)
|
||||||
m_pc.back().second = macroStep;
|
_setPC(macroStep);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,8 @@ void Voice::_macroSampleEnd()
|
|||||||
{
|
{
|
||||||
if (m_sampleEndTrap.macroId == m_state.m_header.m_macroId)
|
if (m_sampleEndTrap.macroId == m_state.m_header.m_macroId)
|
||||||
{
|
{
|
||||||
m_state.m_pc.back().second = m_sampleEndTrap.macroStep;
|
m_state.m_pc.back().second = SoundMacroState::_assertPC(m_sampleEndTrap.macroStep,
|
||||||
|
m_state.m_header.m_size);
|
||||||
m_state.m_inWait = false;
|
m_state.m_inWait = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -751,9 +752,11 @@ bool Voice::_loadSoundMacro(const unsigned char* macroData, int macroStep, doubl
|
|||||||
{
|
{
|
||||||
if (!pushPc)
|
if (!pushPc)
|
||||||
m_state.m_pc.clear();
|
m_state.m_pc.clear();
|
||||||
m_state.m_pc.push_back({macroData, macroStep});
|
const SoundMacroState::Header& header = reinterpret_cast<const SoundMacroState::Header&>(macroData);
|
||||||
m_state.m_header = *reinterpret_cast<const SoundMacroState::Header*>(macroData);
|
const bool swapData = m_audioGroup.getDataFormat() != DataFormat::PC;
|
||||||
if (m_audioGroup.getDataFormat() != DataFormat::PC)
|
m_state.m_pc.push_back({macroData, SoundMacroState::_assertPC(macroStep, header.m_size, swapData)});
|
||||||
|
m_state.m_header = header;
|
||||||
|
if (swapData)
|
||||||
m_state.m_header.swapBig();
|
m_state.m_header.swapBig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -846,7 +849,8 @@ void Voice::keyOff()
|
|||||||
{
|
{
|
||||||
if (m_keyoffTrap.macroId == m_state.m_header.m_macroId)
|
if (m_keyoffTrap.macroId == m_state.m_header.m_macroId)
|
||||||
{
|
{
|
||||||
m_state.m_pc.back().second = m_keyoffTrap.macroStep;
|
m_state.m_pc.back().second = SoundMacroState::_assertPC(m_keyoffTrap.macroStep,
|
||||||
|
m_state.m_header.m_size);
|
||||||
m_state.m_inWait = false;
|
m_state.m_inWait = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -867,7 +871,8 @@ void Voice::message(int32_t val)
|
|||||||
if (m_messageTrap.macroId != 0xffff)
|
if (m_messageTrap.macroId != 0xffff)
|
||||||
{
|
{
|
||||||
if (m_messageTrap.macroId == m_state.m_header.m_macroId)
|
if (m_messageTrap.macroId == m_state.m_header.m_macroId)
|
||||||
m_state.m_pc.back().second = m_messageTrap.macroStep;
|
m_state.m_pc.back().second = SoundMacroState::_assertPC(m_messageTrap.macroStep,
|
||||||
|
m_state.m_header.m_size);
|
||||||
else
|
else
|
||||||
loadSoundObject(m_messageTrap.macroId, m_messageTrap.macroStep, m_state.m_ticksPerSec, m_state.m_initKey,
|
loadSoundObject(m_messageTrap.macroId, m_messageTrap.macroStep, m_state.m_ticksPerSec, m_state.m_initKey,
|
||||||
m_state.m_initVel, m_state.m_initMod);
|
m_state.m_initVel, m_state.m_initMod);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user