[Top][All Lists]

[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:
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]