diff options
author | Federico Tedin <federicotedin@gmail.com> | 2019-02-03 13:48:31 -0300 |
---|---|---|
committer | Tassilo Horn <tsdh@gnu.org> | 2019-02-04 16:47:00 +0100 |
commit | d5f629d193ffe88c464379f02dd2adaadc9dfdf0 (patch) | |
tree | 01e4cc7e6efa8a4fb99fb14d512ad88cc0388933 /lisp/doc-view.el | |
parent | d6f430cb88bc4c395c1ce9f405a938699491b517 (diff) | |
download | emacs-d5f629d193ffe88c464379f02dd2adaadc9dfdf0.tar.gz emacs-d5f629d193ffe88c464379f02dd2adaadc9dfdf0.tar.bz2 emacs-d5f629d193ffe88c464379f02dd2adaadc9dfdf0.zip |
Allow doc-view to open password-protected PDF files (bug#33684)
* lisp/doc-view.el (doc-view-ghostscript-options): Removed "-sDEVICE"
option.
(doc-view-ghostscript-device): New customizable variable, passed as
"-sDEVICE" option to GhostScript.
(doc-view-pdf-password-protected-ghostscript-p): New function.
(doc-view-pdf->png-converter-ghostscript): Can now open
password-protected PDF files.
(doc-view-pdfdraw-program-subcommand): New function.
(doc-view-pdf-password-protected-pdfdraw-p): New function.
(doc-view-pdf->png-converter-mupdf): Can now open password-protected
PDF files.
* etc/NEWS: Mention new doc-view-mode feature.
Diffstat (limited to 'lisp/doc-view.el')
-rw-r--r-- | lisp/doc-view.el | 79 |
1 files changed, 59 insertions, 20 deletions
diff --git a/lisp/doc-view.el b/lisp/doc-view.el index df8a9fc70fe..7ae7c6a96cd 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -183,11 +183,16 @@ (defcustom doc-view-ghostscript-options '("-dSAFER" ;; Avoid security problems when rendering files from untrusted ;; sources. - "-dNOPAUSE" "-sDEVICE=png16m" "-dTextAlphaBits=4" + "-dNOPAUSE" "-dTextAlphaBits=4" "-dBATCH" "-dGraphicsAlphaBits=4" "-dQUIET") "A list of options to give to ghostscript." :type '(repeat string)) +(defcustom doc-view-ghostscript-device "png16m" + "Output device to give to ghostscript." + :type 'string + :version "27.1") + (defcustom doc-view-resolution 100 "Dots per inch resolution used to render the documents. Higher values result in larger images." @@ -950,16 +955,31 @@ Should be invoked when the cached images aren't up-to-date." (list "-o" pdf dvi) callback))) +(defun doc-view-pdf-password-protected-ghostscript-p (pdf) + "Return non-nil if a PDF file is password-protected. +The test is performed using `doc-view-ghostscript-program'." + (with-temp-buffer + (apply #'call-process doc-view-ghostscript-program nil (current-buffer) + nil `(,@doc-view-ghostscript-options + "-sNODISPLAY" + ,pdf)) + (goto-char (point-min)) + (search-forward "This file requires a password for access." nil t))) + (defun doc-view-pdf->png-converter-ghostscript (pdf png page callback) - (doc-view-start-process - "pdf/ps->png" doc-view-ghostscript-program - `(,@doc-view-ghostscript-options - ,(format "-r%d" (round doc-view-resolution)) - ,@(if page `(,(format "-dFirstPage=%d" page))) - ,@(if page `(,(format "-dLastPage=%d" page))) - ,(concat "-sOutputFile=" png) - ,pdf) - callback)) + (let ((pdf-passwd (if (doc-view-pdf-password-protected-ghostscript-p pdf) + (read-passwd "Enter password for PDF file: ")))) + (doc-view-start-process + "pdf/ps->png" doc-view-ghostscript-program + `(,@doc-view-ghostscript-options + ,(concat "-sDEVICE=" doc-view-ghostscript-device) + ,(format "-r%d" (round doc-view-resolution)) + ,@(if page `(,(format "-dFirstPage=%d" page))) + ,@(if page `(,(format "-dLastPage=%d" page))) + ,@(if pdf-passwd `(,(format "-sPDFPassword=%s" pdf-passwd))) + ,(concat "-sOutputFile=" png) + ,pdf) + callback))) (defalias 'doc-view-ps->png-converter-ghostscript 'doc-view-pdf->png-converter-ghostscript) @@ -980,17 +1000,36 @@ If PAGE is nil, convert the whole document." ,tiff) callback)) +(defun doc-view-pdfdraw-program-subcommand () + "Return the mutool subcommand replacing mudraw. +Recent MuPDF distributions replaced 'mudraw' with 'mutool draw'." + (when (string-match "mutool[^/\\]*$" doc-view-pdfdraw-program) + '("draw"))) + +(defun doc-view-pdf-password-protected-pdfdraw-p (pdf) + "Return non-nil if a PDF file is password-protected. +The test is performed using `doc-view-pdfdraw-program'." + (with-temp-buffer + (apply #'call-process doc-view-pdfdraw-program nil (current-buffer) nil + `(,@(doc-view-pdfdraw-program-subcommand) + ,(concat "-o" null-device) + ;; In case PDF isn't password-protected, "draw" only one page. + ,pdf "1")) + (goto-char (point-min)) + (search-forward "error: cannot authenticate password" nil t))) + (defun doc-view-pdf->png-converter-mupdf (pdf png page callback) - (doc-view-start-process - "pdf->png" doc-view-pdfdraw-program - ;; FIXME: Ugly hack: recent mupdf distribution replaced "mudraw" with - ;; "mutool draw". - `(,@(if (string-match "mutool[^/\\]*$" doc-view-pdfdraw-program) '("draw")) - ,(concat "-o" png) - ,(format "-r%d" (round doc-view-resolution)) - ,pdf - ,@(if page `(,(format "%d" page)))) - callback)) + (let ((pdf-passwd (if (doc-view-pdf-password-protected-pdfdraw-p pdf) + (read-passwd "Enter password for PDF file: ")))) + (doc-view-start-process + "pdf->png" doc-view-pdfdraw-program + `(,@(doc-view-pdfdraw-program-subcommand) + ,(concat "-o" png) + ,(format "-r%d" (round doc-view-resolution)) + ,@(if pdf-passwd `("-p" ,pdf-passwd)) + ,pdf + ,@(if page `(,(format "%d" page)))) + callback))) (defun doc-view-odf->pdf-converter-unoconv (odf callback) "Convert ODF to PDF asynchronously and call CALLBACK when finished. |