From f2fffe6757d67be6723b08f9b5e17e075e8bb541 Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 11 Mar 2021 12:04:50 +0000 Subject: [PATCH] AU: Avoid a crash when calling setCurrentProgram() with an out-of-bounds index --- .../juce_AudioUnitPluginFormat.mm | 90 +++++++++---------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index 2ebce0d407..b70c067a08 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -1213,23 +1213,33 @@ public: } //============================================================================== - int getNumPrograms() override + struct ScopedFactoryPresets { - CFArrayRef presets; - UInt32 sz = sizeof (CFArrayRef); - int num = 0; - - if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets, - kAudioUnitScope_Global, 0, &presets, &sz) == noErr) + ScopedFactoryPresets (AudioUnit& au) { - if (presets != nullptr) - { - num = (int) CFArrayGetCount (presets); - CFRelease (presets); - } + UInt32 sz = sizeof (CFArrayRef); + + AudioUnitGetProperty (au, kAudioUnitProperty_FactoryPresets, + kAudioUnitScope_Global, 0, &presets, &sz); } - return num; + ~ScopedFactoryPresets() + { + if (presets != nullptr) + CFRelease (presets); + } + + CFArrayRef presets = nullptr; + }; + + int getNumPrograms() override + { + ScopedFactoryPresets factoryPresets { audioUnit }; + + if (factoryPresets.presets != nullptr) + return (int) CFArrayGetCount (factoryPresets.presets); + + return 0; } int getCurrentProgram() override @@ -1246,33 +1256,26 @@ public: void setCurrentProgram (int newIndex) override { - AUPreset current; - current.presetNumber = newIndex; + ScopedFactoryPresets factoryPresets { audioUnit }; - CFArrayRef presets; - UInt32 sz = sizeof (CFArrayRef); - - if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets, - kAudioUnitScope_Global, 0, &presets, &sz) == noErr) + if (factoryPresets.presets != nullptr + && newIndex < (int) CFArrayGetCount (factoryPresets.presets)) { - if (auto* p = (const AUPreset*) CFArrayGetValueAtIndex (presets, newIndex)) + AUPreset current; + current.presetNumber = newIndex; + + if (auto* p = static_cast (CFArrayGetValueAtIndex (factoryPresets.presets, newIndex))) current.presetName = p->presetName; - CFRelease (presets); + AudioUnitSetProperty (audioUnit, kAudioUnitProperty_PresentPreset, + kAudioUnitScope_Global, 0, ¤t, sizeof (AUPreset)); + + sendAllParametersChangedEvents(); } - - AudioUnitSetProperty (audioUnit, kAudioUnitProperty_PresentPreset, - kAudioUnitScope_Global, 0, ¤t, sizeof (AUPreset)); - - sendAllParametersChangedEvents(); } const String getProgramName (int index) override { - String s; - CFArrayRef presets; - UInt32 sz = sizeof (CFArrayRef); - if (index == -1) { AUPreset current; @@ -1284,27 +1287,20 @@ public: AudioUnitGetProperty (audioUnit, kAudioUnitProperty_PresentPreset, kAudioUnitScope_Global, 0, ¤t, &prstsz); - s = String::fromCFString (current.presetName); + return String::fromCFString (current.presetName); } - else if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_FactoryPresets, - kAudioUnitScope_Global, 0, &presets, &sz) == noErr) + + ScopedFactoryPresets factoryPresets { audioUnit }; + + if (factoryPresets.presets != nullptr) { - for (CFIndex i = 0; i < CFArrayGetCount (presets); ++i) - { - if (auto* p = (const AUPreset*) CFArrayGetValueAtIndex (presets, i)) - { + for (CFIndex i = 0; i < CFArrayGetCount (factoryPresets.presets); ++i) + if (auto* p = static_cast (CFArrayGetValueAtIndex (factoryPresets.presets, i))) if (p->presetNumber == index) - { - s = String::fromCFString (p->presetName); - break; - } - } - } - - CFRelease (presets); + return String::fromCFString (p->presetName); } - return s; + return {}; } void changeProgramName (int /*index*/, const String& /*newName*/) override