aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFederico Tedin2019-02-03 13:48:31 -0300
committerTassilo Horn2019-02-04 16:47:00 +0100
commitd5f629d193ffe88c464379f02dd2adaadc9dfdf0 (patch)
tree01e4cc7e6efa8a4fb99fb14d512ad88cc0388933
parentd6f430cb88bc4c395c1ce9f405a938699491b517 (diff)
downloademacs-d5f629d193ffe88c464379f02dd2adaadc9dfdf0.tar.gz
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.
-rw-r--r--etc/NEWS1
-rw-r--r--lisp/doc-view.el79
2 files changed, 60 insertions, 20 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 2e3d92f2515..bbfc3285ee6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -334,6 +334,7 @@ asked to use :host 'local and :family 'ipv6.
334 334
335** doc-view-mode 335** doc-view-mode
336*** New commands doc-view-presentation and doc-view-fit-window-to-page 336*** New commands doc-view-presentation and doc-view-fit-window-to-page
337*** Added support for password-protected PDF files
337 338
338** map.el 339** map.el
339*** Now also understands plists. 340*** Now also understands plists.
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 @@
183(defcustom doc-view-ghostscript-options 183(defcustom doc-view-ghostscript-options
184 '("-dSAFER" ;; Avoid security problems when rendering files from untrusted 184 '("-dSAFER" ;; Avoid security problems when rendering files from untrusted
185 ;; sources. 185 ;; sources.
186 "-dNOPAUSE" "-sDEVICE=png16m" "-dTextAlphaBits=4" 186 "-dNOPAUSE" "-dTextAlphaBits=4"
187 "-dBATCH" "-dGraphicsAlphaBits=4" "-dQUIET") 187 "-dBATCH" "-dGraphicsAlphaBits=4" "-dQUIET")
188 "A list of options to give to ghostscript." 188 "A list of options to give to ghostscript."
189 :type '(repeat string)) 189 :type '(repeat string))
190 190
191(defcustom doc-view-ghostscript-device "png16m"
192 "Output device to give to ghostscript."
193 :type 'string
194 :version "27.1")
195
191(defcustom doc-view-resolution 100 196(defcustom doc-view-resolution 100
192 "Dots per inch resolution used to render the documents. 197 "Dots per inch resolution used to render the documents.
193Higher values result in larger images." 198Higher values result in larger images."
@@ -950,16 +955,31 @@ Should be invoked when the cached images aren't up-to-date."
950 (list "-o" pdf dvi) 955 (list "-o" pdf dvi)
951 callback))) 956 callback)))
952 957
958(defun doc-view-pdf-password-protected-ghostscript-p (pdf)
959 "Return non-nil if a PDF file is password-protected.
960The test is performed using `doc-view-ghostscript-program'."
961 (with-temp-buffer
962 (apply #'call-process doc-view-ghostscript-program nil (current-buffer)
963 nil `(,@doc-view-ghostscript-options
964 "-sNODISPLAY"
965 ,pdf))
966 (goto-char (point-min))
967 (search-forward "This file requires a password for access." nil t)))
968
953(defun doc-view-pdf->png-converter-ghostscript (pdf png page callback) 969(defun doc-view-pdf->png-converter-ghostscript (pdf png page callback)
954 (doc-view-start-process 970 (let ((pdf-passwd (if (doc-view-pdf-password-protected-ghostscript-p pdf)
955 "pdf/ps->png" doc-view-ghostscript-program 971 (read-passwd "Enter password for PDF file: "))))
956 `(,@doc-view-ghostscript-options 972 (doc-view-start-process
957 ,(format "-r%d" (round doc-view-resolution)) 973 "pdf/ps->png" doc-view-ghostscript-program
958 ,@(if page `(,(format "-dFirstPage=%d" page))) 974 `(,@doc-view-ghostscript-options
959 ,@(if page `(,(format "-dLastPage=%d" page))) 975 ,(concat "-sDEVICE=" doc-view-ghostscript-device)
960 ,(concat "-sOutputFile=" png) 976 ,(format "-r%d" (round doc-view-resolution))
961 ,pdf) 977 ,@(if page `(,(format "-dFirstPage=%d" page)))
962 callback)) 978 ,@(if page `(,(format "-dLastPage=%d" page)))
979 ,@(if pdf-passwd `(,(format "-sPDFPassword=%s" pdf-passwd)))
980 ,(concat "-sOutputFile=" png)
981 ,pdf)
982 callback)))
963 983
964(defalias 'doc-view-ps->png-converter-ghostscript 984(defalias 'doc-view-ps->png-converter-ghostscript
965 'doc-view-pdf->png-converter-ghostscript) 985 'doc-view-pdf->png-converter-ghostscript)
@@ -980,17 +1000,36 @@ If PAGE is nil, convert the whole document."
980 ,tiff) 1000 ,tiff)
981 callback)) 1001 callback))
982 1002
1003(defun doc-view-pdfdraw-program-subcommand ()
1004 "Return the mutool subcommand replacing mudraw.
1005Recent MuPDF distributions replaced 'mudraw' with 'mutool draw'."
1006 (when (string-match "mutool[^/\\]*$" doc-view-pdfdraw-program)
1007 '("draw")))
1008
1009(defun doc-view-pdf-password-protected-pdfdraw-p (pdf)
1010 "Return non-nil if a PDF file is password-protected.
1011The test is performed using `doc-view-pdfdraw-program'."
1012 (with-temp-buffer
1013 (apply #'call-process doc-view-pdfdraw-program nil (current-buffer) nil
1014 `(,@(doc-view-pdfdraw-program-subcommand)
1015 ,(concat "-o" null-device)
1016 ;; In case PDF isn't password-protected, "draw" only one page.
1017 ,pdf "1"))
1018 (goto-char (point-min))
1019 (search-forward "error: cannot authenticate password" nil t)))
1020
983(defun doc-view-pdf->png-converter-mupdf (pdf png page callback) 1021(defun doc-view-pdf->png-converter-mupdf (pdf png page callback)
984 (doc-view-start-process 1022 (let ((pdf-passwd (if (doc-view-pdf-password-protected-pdfdraw-p pdf)
985 "pdf->png" doc-view-pdfdraw-program 1023 (read-passwd "Enter password for PDF file: "))))
986 ;; FIXME: Ugly hack: recent mupdf distribution replaced "mudraw" with 1024 (doc-view-start-process
987 ;; "mutool draw". 1025 "pdf->png" doc-view-pdfdraw-program
988 `(,@(if (string-match "mutool[^/\\]*$" doc-view-pdfdraw-program) '("draw")) 1026 `(,@(doc-view-pdfdraw-program-subcommand)
989 ,(concat "-o" png) 1027 ,(concat "-o" png)
990 ,(format "-r%d" (round doc-view-resolution)) 1028 ,(format "-r%d" (round doc-view-resolution))
991 ,pdf 1029 ,@(if pdf-passwd `("-p" ,pdf-passwd))
992 ,@(if page `(,(format "%d" page)))) 1030 ,pdf
993 callback)) 1031 ,@(if page `(,(format "%d" page))))
1032 callback)))
994 1033
995(defun doc-view-odf->pdf-converter-unoconv (odf callback) 1034(defun doc-view-odf->pdf-converter-unoconv (odf callback)
996 "Convert ODF to PDF asynchronously and call CALLBACK when finished. 1035 "Convert ODF to PDF asynchronously and call CALLBACK when finished.