1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-11 23:54:18 +00:00

iOS Accessibility: Fix a potential use-after-free when deallocating a container element

This commit is contained in:
ed 2021-09-22 16:22:06 +01:00
parent 49fdf1a4d3
commit a6db2ef4ff
3 changed files with 30 additions and 26 deletions

View file

@ -23,6 +23,17 @@
==============================================================================
*/
static void juceFreeAccessibilityPlatformSpecificData (UIAccessibilityElement* element)
{
if (auto* container = juce::getIvar<UIAccessibilityElement*> (element, "container"))
{
object_setInstanceVariable (element, "container", nullptr);
object_setInstanceVariable (container, "handler", nullptr);
[container release];
}
}
namespace juce
{
@ -176,8 +187,6 @@ private:
private:
AccessibilityElement()
{
addMethod (@selector (dealloc), dealloc, "v@:");
addMethod (@selector (isAccessibilityElement), getIsAccessibilityElement, "c@:");
addMethod (@selector (accessibilityContainer), getAccessibilityContainer, "@@:");
addMethod (@selector (accessibilityFrame), getAccessibilityFrame, @encode (CGRect), "@:");
@ -221,17 +230,6 @@ private:
}
//==============================================================================
static void dealloc (id self, SEL)
{
if (UIAccessibilityElement* container = getContainer (self))
{
[container release];
object_setInstanceVariable (self, "container", nullptr);
}
sendSuperclassMessage<void> (self, @selector (dealloc));
}
static id getAccessibilityContainer (id self, SEL)
{
if (auto* handler = getHandler (self))
@ -245,14 +243,16 @@ private:
return container;
static AccessibilityContainer cls;
id windowHandle = (id) handler->getComponent().getWindowHandle();
UIAccessibilityElement* container = [cls.createInstance() initWithAccessibilityContainer: windowHandle];
object_setInstanceVariable (container, "handler", handler);
[container retain];
object_setInstanceVariable (container, "handler", handler);
object_setInstanceVariable (self, "container", container);
return (id) getContainer (self);
return container;
}
if (auto* parent = handler->getParent())

View file

@ -23,6 +23,8 @@
==============================================================================
*/
static void juceFreeAccessibilityPlatformSpecificData (NSAccessibilityElement<NSAccessibility>*) {}
namespace juce
{

View file

@ -27,21 +27,23 @@ namespace juce
{
//==============================================================================
struct AccessibleObjCClassDeleter
{
template <typename ElementType>
void operator() (ElementType* element) const
{
juceFreeAccessibilityPlatformSpecificData (element);
object_setInstanceVariable (element, "handler", nullptr);
[element release];
}
};
template <typename Base>
class AccessibleObjCClass : public ObjCClass<Base>
{
private:
struct Deleter
{
void operator() (Base* element) const
{
object_setInstanceVariable (element, "handler", nullptr);
[element release];
}
};
public:
using Holder = std::unique_ptr<Base, Deleter>;
using Holder = std::unique_ptr<Base, AccessibleObjCClassDeleter>;
protected:
AccessibleObjCClass() : ObjCClass<Base> ("JUCEAccessibilityElement_")