unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: sbaugh@catern.com
To: Eli Zaretskii <eliz@gnu.org>
Cc: 65902@debbugs.gnu.org, Jim Porter <jporterbugs@gmail.com>,
	sbaugh@janestreet.com
Subject: bug#65902: 29.0.92; emacsclient-mail.desktop fails due to complicated escaping
Date: Thu, 14 Sep 2023 11:18:13 +0000 (UTC)	[thread overview]
Message-ID: <87edj1t34b.fsf@catern.com> (raw)
In-Reply-To: <87il8dt3sh.fsf@catern.com> (sbaugh@catern.com's message of "Thu,  14 Sep 2023 11:03:44 +0000 (UTC)")

[-- Attachment #1: Type: text/plain, Size: 115 bytes --]


Here's a revised patch which drops adding the argument to Emacs itself;
it only adds an argument to emacsclient.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-apply-argument-to-emacsclient-to-avoid-escaping.patch --]
[-- Type: text/x-patch, Size: 7960 bytes --]

From d4558462598eaa33466b3b2fb1dbcc26ea877ede Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh@catern.com>
Date: Thu, 14 Sep 2023 07:12:22 -0400
Subject: [PATCH] Add --apply argument to emacsclient to avoid escaping

Passing arguments to functions through emacsclient --eval requires
complicated escaping (as seen in emacsclient-mail.desktop before this
change).

The new --apply argument for emacsclient passes command line arguments
as uninterpreted strings to the specified function.  This simplifies
use cases where arbitrary input needs to be passed to Emacs.

org-protocol will be able to use this as well, which will allow it to
eventually drop its current advice on server-visit-files.

* etc/emacsclient-mail.desktop: Use --apply. (bug#65902)
* lib-src/emacsclient.c (longopts, decode_options, main): Add support
for --apply.
* lisp/server.el (server-apply-and-print): Add.
(server-process-filter): Add support for -apply and -applyargs
---
 etc/emacsclient-mail.desktop |  7 ++-----
 lib-src/emacsclient.c        | 36 ++++++++++++++++++++++++++++++++++--
 lisp/server.el               | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/etc/emacsclient-mail.desktop b/etc/emacsclient-mail.desktop
index 0a2420ddead..ea0690bacd9 100644
--- a/etc/emacsclient-mail.desktop
+++ b/etc/emacsclient-mail.desktop
@@ -1,10 +1,7 @@
 [Desktop Entry]
 Categories=Network;Email;
 Comment=GNU Emacs is an extensible, customizable text editor - and more
-# We want to pass the following commands to the shell wrapper:
-# u=$(echo "$1" | sed 's/[\"]/\\&/g'); exec emacsclient --alternate-editor= --display="$DISPLAY" --eval "(message-mailto \"$u\")"
-# Special chars '"', '$', and '\' must be escaped as '\\"', '\\$', and '\\\\'.
-Exec=sh -c "u=\\$(echo \\"\\$1\\" | sed 's/[\\\\\\"]/\\\\\\\\&/g'); exec emacsclient --alternate-editor= --display=\\"\\$DISPLAY\\" --eval \\"(message-mailto \\\\\\"\\$u\\\\\\")\\"" sh %u
+Exec=emacsclient --alternate-editor= --apply message-mailto -- %u
 Icon=emacs
 Name=Emacs (Mail, Client)
 MimeType=x-scheme-handler/mailto;
@@ -16,7 +13,7 @@ Actions=new-window;new-instance;
 
 [Desktop Action new-window]
 Name=New Window
-Exec=sh -c "u=\\$(echo \\"\\$1\\" | sed 's/[\\\\\\"]/\\\\\\\\&/g'); exec emacsclient --alternate-editor= --create-frame --eval \\"(message-mailto \\\\\\"\\$u\\\\\\")\\"" sh %u
+Exec=emacsclient --alternate-editor= --create-frame --apply message-mailto -- %u
 
 [Desktop Action new-instance]
 Name=New Instance
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 698bf9b50ae..159c22d1ae9 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -116,6 +116,9 @@ #define DEFAULT_TIMEOUT (30)
 /* True means args are expressions to be evaluated.  --eval.  */
 static bool eval;
 
+/* The function to call.  Other arguments are passed as strings.  --apply.  */
+static char *apply;
+
 /* True means open a new frame.  --create-frame etc.  */
 static bool create_frame;
 
@@ -169,6 +172,7 @@ #define DEFAULT_TIMEOUT (30)
   { "quiet",	no_argument,	   NULL, 'q' },
   { "suppress-output", no_argument, NULL, 'u' },
   { "eval",	no_argument,	   NULL, 'e' },
+  { "apply",	required_argument, NULL, 'y' },
   { "help",	no_argument,	   NULL, 'H' },
   { "version",	no_argument,	   NULL, 'V' },
   { "tty",	no_argument,       NULL, 't' },
@@ -552,6 +556,10 @@ decode_options (int argc, char **argv)
 	  eval = true;
 	  break;
 
+	case 'y':
+	  apply = optarg;
+	  break;
+
 	case 'q':
 	  quiet = true;
 	  break;
@@ -690,6 +698,7 @@ print_help_and_exit (void)
 -F ALIST, --frame-parameters=ALIST\n\
 			Set the parameters of a new frame\n\
 -e, --eval    		Evaluate the FILE arguments as ELisp expressions\n\
+-y, --apply FUNC	Call ELisp FUNC, passing all FILE arguments as strings\n\
 -n, --no-wait		Don't wait for the server to return\n\
 -w, --timeout=SECONDS	Seconds to wait before timing out\n\
 -q, --quiet		Don't display messages on success\n\
@@ -1953,7 +1962,7 @@ main (int argc, char **argv)
   /* Process options.  */
   decode_options (argc, argv);
 
-  if (! (optind < argc || eval || create_frame))
+  if (! (optind < argc || eval || apply || create_frame))
     {
       message (true, ("%s: file name or argument required\n"
 		      "Try '%s --help' for more information\n"),
@@ -1961,6 +1970,14 @@ main (int argc, char **argv)
       exit (EXIT_FAILURE);
     }
 
+  if (eval && apply)
+    {
+      message (true, ("%s: can't pass both --eval and --apply\n"
+		      "Try '%s --help' for more information\n"),
+	       progname, progname);
+      exit (EXIT_FAILURE);
+    }
+
 #ifdef SOCKETS_IN_FILE_SYSTEM
   if (tty)
     {
@@ -2080,6 +2097,13 @@ main (int argc, char **argv)
               send_to_emacs (emacs_socket, " ");
               continue;
             }
+	  else if (apply)
+	    {
+              send_to_emacs (emacs_socket, "-applyarg ");
+              quote_argument (emacs_socket, argv[i]);
+              send_to_emacs (emacs_socket, " ");
+              continue;
+	    }
 
 	  char *p = argv[i];
 	  if (*p == '+')
@@ -2136,10 +2160,18 @@ main (int argc, char **argv)
       send_to_emacs (emacs_socket, " ");
     }
 
+  if (apply)
+    {
+      send_to_emacs (emacs_socket, "-apply ");
+      quote_argument (emacs_socket, apply);
+      send_to_emacs (emacs_socket, " ");
+    }
+
+
   send_to_emacs (emacs_socket, "\n");
 
   /* Wait for an answer. */
-  if (!eval && !tty && !nowait && !quiet && 0 <= process_grouping ())
+  if (!eval && !apply && !tty && !nowait && !quiet && 0 <= process_grouping ())
     {
       printf ("Waiting for Emacs...");
       skiplf = false;
diff --git a/lisp/server.el b/lisp/server.el
index c3325e5a24c..5981e90625d 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -873,6 +873,17 @@ server-eval-and-print
                        (point-min) (point-max))))
             (server-reply-print (server-quote-arg text) proc)))))))
 
+(defun server-apply-and-print (func args proc)
+  "Call FUNC on ARGS and send the result back to client PROC."
+  (let ((v (with-local-quit (eval (apply (intern func) args) t))))
+    (when proc
+      (with-temp-buffer
+        (let ((standard-output (current-buffer)))
+          (pp v)
+          (let ((text (buffer-substring-no-properties
+                       (point-min) (point-max))))
+            (server-reply-print (server-quote-arg text) proc)))))))
+
 (defconst server-msg-size 1024
   "Maximum size of a message sent to a client.")
 
@@ -1196,6 +1207,7 @@ server-process-filter
 		tty-type   ; string.
 		files
 		filepos
+		applyargs
 		args-left)
 	    ;; Remove this line from STRING.
 	    (setq string (substring string (match-end 0)))
@@ -1323,6 +1335,28 @@ server-process-filter
                          commands)
                    (setq filepos nil)))
 
+                ;; -apply FUNC:  Call a function on arguments.
+                ("-apply"
+                 (if use-current-frame
+                     (setq use-current-frame 'always))
+                 (let ((func (pop args-left)))
+                   (if coding-system
+                       (setq func (decode-coding-string func coding-system)))
+                   (push (lambda () (server-apply-and-print func applyargs proc))
+                         commands)
+                   (setq applyargs nil)
+                   (setq filepos nil)))
+
+                ;; -applyarg ARG:  Add an argument for later -apply.
+                ("-applyarg"
+                 (if use-current-frame
+                     (setq use-current-frame 'always))
+                 (let ((arg (pop args-left)))
+                   (if coding-system
+                       (setq arg (decode-coding-string arg coding-system)))
+                   (push arg applyargs)
+                   (setq filepos nil)))
+
                 ;; -env NAME=VALUE:  An environment variable.
                 ("-env"
                  (let ((var (pop args-left)))
-- 
2.41.0


  reply	other threads:[~2023-09-14 11:18 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <fe2cc764-86c6-4840-80b7-8f3a3778b374@email.android.com>
2023-09-13 14:50 ` bug#65902: 29.0.92; emacsclient-mail.desktop fails due to complicated escaping Eli Zaretskii
2023-09-13 15:01   ` Andreas Schwab
2023-09-13 15:23   ` Spencer Baugh
2023-09-13 16:19     ` Jim Porter
2023-09-13 19:13     ` Eli Zaretskii
2023-09-13 19:33       ` Jim Porter
2023-09-13 20:00         ` Spencer Baugh
2023-09-13 20:16           ` Jim Porter
2023-09-14  5:10         ` Eli Zaretskii
2023-09-14 11:03           ` sbaugh
2023-09-14 11:18             ` sbaugh [this message]
2023-09-14 11:35             ` sbaugh
2023-09-14 13:36             ` Eli Zaretskii
2023-09-14 14:04               ` Spencer Baugh
2023-09-14 14:31                 ` Eli Zaretskii
2023-09-14 19:16               ` Jim Porter
2023-09-15  5:33                 ` Eli Zaretskii
2023-09-16 13:43           ` Björn Bidar via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-09-16 14:02             ` Eli Zaretskii
2023-09-16 15:54               ` Björn Bidar via Bug reports for GNU Emacs, the Swiss army knife of text editors
     [not found] <80d8aeb0-c9f1-410f-b83d-60f83ca5b3af@email.android.com>
2023-09-14 14:57 ` Eli Zaretskii
2023-09-14 15:10   ` Spencer Baugh
2023-09-15  6:29     ` Eli Zaretskii
2023-09-22  1:36       ` sbaugh
2023-09-22  6:36         ` Eli Zaretskii
2023-09-23 20:24           ` sbaugh
2023-09-24  5:18             ` Eli Zaretskii
2023-09-24 14:20               ` sbaugh
2023-10-21 15:20                 ` sbaugh
2023-10-22  5:27                   ` Eli Zaretskii
2023-10-22 14:15                     ` sbaugh
2023-10-22 16:09                       ` Andreas Schwab
2023-10-22 19:53                         ` sbaugh
2023-10-23 16:38                           ` Andreas Schwab
2023-10-23 16:52                           ` Jim Porter
2023-10-24 16:27                             ` sbaugh
2023-10-29 12:20                               ` Eli Zaretskii
2023-10-22  5:39                   ` Jim Porter
2023-09-22  7:05         ` Stefan Kangas
2023-09-22  7:14           ` Eli Zaretskii
2023-09-22  9:29             ` Andreas Schwab
2023-09-22 11:32               ` Eli Zaretskii
2023-09-22 12:37                 ` Andreas Schwab
2023-09-22 12:56                   ` Eli Zaretskii
2023-09-22 13:23                     ` Andreas Schwab
2023-09-22 14:51                       ` Eli Zaretskii
2023-09-22 14:52                         ` Andreas Schwab
2023-09-13  2:24 sbaugh
2023-09-13  2:30 ` sbaugh
2023-09-13  3:46   ` Jim Porter
2023-09-13  8:00     ` Robert Pluim
2023-09-13 13:06       ` Eli Zaretskii
2023-09-13 14:22         ` Robert Pluim
2023-09-13 12:41     ` Eli Zaretskii
2023-09-13 12:57     ` sbaugh
2023-09-13 12:41   ` Eli Zaretskii
2023-09-13 13:01     ` sbaugh
2023-09-13 13:26       ` Eli Zaretskii
2023-09-16 13:30         ` Björn Bidar via Bug reports for GNU Emacs, the Swiss army knife of text editors

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87edj1t34b.fsf@catern.com \
    --to=sbaugh@catern.com \
    --cc=65902@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=jporterbugs@gmail.com \
    --cc=sbaugh@janestreet.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).