|
From: <man...@us...> - 2014-02-18 20:53:15
|
Revision: 3738
http://sourceforge.net/p/modplug/code/3738
Author: manxorist
Date: 2014-02-18 20:53:06 +0000 (Tue, 18 Feb 2014)
Log Message:
-----------
[Fix] Taking references or pointers (of non-packed type) to members of packed structures is not allowed and causes unaligned memory access later on. Avoid it in XM instrument I/O code by passing an envelope type enum and accessing the packed envelope data directly depending on which envelope is selected. (found with clang sanitizer)
Modified Paths:
--------------
trunk/OpenMPT/soundlib/XMTools.cpp
trunk/OpenMPT/soundlib/XMTools.h
Modified: trunk/OpenMPT/soundlib/XMTools.cpp
===================================================================
--- trunk/OpenMPT/soundlib/XMTools.cpp 2014-02-18 20:42:09 UTC (rev 3737)
+++ trunk/OpenMPT/soundlib/XMTools.cpp 2014-02-18 20:53:06 UTC (rev 3738)
@@ -49,16 +49,25 @@
// Convert OpenMPT's internal envelope representation to XM envelope data.
-void XMInstrument::ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8 &numPoints, uint8 &flags, uint8 &sustain, uint8 &loopStart, uint8 &loopEnd, uint16 *envData)
-//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+void XMInstrument::ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8 &numPoints, uint8 &flags, uint8 &sustain, uint8 &loopStart, uint8 &loopEnd, EnvType env)
+//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
{
numPoints = static_cast<uint8>(std::min(12u, mptEnv.nNodes));
// Envelope Data
for(size_t i = 0; i < numPoints; i++)
{
- envData[i * 2] = std::min(mptEnv.Ticks[i], uint16_max);
- envData[i * 2 + 1] = mptEnv.Values[i];
+ switch(env)
+ {
+ case EnvTypeVol:
+ volEnv[i * 2] = std::min(mptEnv.Ticks[i], uint16_max);
+ volEnv[i * 2 + 1] = mptEnv.Values[i];
+ break;
+ case EnvTypePan:
+ panEnv[i * 2] = std::min(mptEnv.Ticks[i], uint16_max);
+ panEnv[i * 2 + 1] = mptEnv.Values[i];
+ break;
+ }
}
// Envelope Flags
@@ -84,8 +93,8 @@
volFade = static_cast<uint16>(std::min(mptIns.nFadeOut, uint32(32767)));
// Convert envelopes
- ConvertEnvelopeToXM(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, volEnv);
- ConvertEnvelopeToXM(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, panEnv);
+ ConvertEnvelopeToXM(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, EnvTypeVol);
+ ConvertEnvelopeToXM(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, EnvTypePan);
// Create sample assignment table
std::vector<SAMPLEINDEX> sampleList = GetSampleList(mptIns, compatibilityExport);
@@ -146,16 +155,25 @@
// Convert XM envelope data to an OpenMPT's internal envelope representation.
-void XMInstrument::ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, const uint16 (&envData)[24]) const
-//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+void XMInstrument::ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, EnvType env) const
+//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
{
mptEnv.nNodes = MIN(numPoints, 12);
// Envelope Data
for(size_t i = 0; i < 12; i++)
{
- mptEnv.Ticks[i] = envData[i * 2];
- mptEnv.Values[i] = static_cast<uint8>(envData[i * 2 + 1]);
+ switch(env)
+ {
+ case EnvTypeVol:
+ mptEnv.Ticks[i] = volEnv[i * 2];
+ mptEnv.Values[i] = static_cast<uint8>(volEnv[i * 2 + 1]);
+ break;
+ case EnvTypePan:
+ mptEnv.Ticks[i] = panEnv[i * 2];
+ mptEnv.Values[i] = static_cast<uint8>(panEnv[i * 2 + 1]);
+ break;
+ }
if(i > 0 && mptEnv.Ticks[i] < mptEnv.Ticks[i - 1])
{
@@ -199,8 +217,8 @@
mptIns.nFadeOut = volFade;
// Convert envelopes
- ConvertEnvelopeToMPT(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, volEnv);
- ConvertEnvelopeToMPT(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, panEnv);
+ ConvertEnvelopeToMPT(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, EnvTypeVol);
+ ConvertEnvelopeToMPT(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, EnvTypePan);
// Create sample assignment table
for(size_t i = 0; i < CountOf(sampleMap); i++)
Modified: trunk/OpenMPT/soundlib/XMTools.h
===================================================================
--- trunk/OpenMPT/soundlib/XMTools.h 2014-02-18 20:42:09 UTC (rev 3737)
+++ trunk/OpenMPT/soundlib/XMTools.h 2014-02-18 20:53:06 UTC (rev 3738)
@@ -85,10 +85,15 @@
// Convert all multi-byte numeric values to current platform's endianness or vice versa.
void ConvertEndianness();
+ enum EnvType
+ {
+ EnvTypeVol,
+ EnvTypePan,
+ };
// Convert OpenMPT's internal envelope representation to XM envelope data.
- void ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8 &numPoints, uint8 &flags, uint8 &sustain, uint8 &loopStart, uint8 &loopEnd, uint16 *envData);
+ void ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8 &numPoints, uint8 &flags, uint8 &sustain, uint8 &loopStart, uint8 &loopEnd, EnvType env);
// Convert XM envelope data to an OpenMPT's internal envelope representation.
- void ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, const uint16 (&envData)[24]) const;
+ void ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, EnvType env) const;
// Convert OpenMPT's internal sample representation to an XMInstrument.
uint16 ConvertToXM(const ModInstrument &mptIns, bool compatibilityExport);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|