From 7e3e38be62dc88a7f9a64d5d4facfa18382d91c0 Mon Sep 17 00:00:00 2001 From: HW Date: Tue, 20 Mar 2012 00:10:19 +0100 Subject: [PATCH] Password input, handling for broken documents --- djvureader.lua | 8 ++++++-- pdfreader.lua | 29 ++++++++++++++++++++++++++--- reader.lua | 24 ++++++++++++++---------- unireader.lua | 9 ++++++++- 4 files changed, 54 insertions(+), 16 deletions(-) diff --git a/djvureader.lua b/djvureader.lua index 1b4b37697..0582073b9 100644 --- a/djvureader.lua +++ b/djvureader.lua @@ -5,6 +5,10 @@ DJVUReader = UniReader:new{} -- open a DJVU file and its settings store -- DJVU does not support password yet function DJVUReader:open(filename) - self.doc = djvu.openDocument(filename) - return self:loadSettings(filename) + local ok + ok, self.doc = pcall(djvu.openDocument, filename) + if not ok then + return ok, self.doc -- this will be the error message instead + end + return ok end diff --git a/pdfreader.lua b/pdfreader.lua index 2af16f1cb..ec4e1a105 100644 --- a/pdfreader.lua +++ b/pdfreader.lua @@ -1,9 +1,32 @@ require "unireader" +require "inputbox" PDFReader = UniReader:new{} -- open a PDF file and its settings store -function PDFReader:open(filename, password) - self.doc = pdf.openDocument(filename, password or "") - return self:loadSettings(filename) +function PDFReader:open(filename) + -- muPDF manages its own cache, set second parameter + -- to the maximum size you want it to grow + local ok + ok, self.doc = pcall(pdf.openDocument, filename, 64*1024*1024) + if not ok then + return false, self.doc -- will contain error message + end + if self.doc:needsPassword() then + local password = InputBox:input(height-100, 100, "Pass:") + if not password or not self.doc:authenticatePassword(password) then + self.doc:close() + self.doc = nil + return false, "wrong or missing password" + end + -- password wrong or not entered + end + local ok, err = pcall(self.doc.getPages, self.doc) + if not ok then + -- for PDFs, they might trigger errors later when accessing page tree + self.doc:close() + self.doc = nil + return false, "damaged page tree" + end + return true end diff --git a/reader.lua b/reader.lua index 83cc0bb1d..7afefa90f 100755 --- a/reader.lua +++ b/reader.lua @@ -35,21 +35,25 @@ longopts = { function openFile(filename) local file_type = string.lower(string.match(filename, ".+%.([^.]+)")) + local reader = nil if file_type == "djvu" then - if DJVUReader:open(filename) then - page_num = DJVUReader.settings:readsetting("last_page") or 1 - DJVUReader:goto(tonumber(page_num)) - reader_settings:savesetting("lastfile", filename) - return DJVUReader:inputloop() - end + reader = DJVUReader elseif file_type == "pdf" or file_type == "xps" or file_type == "cbz" then - if PDFReader:open(filename,"") then -- TODO: query for password - page_num = PDFReader.settings:readsetting("last_page") or 1 - PDFReader:goto(tonumber(page_num)) + reader = PDFReader + end + if reader then + local ok, err = reader:open(filename) + if ok then + reader:loadSettings(filename) + page_num = reader.settings:readsetting("last_page") or 1 + reader:goto(tonumber(page_num)) reader_settings:savesetting("lastfile", filename) - return PDFReader:inputloop() + return reader:inputloop() + else + -- TODO: error handling end end + return true -- on failed attempts, we signal to keep running end function showusage() diff --git a/unireader.lua b/unireader.lua index 27251a486..b738197a2 100644 --- a/unireader.lua +++ b/unireader.lua @@ -175,7 +175,11 @@ function UniReader:draworcache(no, preCache) -- #4 goal: we render next page, too. (TODO) -- ideally, this should be factored out and only be called when needed (TODO) - local page = self.doc:openPage(no) + local ok, page = pcall(self.doc.openPage, self.doc, no) + if not ok then + -- TODO: error handling + return nil + end local dc = self:setzoom(page) -- offset_x_in_page & offset_y_in_page is the offset within zoomed page @@ -433,6 +437,9 @@ end -- render and blit a page function UniReader:show(no) local pagehash, offset_x, offset_y = self:draworcache(no) + if not pagehash then + return + end self.pagehash = pagehash local bb = self.cache[pagehash].bb local dest_x = 0