| @@ -785,6 +785,27 @@ public: | |||||
| // Remove the data entry from the state to prevent the superclass loading the parameters | // Remove the data entry from the state to prevent the superclass loading the parameters | ||||
| CFUniquePtr<CFMutableDictionaryRef> copyWithoutData (CFDictionaryCreateMutableCopy (nullptr, 0, (CFDictionaryRef) inData)); | CFUniquePtr<CFMutableDictionaryRef> copyWithoutData (CFDictionaryCreateMutableCopy (nullptr, 0, (CFDictionaryRef) inData)); | ||||
| CFDictionaryRemoveValue (copyWithoutData.get(), CFSTR (kAUPresetDataKey)); | CFDictionaryRemoveValue (copyWithoutData.get(), CFSTR (kAUPresetDataKey)); | ||||
| auto* originalVersion = static_cast<CFNumberRef> (CFDictionaryGetValue (copyWithoutData.get(), CFSTR (kAUPresetVersionKey))); | |||||
| if (originalVersion != nullptr && CFGetTypeID (originalVersion) == CFNumberGetTypeID()) | |||||
| { | |||||
| SInt32 value = 0; | |||||
| CFNumberGetValue (originalVersion, kCFNumberSInt32Type, &value); | |||||
| // Data with a version of "1" is generated by AUv3 plug-ins. | |||||
| // This data appears to be compatible with RestoreState below, but RestoreState | |||||
| // fails when "version" is not 0. | |||||
| // We only overwrite the version if it is 1 so that if future preset versions are | |||||
| // completely incompatible, RestoreState will be bypassed rather than passed data | |||||
| // which could put the plugin into a broken state. | |||||
| if (value == 1) | |||||
| { | |||||
| const SInt32 zero = 0; | |||||
| CFUniquePtr<CFNumberRef> newVersion (CFNumberCreate (nullptr, kCFNumberSInt32Type, &zero)); | |||||
| CFDictionarySetValue (copyWithoutData.get(), CFSTR (kAUPresetVersionKey), newVersion.get()); | |||||
| } | |||||
| } | |||||
| ComponentResult err = MusicDeviceBase::RestoreState (copyWithoutData.get()); | ComponentResult err = MusicDeviceBase::RestoreState (copyWithoutData.get()); | ||||
| if (err != noErr) | if (err != noErr) | ||||