diff options
| author | Federico Tedin | 2019-02-03 13:48:31 -0300 |
|---|---|---|
| committer | Tassilo Horn | 2019-02-04 16:47:00 +0100 |
| commit | d5f629d193ffe88c464379f02dd2adaadc9dfdf0 (patch) | |
| tree | 01e4cc7e6efa8a4fb99fb14d512ad88cc0388933 | |
| parent | d6f430cb88bc4c395c1ce9f405a938699491b517 (diff) | |
| download | emacs-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/NEWS | 1 | ||||
| -rw-r--r-- | lisp/doc-view.el | 79 |
2 files changed, 60 insertions, 20 deletions
| @@ -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. |
| 193 | Higher values result in larger images." | 198 | Higher 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. | ||
| 960 | The 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. | ||
| 1005 | Recent 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. | ||
| 1011 | The 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 | 1029 | ,@(if pdf-passwd `("-p" ,pdf-passwd)) | |
| 992 | ,@(if page `(,(format "%d" page)))) | 1030 | |
| 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. |