From 5828ef8f1c992dc58cac5f1c1662b823aa04ad4f Mon Sep 17 00:00:00 2001 From: poire-z Date: Wed, 20 Sep 2017 17:35:30 +0200 Subject: [PATCH] Fix potential crash when clearing hold highlight (#3241) A delayed clear() could reset hold_pos while a onHold/onHoldPan/ onHoldRelease is in progress, resulting in hold_pos becoming nil and a crash. --- .../apps/reader/modules/readerhighlight.lua | 19 ++++++++++++++++++- frontend/ui/widget/dictquicklookup.lua | 8 +++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index de9f1003e..6137c9757 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -110,7 +110,23 @@ function ReaderHighlight:genHighlightDrawerMenu() } end -function ReaderHighlight:clear() +-- Returns a unique id, that can be provided on delayed call to :clear(id) +-- to ensure current highlight has not already been cleared, and that we +-- are not going to clear a new highlight +function ReaderHighlight:getClearId() + self.clear_id = TimeVal.now() -- can act as a unique id + return self.clear_id +end + +function ReaderHighlight:clear(clear_id) + if clear_id then -- should be provided by delayed call to clear() + if clear_id ~= self.clear_id then + -- if clear_id is no more valid, highlight has already been + -- cleared since this clear_id was given + return + end + end + self.clear_id = nil -- invalidate id if self.ui.document.info.has_pages then self.view.highlight.temp = {} else @@ -223,6 +239,7 @@ end function ReaderHighlight:onHold(arg, ges) -- disable hold gesture if highlighting is disabled if self.view.highlight.disabled then return true end + self:clear() -- clear previous highlight (delayed clear may not have done it yet) self.hold_pos = self.view:screenToPageTransform(ges.pos) logger.dbg("hold position in page", self.hold_pos) if not self.hold_pos then diff --git a/frontend/ui/widget/dictquicklookup.lua b/frontend/ui/widget/dictquicklookup.lua index 8029a47d9..5da920c2d 100644 --- a/frontend/ui/widget/dictquicklookup.lua +++ b/frontend/ui/widget/dictquicklookup.lua @@ -613,8 +613,9 @@ function DictQuickLookup:onClose() if self.highlight then -- delay unhighlight of selection, so we can see where we stopped when -- back from our journey into dictionary or wikipedia + local clear_id = self.highlight:getClearId() UIManager:scheduleIn(0.5, function() - self.highlight:clear() + self.highlight:clear(clear_id) end) end return true @@ -626,8 +627,9 @@ function DictQuickLookup:onHoldClose(no_clear) local window = self.window_list[i] -- if one holds a highlight, let's clear it like in onClose() if window.highlight and not no_clear then - UIManager:scheduleIn(1, function() - window.highlight:clear() + local clear_id = window.highlight:getClearId() + UIManager:scheduleIn(0.5, function() + window.highlight:clear(clear_id) end) end UIManager:close(window)