credocument: deal with loadDocument() failures (#3570)

cre:loadDocument() may fail in recognizing the document format, and
koreader would previously keep calling other methods on it, which would
make crengine segfaults. We now check loadDocument success at the
various places it is called, and try to deal the best way we can when it fails.
This commit is contained in:
poire-z
2018-01-03 09:43:49 +01:00
committed by GitHub
parent 6f41cecab2
commit 7797c2369e
5 changed files with 139 additions and 78 deletions

View File

@@ -263,7 +263,9 @@ function ReaderUI:init()
else
-- make sure we render document first before calling any callback
self:registerPostInitCallback(function()
self.document:loadDocument()
if not self.document:loadDocument() then
self:dealWithLoadDocumentFailure()
end
-- used to read additional settings after the document has been
-- loaded (but not rendered yet)
@@ -561,4 +563,34 @@ function ReaderUI:onClose()
end
end
function ReaderUI:dealWithLoadDocumentFailure()
-- Sadly, we had to delay loadDocument() to about now, so we only
-- know now this document is not valid or recognized.
-- We can't do much more than crash properly here (still better than
-- going on and segfaulting when calling other methods on unitiliazed
-- _document)
-- We must still remove it from lastfile and history (as it has
-- already been added there) so that koreader don't crash again
-- at next launch...
local readhistory = require("readhistory")
readhistory:removeItemByPath(self.document.file)
if G_reader_settings:readSetting("lastfile") == self.document.file then
G_reader_settings:saveSetting("lastfile", #readhistory.hist > 0 and readhistory.hist[1].file or nil)
end
-- As we are in a coroutine, we can pause and show an InfoMessage before exiting
local _coroutine = coroutine.running()
if coroutine then
logger.warn("crengine failed recognizing or parsing this file: unsupported or invalid document")
UIManager:show(InfoMessage:new{
text = _("Failed recognizing or parsing this file: unsupported or invalid document.\nKOReader will exit now."),
dismiss_callback = function()
coroutine.resume(_coroutine, false)
end,
})
coroutine.yield() -- pause till InfoMessage is dismissed
end
-- We have to error and exit the coroutine anyway to avoid any segfault
error("crengine failed recognizing or parsing this file: unsupported or invalid document")
end
return ReaderUI