From 4d03aca33606cfd502cabaa1a18a14b7f8d15efd Mon Sep 17 00:00:00 2001 From: Eetu Rantanen Date: Thu, 24 Nov 2022 05:46:08 +0200 Subject: [PATCH] Button: prevent crashes caused by _isWithinBounds There's currently a chance that the button's touch event is still called after the button's `view.parent` has already been removed and set to nil. This will result in a runtime error within `function widget._isWithinBounds( object, event )` when it attempts to index a nil value (i.e. `object.contentBounds` within `object` as it isn't a table anymore). https://github.com/coronalabs/framework-widget/blob/d425ae72f47b29a3da5880eebcb1111f2cdf6cd2/widgetLibrary/widget.lua#L245-L257 The safest and easiest way to fix this issue is to just check that the button's `view.parent` exists and is still a display object at the start of the touch listener. As a part of these changes, there's no need for further checks to see if the parent view exists given that the function won't get past the new initial check if it doesn't. --- widgetLibrary/widget_button.lua | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/widgetLibrary/widget_button.lua b/widgetLibrary/widget_button.lua index 5ea5ce6..4534786 100755 --- a/widgetLibrary/widget_button.lua +++ b/widgetLibrary/widget_button.lua @@ -20,8 +20,8 @@ local isByteColorRange = display.getDefault( "isByteColorRange" ) local function manageButtonTouch( view, event ) local phase = event.phase - -- If the button isn't active, just return - if not view._isEnabled then + -- If the button isn't active or it has somehow already been removed, just return + if not view._isEnabled or type( view.parent ) ~= "table" or view.parent.x == nil then return end @@ -43,13 +43,9 @@ local function manageButtonTouch( view, event ) view._onPress( event ) end - -- If the parent group still exists - if "table" == type( view.parent ) then - -- Set focus on the button - view._isFocus = true - display.getCurrentStage():setFocus( view, event.id ) - - end + -- Set focus on the button + view._isFocus = true + display.getCurrentStage():setFocus( view, event.id ) elseif view._isFocus then if "moved" == phase then