From 6aae0c798cbacc8f72af4d6c983a2151e8cf679e Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 26 Sep 2013 12:05:01 +0100 Subject: [PATCH] Added sanity-checking in AudioProcessor to block parameter change calls with nonsense indexes (as seen being sent by some buggy plugins). Also improved AudioProcessor::copyXmlToBinary method. --- .../processors/juce_AudioProcessor.cpp | 92 +++++++++++-------- .../processors/juce_AudioProcessor.h | 10 +- 2 files changed, 59 insertions(+), 43 deletions(-) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 85375c49f8..89a790c10c 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -139,44 +139,59 @@ AudioProcessorListener* AudioProcessor::getListenerLocked (const int index) cons void AudioProcessor::sendParamChangeMessageToListeners (const int parameterIndex, const float newValue) { - jassert (isPositiveAndBelow (parameterIndex, getNumParameters())); - - for (int i = listeners.size(); --i >= 0;) - if (AudioProcessorListener* l = getListenerLocked (i)) - l->audioProcessorParameterChanged (this, parameterIndex, newValue); + if (isPositiveAndBelow (parameterIndex, getNumParameters())) + { + for (int i = listeners.size(); --i >= 0;) + if (AudioProcessorListener* l = getListenerLocked (i)) + l->audioProcessorParameterChanged (this, parameterIndex, newValue); + } + else + { + jassertfalse; // called with an out-of-range parameter index! + } } void AudioProcessor::beginParameterChangeGesture (int parameterIndex) { - jassert (isPositiveAndBelow (parameterIndex, getNumParameters())); + if (isPositiveAndBelow (parameterIndex, getNumParameters())) + { + #if JUCE_DEBUG + // This means you've called beginParameterChangeGesture twice in succession without a matching + // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it. + jassert (! changingParams [parameterIndex]); + changingParams.setBit (parameterIndex); + #endif - #if JUCE_DEBUG - // This means you've called beginParameterChangeGesture twice in succession without a matching - // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it. - jassert (! changingParams [parameterIndex]); - changingParams.setBit (parameterIndex); - #endif - - for (int i = listeners.size(); --i >= 0;) - if (AudioProcessorListener* l = getListenerLocked (i)) - l->audioProcessorParameterChangeGestureBegin (this, parameterIndex); + for (int i = listeners.size(); --i >= 0;) + if (AudioProcessorListener* l = getListenerLocked (i)) + l->audioProcessorParameterChangeGestureBegin (this, parameterIndex); + } + else + { + jassertfalse; // called with an out-of-range parameter index! + } } void AudioProcessor::endParameterChangeGesture (int parameterIndex) { - jassert (isPositiveAndBelow (parameterIndex, getNumParameters())); + if (isPositiveAndBelow (parameterIndex, getNumParameters())) + { + #if JUCE_DEBUG + // This means you've called endParameterChangeGesture without having previously called + // endParameterChangeGesture. That might be fine in most hosts, but better to keep the + // calls matched correctly. + jassert (changingParams [parameterIndex]); + changingParams.clearBit (parameterIndex); + #endif - #if JUCE_DEBUG - // This means you've called endParameterChangeGesture without having previously called - // endParameterChangeGesture. That might be fine in most hosts, but better to keep the - // calls matched correctly. - jassert (changingParams [parameterIndex]); - changingParams.clearBit (parameterIndex); - #endif - - for (int i = listeners.size(); --i >= 0;) - if (AudioProcessorListener* l = getListenerLocked (i)) - l->audioProcessorParameterChangeGestureEnd (this, parameterIndex); + for (int i = listeners.size(); --i >= 0;) + if (AudioProcessorListener* l = getListenerLocked (i)) + l->audioProcessorParameterChangeGestureEnd (this, parameterIndex); + } + else + { + jassertfalse; // called with an out-of-range parameter index! + } } void AudioProcessor::updateHostDisplay() @@ -247,16 +262,17 @@ const uint32 magicXmlNumber = 0x21324356; void AudioProcessor::copyXmlToBinary (const XmlElement& xml, juce::MemoryBlock& destData) { - const String xmlString (xml.createDocument (String::empty, true, false)); - const size_t stringLength = xmlString.getNumBytesAsUTF8(); + { + MemoryOutputStream out (destData, false); + out.writeInt (magicXmlNumber); + out.writeInt (0); + xml.writeToStream (out, String::empty, true, false); + out.writeByte (0); + } - destData.setSize (stringLength + 9); - - uint32* const d = static_cast (destData.getData()); - d[0] = ByteOrder::swapIfBigEndian ((const uint32) magicXmlNumber); - d[1] = ByteOrder::swapIfBigEndian ((const uint32) stringLength); - - xmlString.copyToUTF8 ((CharPointer_UTF8::CharType*) (d + 2), stringLength + 1); + // go back and write the string length.. + static_cast (destData.getData())[1] + = ByteOrder::swapIfBigEndian ((uint32) destData.getSize() - 9); } XmlElement* AudioProcessor::getXmlFromBinary (const void* data, const int sizeInBytes) @@ -276,7 +292,7 @@ XmlElement* AudioProcessor::getXmlFromBinary (const void* data, const int sizeIn //============================================================================== void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} -void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int) {} +void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int) {} //============================================================================== bool AudioPlayHead::CurrentPositionInfo::operator== (const CurrentPositionInfo& other) const noexcept diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index d526a2e5f3..3caaec373e 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -620,10 +620,6 @@ public: */ WrapperType wrapperType; - /** @internal */ - static void JUCE_CALLTYPE setTypeOfNextNewPlugin (WrapperType); - -protected: //============================================================================== /** Helper function that just converts an xml element into a binary blob. @@ -643,6 +639,10 @@ protected: */ static XmlElement* getXmlFromBinary (const void* data, int sizeInBytes); + /** @internal */ + static void JUCE_CALLTYPE setTypeOfNextNewPlugin (WrapperType); + +protected: /** @internal */ AudioPlayHead* playHead; @@ -650,7 +650,7 @@ protected: void sendParamChangeMessageToListeners (int parameterIndex, float newValue); private: - Array listeners; + Array listeners; Component::SafePointer activeEditor; double sampleRate; int blockSize, numInputChannels, numOutputChannels, latencySamples;