aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorPaul Eggert2026-04-12 22:56:16 -0700
committerPaul Eggert2026-04-12 23:21:02 -0700
commit7d07690e5dade398da8a26805744f8bf1daafe8c (patch)
treeef07c4b531d0654ae8bef142ba317fe0193f4be2 /lib-src
parent46c08d85743e30cd024264703e4e1b6f8927fb58 (diff)
downloademacs-7d07690e5dade398da8a26805744f8bf1daafe8c.tar.gz
emacs-7d07690e5dade398da8a26805744f8bf1daafe8c.zip
emacsclient receiving long-line fixes
Do not mishandle long lines, or lines containing NUL, when receiving data. * lib-src/emacsclient.c (check_socket_timeout, main): Use ssize_t for return values from recv, since in theory the value could exceed INT_MAX now. (main): Do not use a fixed-size buffer for receiving data; instead, grow the buffer as needed (admittedly unlikely). When a partial line is received via recv, do not discard its data; instead, keep reading, possibly with a grown buffer. Do not ignore received data after a null byte is received. Add a comment about when received data is ignored due to a goto.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/emacsclient.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 3ee4e3f92d5..134c2217650 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -1975,7 +1975,7 @@ set_socket_timeout (HSOCKET socket, int seconds)
1975} 1975}
1976 1976
1977static bool 1977static bool
1978check_socket_timeout (int rl) 1978check_socket_timeout (ssize_t rl)
1979{ 1979{
1980#ifndef WINDOWSNT 1980#ifndef WINDOWSNT
1981 return (rl == -1) 1981 return (rl == -1)
@@ -1994,9 +1994,11 @@ main (int argc, char **argv)
1994 main_argv = argv; 1994 main_argv = argv;
1995 progname = argv[0] ? argv[0] : "emacsclient"; 1995 progname = argv[0] ? argv[0] : "emacsclient";
1996 1996
1997 int rl = 0; 1997 ssize_t rl = 0;
1998 bool skiplf = true; 1998 bool skiplf = true;
1999 char string[BUFSIZ + 1]; 1999 char *recv_buf = NULL;
2000 ptrdiff_t recv_bufsize = 0;
2001
2000 int exit_status = EXIT_SUCCESS; 2002 int exit_status = EXIT_SUCCESS;
2001 2003
2002#ifdef HAVE_NTGUI 2004#ifdef HAVE_NTGUI
@@ -2208,6 +2210,8 @@ main (int argc, char **argv)
2208 2210
2209 set_socket_timeout (emacs_socket, timeout > 0 ? timeout : DEFAULT_TIMEOUT); 2211 set_socket_timeout (emacs_socket, timeout > 0 ? timeout : DEFAULT_TIMEOUT);
2210 bool saw_response = false; 2212 bool saw_response = false;
2213 ptrdiff_t nrecv = 0;
2214
2211 /* Now, wait for an answer and print any messages. */ 2215 /* Now, wait for an answer and print any messages. */
2212 while (exit_status == EXIT_SUCCESS) 2216 while (exit_status == EXIT_SUCCESS)
2213 { 2217 {
@@ -2216,7 +2220,14 @@ main (int argc, char **argv)
2216 do 2220 do
2217 { 2221 {
2218 act_on_signals (emacs_socket); 2222 act_on_signals (emacs_socket);
2219 rl = recv (emacs_socket, string, BUFSIZ, 0); 2223 if (nrecv == recv_bufsize)
2224 {
2225 enum { DEFAULT_RECV_BUFSIZE = 4096 };
2226 recv_bufsize = (recv_bufsize + (recv_bufsize >> 1)
2227 + DEFAULT_RECV_BUFSIZE);
2228 recv_buf = xrealloc (recv_buf, recv_bufsize);
2229 }
2230 rl = recv (emacs_socket, recv_buf + nrecv, recv_bufsize - nrecv, 0);
2220 retry = check_socket_timeout (rl); 2231 retry = check_socket_timeout (rl);
2221 if (retry && !saw_response) 2232 if (retry && !saw_response)
2222 { 2233 {
@@ -2239,16 +2250,17 @@ main (int argc, char **argv)
2239 if (rl <= 0) 2250 if (rl <= 0)
2240 break; 2251 break;
2241 2252
2253 nrecv += rl;
2242 saw_response = true; 2254 saw_response = true;
2243 string[rl] = '\0';
2244 2255
2245 /* Loop over all NL-terminated messages. */ 2256 /* Loop over all NL-terminated messages. */
2246 char *p = string; 2257 char *p = recv_buf;
2247 for (char *end_p = p; end_p && *end_p != '\0'; p = end_p) 2258 for (char *end_p = p; end_p < recv_buf + nrecv; p = end_p)
2248 { 2259 {
2249 end_p = strchr (p, '\n'); 2260 end_p = memchr (p, '\n', recv_buf + nrecv - p);
2250 if (end_p != NULL) 2261 if (!end_p)
2251 *end_p++ = '\0'; 2262 break;
2263 *end_p++ = '\0';
2252 2264
2253 if (strprefix ("-emacs-pid ", p)) 2265 if (strprefix ("-emacs-pid ", p))
2254 { 2266 {
@@ -2271,6 +2283,7 @@ main (int argc, char **argv)
2271 tty = true; 2283 tty = true;
2272 } 2284 }
2273 2285
2286 /* This discards any remaining data in recv_buf. */
2274 goto retry; 2287 goto retry;
2275 } 2288 }
2276 else if (strprefix ("-print ", p)) 2289 else if (strprefix ("-print ", p))
@@ -2324,6 +2337,9 @@ main (int argc, char **argv)
2324 skiplf = true; 2337 skiplf = true;
2325 } 2338 }
2326 } 2339 }
2340
2341 nrecv -= p - recv_buf;
2342 memmove (recv_buf, p, nrecv);
2327 } 2343 }
2328 2344
2329 if (!skiplf && 0 <= process_grouping ()) 2345 if (!skiplf && 0 <= process_grouping ())