Subject: bug#42984: 27.1; package-list results in error while updating archive due to malformed path

From: Mirko Vukovic <[email-masked]>
Date: Thu, 26 Nov 2020 10:28:17 -0500

On Thu, Nov 26, 2020 at 9:09 AM Eli Zaretskii <[email-masked]> wrote:

> > From: Stefan Kangas <[email-masked]>
> > Date: Wed, 25 Nov 2020 23:36:36 -0500
> > Cc: [email-masked], [email-masked]
> >
> > Eli Zaretskii <[email-masked]> writes:
> >
> > >> Does anyone have an idea why a path like this would be used on
> Windows?
> > >>
> > >>
>  "/c/Users/977315/tmp/c:/Users/977315/.emacs.d/elpa/gnupg/pubring.kbx"
> > >
> > > Yes, it happens when MSYS2 ports of programs (gpg?) are mixed with
> > > native Windows ports.
> >
> > Should we do anything about that, or is it expected?
>
> My guess is it's not an Emacs problem.  But to be sure, I miss some
> details:
>
>   . is gpg being used an MSYS2 port of a native Windows
>     (a.k.a. "mingw") port?
>   . was the problematic file name emitted by gpg, or was it generated
>     by Emacs and passed to gpg?
>
> The last question could be answered by stepping in Edebug through
> package--check-signature-content and epg functions it calls, and
> looking at the file names we place on the gpg command line.
>
> If the OP could provide this information, we could easily see whether
> there's some problem in Emacs in this use case.
>

Tracing package--check-signature-content

   - I trace it in plain emacs, started with emacs -Q
   - I edebug the function and step through it
   - I have a single signature and its status is no-pub-key which triggers
   the No public key error
      - This results in the message in the error buffer with the malformed
      directory

Below is the code annotated with values of key variables. I did not see
anything obvious.

I evaluated context at several points. I following deeper into the epg-...
functions, stopped when I saw compiler macros. I would need guidance to
trace those.

Let me know if you required additional debug/testing, including issuing gpg
commands in the shell.

(defun package--check-signature-content (content string &optional sig-file)
  "Check signature CONTENT against STRING.
SIG-FILE is the name of the signature file, used when signaling
errors."
  ;; Evaluated in edebug and copied from *Messages*
  ;; content:  "\211 \263 \0 \n\0  ! \3043UGf\323\335\306B!\277\252
m\257\313\201\344,@  _\277}\316\0\n	  m\257\313\201\344,@..."
  ;; string: "(1\n (ace-window .\n	     [(0 9 0)\n	      ((avy\n		(0..."
  ;; sig-file: "archive-contents.sig"
  (let ((context (epg-make-context 'OpenPGP)))
  ;; #s(epg-context :protocol OpenPGP :program
"c:/msys64-a/usr/bin/gpg.exe" :home-directory nil :armor nil :textmode
nil :include-certs nil :cipher-algorithm nil :digest-algorithm nil
:compress-algorithm nil :passphrase-callback
(epg-passphrase-callback-function) :progress-callback nil
:edit-callback nil :signers nil :sender nil :sig-notations nil
:process nil :output-file nil :result nil :operation nil
:pinentry-mode nil :error-output "" :error-buffer nil)
    (when package-gnupghome-dir
      (setf (epg-context-home-directory context) package-gnupghome-dir))
      ;; #s(epg-context :protocol OpenPGP :program
"c:/msys64-a/usr/bin/gpg.exe" :home-directory
"c:/Users/977315/.emacs.d/elpa/gnupg" :armor nil :textmode nil
:include-certs nil :cipher-algorithm nil :digest-algorithm nil
:compress-algorithm nil :passphrase-callback
(epg-passphrase-callback-function) :progress-callback nil
:edit-callback nil :signers nil :sender nil :sig-notations nil
:process nil :output-file nil :result nil :operation nil
:pinentry-mode nil :error-output "" :error-buffer nil)
    (condition-case error
        (epg-verify-string context content string) ;; ""
      (error (package--display-verify-error context sig-file)
             (signal 'bad-signature error)))
    (let (good-signatures had-fatal-error)
      ;; The .sig file may contain multiple signatures.  Success if one
      ;; of the signatures is good.
      ;; context: #s(epg-context :protocol OpenPGP :program
"c:/msys64-a/usr/bin/gpg.exe" :home-directory
"c:/Users/977315/.emacs.d/elpa/gnupg" :armor nil :textmode nil
:include-certs nil :cipher-algorithm nil :digest-algorithm nil
:compress-algorithm nil :passphrase-callback
(epg-passphrase-callback-function) :progress-callback nil
:edit-callback nil :signers nil :sender nil :sig-notations nil
:process nil :output-file
"c:/Users/977315/AppData/Local/Temp/epg-output2eIiW..." :result
((error) (verify #s(epg-signature :status no-pubkey :key-id
"066DAFCB81E42C40" :validity nil :fingerprint nil :creation-time
1606385102 :expiration-time nil :pubkey-algorithm 1 :digest-algorithm
10 :class 0 :version nil :notations nil))) :operation verify
:pinentry-mode nil :error-output "gpg: keyblock resource
'/home/977315/.emacs.d/elpa..." :error-buffer #<killed buffer>)
      (dolist (sig (epg-context-result-for context 'verify))
      ;; sig: #s(epg-signature :status no-pubkey :key-id
"066DAFCB81E42C40" :validity nil :fingerprint nil :creation-time
1606385102 :expiration-time nil :pubkey-algorithm 1 :digest-algorithm
10 :class 0 :version nil :notations nil)
        (if (eq (epg-signature-status sig) 'good) ;;
epg-signature-status returns NO-PUBKEY
            (push sig good-signatures)
          ;; If `package-check-signature' is allow-unsigned, don't
          ;; signal error when we can't verify signature because of
          ;; missing public key.  Other errors are still treated as
          ;; fatal (bug#17625).
          (unless (and (eq (package-check-signature) 'allow-unsigned) ;; T
                       (eq (epg-signature-status sig) 'no-pubkey)) ;; T
            (setq had-fatal-error t)))) ;; NIL
      (when (or (null good-signatures) ;; T
                (and (eq (package-check-signature) 'all)
                     had-fatal-error))
       ;; context: #s(epg-context :protocol OpenPGP :program
"c:/msys64-a/usr/bin/gpg.exe" :home-directory
"c:/Users/977315/.emacs.d/elpa/gnupg" :armor nil :textmode nil
:include-certs nil :cipher-algorithm nil :digest-algorithm nil
:compress-algorithm nil :passphrase-callback
(epg-passphrase-callback-function) :progress-callback nil
:edit-callback nil :signers nil :sender nil :sig-notations nil
:process nil :output-file
"c:/Users/977315/AppData/Local/Temp/epg-output2eIiW..." :result
((error) (verify #s(epg-signature :status no-pubkey :key-id
"066DAFCB81E42C40" :validity nil :fingerprint nil :creation-time
1606385102 :expiration-time nil :pubkey-algorithm 1 :digest-algorithm
10 :class 0 :version nil :notations nil))) :operation verify
:pinentry-mode nil :error-output "gpg: keyblock resource
'/home/977315/.emacs.d/elpa..." :error-buffer #<killed buffer>)
        (package--display-verify-error context sig-file)
;; Failed to verify signature archive-contents.sig:
;; No public key for 066DAFCB81E42C40 created at
2020-11-26T05:05:02-0500 using RSA
;; Command output:
;; gpg: keyblock resource
'/home/977315/.emacs.d/elpa/gnupg/c:/Users/977315/.emacs.d/elpa/gnupg/pubring.kbx':
No such file or directory
;; gpg: Signature made Thu, Nov 26, 2020  5:05:02 AM EST
;; gpg:                using RSA key C433554766D3DDC64221BFAA066DAFCB81E42C40
;; gpg: Can't check signature: No public key
        (signal 'bad-signature (list sig-file)))
      good-signatures)))