GNU bug report logs - #24576
25.1; desktop.el does not fully preserve registers with macros

Previous Next

Package: emacs;

Reported by: Dmitri Paduchikh <dpaduchikh <at> gmail.com>

Date: Sat, 1 Oct 2016 04:50:01 UTC

Severity: normal

Tags: fixed

Found in version 25.1

Fixed in version 27.1

Done: npostavs <at> gmail.com

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 24576 in the body.
You can then email your comments to 24576 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#24576; Package emacs. (Sat, 01 Oct 2016 04:50:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Dmitri Paduchikh <dpaduchikh <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sat, 01 Oct 2016 04:50:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Dmitri Paduchikh <dpaduchikh <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 25.1; desktop.el does not fully preserve registers with macros
Date: Sat, 01 Oct 2016 09:48:48 +0500
Hello,

Register ?a contains keyboard macro. After loading desktop file:

(registerv-insert-func (get-register ?a))
=> "Unprintable entity"

(registerv-print-func (get-register ?a))
=> "Unprintable entity"

This makes M-x list-registers and register insertion to fail. Using
interpreted version of kmacro-to-register fixes this problem.

(registerv-insert-func (get-register ?b))
=> (lambda (k) (insert (format-kbd-macro k)))

(registerv-print-func (get-register ?b))
=> (lambda (k) (princ (format "a keyboard macro:
   %s" (format-kbd-macro k))))

In GNU Emacs 25.1.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.20.9)
 of 2016-09-18 built on juergen

Regards,
Dmitri Paduchikh




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#24576; Package emacs. (Fri, 10 May 2019 22:42:01 GMT) Full text and rfc822 format available.

Message #8 received at 24576 <at> debbugs.gnu.org (full text, mbox):

From: Matthew Newton <matt <at> knosis.org>
To: 24576 <at> debbugs.gnu.org
Cc: dpaduchikh <at> gmail.com
Subject: bug#24576: 25.1;	desktop.el does not fully preserve registers with
 macros
Date: Fri, 10 May 2019 13:53:54 -0700
Apologies for reviving a stale bug but it appears to not be resolved yet.

Here is my experience with this, running my own build from a recent master:
GNU Emacs 27.0.50 (build 1, x86_64-apple-darwin18.5.0, NS appkit-1671.40 Version 10.14.4 (Build 18E226)) of 2019-04-22

;; .emacs
(require ‘desktop)
(desktop-save-mode 1)


;; before killing Emacs
(pp register-alist)
((107 . #s(registerv ""
                     #[257 "\300\301\302\303!\"!\207"
                           [princ format "a keyboard macro:\n   %s" format-kbd-macro]
                           6 "\n\n(fn K)"]
                     kmacro-execute-from-register
                     #[257 "\300!c\207"
                           [format-kbd-macro]
                           3 "\n\n(fn K)"])))

`M-x list-registers`
Register k contains a keyboard macro:
   C-e
Register p contains a buffer position:
    buffer t.el, position 21


;; after killing Emacs and running it again
(pp register-alist)
((107 . #s(registerv "" "Unprintable entity" kmacro-execute-from-register "Unprintable entity")))

`M-x list-registers`
Invalid function: "Unprintable entity”

;; Abbreviated stack trace
Debugger entered--Lisp error: (invalid-function "Unprintable entity")
  "Unprintable entity"("\5")
  #f(compiled-function (val verbose) #<bytecode 0x44180705>)(#s(registerv :data "\5" :print-func "Unprintable entity" :jump-func kmacro-execute-from-register :insert-func "Unprintable entity") nil)
  apply(#f(compiled-function (val verbose) #<bytecode 0x44180705>) #s(registerv :data "\5" :print-func "Unprintable entity" :jump-func kmacro-execute-from-register :insert-func "Unprintable entity") nil)
  register-val-describe(#s(registerv :data "\5" :print-func "Unprintable entity" :jump-func kmacro-execute-from-register :insert-func "Unprintable entity") nil)
  describe-register-1(107)
  list-registers()
  funcall-interactively(list-registers)
  call-interactively(list-registers record nil)
  command-execute(list-registers record)
  (closure ((externs) (initial-input) smex-ido-cache smex-initialized-p amx-cache amx-initialized info-lookup-mode t) (cmd) (setq cmd (intern cmd)) (cond ((and (boundp 'amx-initialized) amx-initialized) (amx-rank cmd)) ((and (boundp 'smex-initialized-p) smex-initialized-p) (smex-rank cmd))) (setq prefix-arg current-prefix-arg) (setq this-command cmd) (setq real-this-command cmd) (command-execute cmd 'record))("list-registers")
  #f(compiled-function (x) #<bytecode 0x1ff2b34c45a5>)("list-registers")



So there seem to be two bugs:

1. `desktop-save-mode` doesn’t serialize/deserialize keyboard macros properly (is it difficult to serialize a function object?)
2. Either :print-func and :insert-func should never be set to “Unprintable entity” or `register-val-describe` should handle the case where they are set to that value instead of a function. I’ve also seen “Unprintable entity” show up when a buffer position register points to a nonexistent buffer. Not sure how to reproduce that one.

I could probably dive deeper and see if I can fix this. But I would appreciate some thoughts from experienced Emacs devs about whether I understand the problem correctly. Any hints as to the best solution would also be great.

Cheers,
Matt



Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#24576; Package emacs. (Sat, 11 May 2019 12:16:02 GMT) Full text and rfc822 format available.

Message #11 received at 24576 <at> debbugs.gnu.org (full text, mbox):

From: Noam Postavsky <npostavs <at> gmail.com>
To: Matthew Newton <matt <at> knosis.org>
Cc: dpaduchikh <at> gmail.com, 24576 <at> debbugs.gnu.org
Subject: Re: bug#24576: 25.1;
 desktop.el does not fully preserve registers with macros
Date: Sat, 11 May 2019 08:15:50 -0400
Matthew Newton <matt <at> knosis.org> writes:

> Apologies for reviving a stale bug but it appears to not be resolved yet.

No apologies needed, on the contrary, thank you for looking at it.

> So there seem to be two bugs:
>
> 1. `desktop-save-mode` doesn’t serialize/deserialize keyboard macros
> properly (is it difficult to serialize a function object?)

> 2. Either :print-func and :insert-func should never be set to
> “Unprintable entity” or `register-val-describe` should handle the case
> where they are set to that value instead of a function.

The "unprintable entity" comes from desktop--v2s, looks like it doesn't
handle compiled function values, so that's why :print-func and
:insert-func get messed up like that.

> I’ve also seen “Unprintable entity” show up when a buffer position
> register points to a nonexistent buffer. Not sure how to reproduce
> that one.

I guess if you save a position in a buffer, then kill the buffer.






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#24576; Package emacs. (Wed, 22 May 2019 20:59:02 GMT) Full text and rfc822 format available.

Message #14 received at 24576 <at> debbugs.gnu.org (full text, mbox):

From: Matthew Newton <matt <at> knosis.org>
To: Noam Postavsky <npostavs <at> gmail.com>
Cc: dpaduchikh <at> gmail.com, 24576 <at> debbugs.gnu.org
Subject: Re: bug#24576: 25.1;	desktop.el does not fully preserve registers
 with macros
Date: Wed, 22 May 2019 13:58:06 -0700
It seems that the more pressing issue is desktop handling byte code.

> On May 11, 2019, at 5:15 AM, Noam Postavsky <npostavs <at> gmail.com> wrote:
> 
> Matthew Newton <matt <at> knosis.org> writes:
> 
>> Apologies for reviving a stale bug but it appears to not be resolved yet.
> 
> No apologies needed, on the contrary, thank you for looking at it.
> 
>> So there seem to be two bugs:
>> 
>> 1. `desktop-save-mode` doesn’t serialize/deserialize keyboard macros
>> properly (is it difficult to serialize a function object?)
Would it make sense to simply do something like this?

(defun desktop--v2s (value)
  ...
  (cond
   ((byte-code-function-p value)
    (let* ((pass1 (mapcar #'desktop--v2s value))
           (special (assq nil pass1)))
      (if special
          (cons nil `(make-byte-code
                      ,@(mapcar (lambda (el)
                                  (if (eq (car el) 'must)
                                      `',(cdr el) (cdr el)))
                                pass1)))
        (cons 'may `[,@(mapcar #'cdr pass1)]))))
   …))

I copied that from the `cond` clause for vector. It works in my limited testing.

Are there security concerns or other considerations?
> 
>> 2. Either :print-func and :insert-func should never be set to
>> “Unprintable entity” or `register-val-describe` should handle the case
>> where they are set to that value instead of a function.
> 
> The "unprintable entity" comes from desktop--v2s, looks like it doesn't
> handle compiled function values, so that's why :print-func and
> :insert-func get messed up like that.
> 
>> I’ve also seen “Unprintable entity” show up when a buffer position
>> register points to a nonexistent buffer. Not sure how to reproduce
>> that one.
> 
> I guess if you save a position in a buffer, then kill the buffer.
> 
Here is what I found: if the killed buffer visits a file, it gets converted into a file-query. If there is no `buffer-file-name` then it stays a file marker pointing to nowhere. Desktop handles both of those cases correctly. So while I have seen it happen I’m not sure of the case where a buffer position register becomes an “Unprintable entity”. Did you find reproduction steps?

Cheers,
Matt






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#24576; Package emacs. (Thu, 23 May 2019 03:44:01 GMT) Full text and rfc822 format available.

Message #17 received at 24576 <at> debbugs.gnu.org (full text, mbox):

From: Noam Postavsky <npostavs <at> gmail.com>
To: Matthew Newton <matt <at> knosis.org>
Cc: dpaduchikh <at> gmail.com, 24576 <at> debbugs.gnu.org
Subject: Re: bug#24576: 25.1;
 desktop.el does not fully preserve registers with macros
Date: Wed, 22 May 2019 23:43:12 -0400
Matthew Newton <matt <at> knosis.org> writes:

> (defun desktop--v2s (value)
>   ...
>   (cond
>    ((byte-code-function-p value)
>     (let* ((pass1 (mapcar #'desktop--v2s value))
>            (special (assq nil pass1)))
>       (if special
>           (cons nil `(make-byte-code
>                       ,@(mapcar (lambda (el)
>                                   (if (eq (car el) 'must)
>                                       `',(cdr el) (cdr el)))
>                                 pass1)))
>         (cons 'may `[,@(mapcar #'cdr pass1)]))))

I don't think `[...] will ever return a byte code function, so the
non-special case doesn't seem quite right.

> Are there security concerns or other considerations?

Well, as (info "(elisp) Byte-Code Objects") mentions, passing the wrong
args to make-byte-code can produce a function which will crash Emacs
when called, so it's somewhat high risk.

>> The "unprintable entity" comes from desktop--v2s, looks like it doesn't
>> handle compiled function values, so that's why :print-func and
>> :insert-func get messed up like that.

I note that the functions in question come from this code in kmacro.el:

(defun kmacro-to-register (r)
  ... (registerv-make
		   last-kbd-macro
		   :jump-func 'kmacro-execute-from-register
		   :print-func (lambda (k)
				 (princ (format "a keyboard macro:\n   %s"
						(format-kbd-macro k))))
		   :insert-func (lambda (k)
				  (insert (format-kbd-macro k))))

While in register.el we have:

(cl-defun registerv-make (data &key print-func jump-func insert-func)
  ...
  (declare (obsolete "Use your own type with methods on register-val-(insert|describe|jump-to)" "27.1"))

So perhaps this is a good opportunity to change the kmacro register
stuff to use the non-obsolete way.
 
>>> I’ve also seen “Unprintable entity” show up when a buffer position
>>> register points to a nonexistent buffer. Not sure how to reproduce
>>> that one.
>> 
>> I guess if you save a position in a buffer, then kill the buffer.
>> 
> Here is what I found: if the killed buffer visits a file, it gets
> converted into a file-query. If there is no `buffer-file-name` then it
> stays a file marker pointing to nowhere. Desktop handles both of those
> cases correctly. So while I have seen it happen I’m not sure of the
> case where a buffer position register becomes an “Unprintable
> entity”. Did you find reproduction steps?

Ah, no, I was just guessing based on your initial description, no idea
how to reproduce it if desktop.el is already handling these cases.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#24576; Package emacs. (Wed, 29 May 2019 17:42:02 GMT) Full text and rfc822 format available.

Message #20 received at 24576 <at> debbugs.gnu.org (full text, mbox):

From: Dmitri Paduchikh <dpaduchikh <at> gmail.com>
To: Noam Postavsky <npostavs <at> gmail.com>
Cc: Matthew Newton <matt <at> knosis.org>, 24576 <at> debbugs.gnu.org
Subject: Re: bug#24576: 25.1;
 desktop.el does not fully preserve registers with macros
Date: Wed, 29 May 2019 22:41:58 +0500
Noam Postavsky <npostavs <at> gmail.com> wrote:

>>> The "unprintable entity" comes from desktop--v2s, looks like it doesn't
>>> handle compiled function values, so that's why :print-func and
>>> :insert-func get messed up like that.

NP> I note that the functions in question come from this code in kmacro.el:

NP> (defun kmacro-to-register (r)
NP>   ... (registerv-make
NP>                    last-kbd-macro
NP>                    :jump-func 'kmacro-execute-from-register
NP>                    :print-func (lambda (k)
NP>                                  (princ (format "a keyboard macro:\n   %s"
NP>                                                 (format-kbd-macro k))))
NP>                    :insert-func (lambda (k)
NP>                                   (insert (format-kbd-macro k))))

This must be easy to fix. Just defun these anonymous functions and use their
names in place of lambdas. Or any newer approach, of course.

All the best.
Dmitri Paduchikh




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#24576; Package emacs. (Wed, 12 Jun 2019 17:45:01 GMT) Full text and rfc822 format available.

Message #23 received at 24576 <at> debbugs.gnu.org (full text, mbox):

From: npostavs <at> gmail.com
To: Noam Postavsky <npostavs <at> gmail.com>
Cc: Matthew Newton <matt <at> knosis.org>, dpaduchikh <at> gmail.com,
 24576 <at> debbugs.gnu.org
Subject: Re: bug#24576: 25.1;
 desktop.el does not fully preserve registers with macros
Date: Wed, 12 Jun 2019 13:43:54 -0400
tags 24576 fixed
close 24576 27.1
quit

> So perhaps this is a good opportunity to change the kmacro register
> stuff to use the non-obsolete way.

Lars did this, so I think the bug should be fixed now.

[1: 26f2b1f]: 2019-06-12 18:21:35 +0200
  Rewrite the kmacro register function to avoid using obsolete functions
  https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=26f2b1faaa1dc8847f2013268c20f51c144ae711




Added tag(s) fixed. Request was from npostavs <at> gmail.com to control <at> debbugs.gnu.org. (Wed, 12 Jun 2019 17:45:02 GMT) Full text and rfc822 format available.

bug marked as fixed in version 27.1, send any further explanations to 24576 <at> debbugs.gnu.org and Dmitri Paduchikh <dpaduchikh <at> gmail.com> Request was from npostavs <at> gmail.com to control <at> debbugs.gnu.org. (Wed, 12 Jun 2019 17:45:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Thu, 11 Jul 2019 11:24:08 GMT) Full text and rfc822 format available.

This bug report was last modified 6 years and 59 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.