emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lazy load of org-protocol


From: Max Nikulin
Subject: Re: Lazy load of org-protocol
Date: Sun, 6 Feb 2022 23:42:11 +0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0

On 06/02/2022 01:27, Jim Porter wrote:
On 2/5/2022 3:54 AM, Max Nikulin wrote:
etc/emacsclient-mail.desktop in the Emacs repo does this.) The command to use for a new Emacs instance is simple:

   emacs -f message-mailto %u

However, doing this for emacsclient is harder:

  emacsclient --alternate-editor= --create-frame --eval "(message-mailto \\"%u\\")"

There's no problem with "--alternate-editor=" and "--create-frame", but the fact that emacsclient requires evaling the function call that way is: if %u holds a string with quotation marks, this will break, and worse, could even result in arbitrary code being executed. (In practice, this is probably rare, since URLs are generally URL-encoded, and so don't have literal quotes in them.)

Thank you for suggesting another use case.

Quoting issues was the reason why I started to search a better way. There should be an easy and safe means to pass argument from command line to evaluated expressions similar to shell
    sh -c 'echo "$1"' example 'Hello, World!'

Some people could not even choose proper quotes for shell command:
https://www.reddit.com/r/emacs/comments/hhbcg7/emacsclient_eval_with_command_line_arguments/
https://stackoverflow.com/questions/8848819/emacs-eval-ediff-1-2-how-to-put-this-line-in-to-shell-script
First recipe and the accepted answer in second source solves the obvious problem but they miss escaping for elisp expression. Another answer on stackoverflow is more accurate, it suggests
    quoted1=${1//\\/\\\\}; quoted1=${quoted1//\"/\\\"}
I suppose, these links is a good illustration that substitution of arbitrary argument into lisp expression is harder than it should be to help users to avoid security issues.

As a result, I think a good first step might be to add support for "--funcall" to emacsclient, just like the regular emacs binary. (The "-f" shorthand won't work though, since emacsclient already uses that for "--server-file"). This would simplify the `message-mailto' case above and would also allow org-protocol to do something similar:

   emacsclient --funcall org-protocol-capture %u

No, --funcall is just a sugar for --eval '(func)' that does not contain arbitrary input, but func has no access to other arguments and it is the real problem.

I think, the solution is to add -arg command to emacs server protocol that pushes its argument to a list and extend -exec command that would make such list available as argv or as `command-line-args-left' for evaluated expression. Of course, emacsclient option parser should be modified as well to support --arg option
     emacsclient --eval '(func)' --arg 1 2 3
     emacsclient --eval '(func)' --arg -- 1 2 3
and maybe even for multiple eval+arg pairs
     emacsclient --eval '(f1)' --arg 'a1' --eval '(f2)' --arg 'a2' 'a3'

The proper place to discuss idea is emacs-devel list, but I am afraid that without a patch it will be just buried.

   emacsclient --eval "(org-protocol-capture \\"%u\\")"

Due to quoting issues a small wrapper may be safer (modulo -a, -c)

    emacsclient --eval "(require 'org-protocol)"
    emacsclient -- "$@"




reply via email to

[Prev in Thread] Current Thread [Next in Thread]