aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorPhilipp Stephani2020-12-30 22:33:22 +0100
committerPhilipp Stephani2020-12-30 23:04:34 +0100
commit0ea7bb3578998ebdf7c4903e7f38a8abf2e41b68 (patch)
tree1378d50b1c9a6eb5d2b863710fa8c0d01ab3281e /src/process.c
parent3a6137a498fe065cadbbf9a1f0575623155a9e55 (diff)
downloademacs-0ea7bb3578998ebdf7c4903e7f38a8abf2e41b68.tar.gz
emacs-0ea7bb3578998ebdf7c4903e7f38a8abf2e41b68.zip
Consistently check for FD_SETSIZE overflow.
Previously this was only checked in a few places. Now assert that file descriptors are within the expected range whenever we'd otherwise introduce undefined behavior. * src/process.c (add_read_fd, add_process_read_fd, delete_read_fd) (recompute_max_desc, delete_write_fd, compute_input_wait_mask) (compute_non_process_wait_mask, compute_non_keyboard_wait_mask) (compute_write_mask, clear_waiting_thread_info) (update_processes_for_thread_death, Fset_process_thread) (create_process, create_pty, Fmake_pipe_process) (Fprocess_datagram_address, Fset_process_datagram_address) (Fmake_serial_process, finish_after_tls_connection) (connect_network_socket, deactivate_process) (server_accept_connection, wait_reading_process_output) (read_process_output, read_and_dispose_of_process_output) (send_process, Fcontinue_process, Fprocess_send_eof) (Fprocess_filter_multibyte_p, keyboard_bit_set) (add_timer_wait_descriptor, setup_process_coding_systems): Add assertions to document and check that file descriptors are within the expected range when used as file descriptor set elements or array subscripts.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/process.c b/src/process.c
index 28ab15c9038..7c56366d8e1 100644
--- a/src/process.c
+++ b/src/process.c
@@ -465,6 +465,7 @@ add_read_fd (int fd, fd_callback func, void *data)
465{ 465{
466 add_keyboard_wait_descriptor (fd); 466 add_keyboard_wait_descriptor (fd);
467 467
468 eassert (0 <= fd && fd < FD_SETSIZE);
468 fd_callback_info[fd].func = func; 469 fd_callback_info[fd].func = func;
469 fd_callback_info[fd].data = data; 470 fd_callback_info[fd].data = data;
470} 471}
@@ -485,6 +486,7 @@ static void
485add_process_read_fd (int fd) 486add_process_read_fd (int fd)
486{ 487{
487 add_non_keyboard_read_fd (fd); 488 add_non_keyboard_read_fd (fd);
489 eassert (0 <= fd && fd < FD_SETSIZE);
488 fd_callback_info[fd].flags |= PROCESS_FD; 490 fd_callback_info[fd].flags |= PROCESS_FD;
489} 491}
490 492
@@ -495,6 +497,7 @@ delete_read_fd (int fd)
495{ 497{
496 delete_keyboard_wait_descriptor (fd); 498 delete_keyboard_wait_descriptor (fd);
497 499
500 eassert (0 <= fd && fd < FD_SETSIZE);
498 if (fd_callback_info[fd].flags == 0) 501 if (fd_callback_info[fd].flags == 0)
499 { 502 {
500 fd_callback_info[fd].func = 0; 503 fd_callback_info[fd].func = 0;
@@ -534,6 +537,7 @@ recompute_max_desc (void)
534{ 537{
535 int fd; 538 int fd;
536 539
540 eassert (max_desc < FD_SETSIZE);
537 for (fd = max_desc; fd >= 0; --fd) 541 for (fd = max_desc; fd >= 0; --fd)
538 { 542 {
539 if (fd_callback_info[fd].flags != 0) 543 if (fd_callback_info[fd].flags != 0)
@@ -542,6 +546,7 @@ recompute_max_desc (void)
542 break; 546 break;
543 } 547 }
544 } 548 }
549 eassert (max_desc < FD_SETSIZE);
545} 550}
546 551
547/* Stop monitoring file descriptor FD for when write is possible. */ 552/* Stop monitoring file descriptor FD for when write is possible. */
@@ -549,6 +554,7 @@ recompute_max_desc (void)
549void 554void
550delete_write_fd (int fd) 555delete_write_fd (int fd)
551{ 556{
557 eassert (0 <= fd && fd < FD_SETSIZE);
552 if ((fd_callback_info[fd].flags & NON_BLOCKING_CONNECT_FD) != 0) 558 if ((fd_callback_info[fd].flags & NON_BLOCKING_CONNECT_FD) != 0)
553 { 559 {
554 if (--num_pending_connects < 0) 560 if (--num_pending_connects < 0)
@@ -571,6 +577,7 @@ compute_input_wait_mask (fd_set *mask)
571 int fd; 577 int fd;
572 578
573 FD_ZERO (mask); 579 FD_ZERO (mask);
580 eassert (max_desc < FD_SETSIZE);
574 for (fd = 0; fd <= max_desc; ++fd) 581 for (fd = 0; fd <= max_desc; ++fd)
575 { 582 {
576 if (fd_callback_info[fd].thread != NULL 583 if (fd_callback_info[fd].thread != NULL
@@ -593,6 +600,7 @@ compute_non_process_wait_mask (fd_set *mask)
593 int fd; 600 int fd;
594 601
595 FD_ZERO (mask); 602 FD_ZERO (mask);
603 eassert (max_desc < FD_SETSIZE);
596 for (fd = 0; fd <= max_desc; ++fd) 604 for (fd = 0; fd <= max_desc; ++fd)
597 { 605 {
598 if (fd_callback_info[fd].thread != NULL 606 if (fd_callback_info[fd].thread != NULL
@@ -616,6 +624,7 @@ compute_non_keyboard_wait_mask (fd_set *mask)
616 int fd; 624 int fd;
617 625
618 FD_ZERO (mask); 626 FD_ZERO (mask);
627 eassert (max_desc < FD_SETSIZE);
619 for (fd = 0; fd <= max_desc; ++fd) 628 for (fd = 0; fd <= max_desc; ++fd)
620 { 629 {
621 if (fd_callback_info[fd].thread != NULL 630 if (fd_callback_info[fd].thread != NULL
@@ -639,6 +648,7 @@ compute_write_mask (fd_set *mask)
639 int fd; 648 int fd;
640 649
641 FD_ZERO (mask); 650 FD_ZERO (mask);
651 eassert (max_desc < FD_SETSIZE);
642 for (fd = 0; fd <= max_desc; ++fd) 652 for (fd = 0; fd <= max_desc; ++fd)
643 { 653 {
644 if (fd_callback_info[fd].thread != NULL 654 if (fd_callback_info[fd].thread != NULL
@@ -660,6 +670,7 @@ clear_waiting_thread_info (void)
660{ 670{
661 int fd; 671 int fd;
662 672
673 eassert (max_desc < FD_SETSIZE);
663 for (fd = 0; fd <= max_desc; ++fd) 674 for (fd = 0; fd <= max_desc; ++fd)
664 { 675 {
665 if (fd_callback_info[fd].waiting_thread == current_thread) 676 if (fd_callback_info[fd].waiting_thread == current_thread)
@@ -936,8 +947,10 @@ update_processes_for_thread_death (Lisp_Object dying_thread)
936 struct Lisp_Process *proc = XPROCESS (process); 947 struct Lisp_Process *proc = XPROCESS (process);
937 948
938 pset_thread (proc, Qnil); 949 pset_thread (proc, Qnil);
950 eassert (proc->infd < FD_SETSIZE);
939 if (proc->infd >= 0) 951 if (proc->infd >= 0)
940 fd_callback_info[proc->infd].thread = NULL; 952 fd_callback_info[proc->infd].thread = NULL;
953 eassert (proc->outfd < FD_SETSIZE);
941 if (proc->outfd >= 0) 954 if (proc->outfd >= 0)
942 fd_callback_info[proc->outfd].thread = NULL; 955 fd_callback_info[proc->outfd].thread = NULL;
943 } 956 }
@@ -1378,8 +1391,10 @@ If THREAD is nil, the process is unlocked. */)
1378 1391
1379 proc = XPROCESS (process); 1392 proc = XPROCESS (process);
1380 pset_thread (proc, thread); 1393 pset_thread (proc, thread);
1394 eassert (proc->infd < FD_SETSIZE);
1381 if (proc->infd >= 0) 1395 if (proc->infd >= 0)
1382 fd_callback_info[proc->infd].thread = tstate; 1396 fd_callback_info[proc->infd].thread = tstate;
1397 eassert (proc->outfd < FD_SETSIZE);
1383 if (proc->outfd >= 0) 1398 if (proc->outfd >= 0)
1384 fd_callback_info[proc->outfd].thread = tstate; 1399 fd_callback_info[proc->outfd].thread = tstate;
1385 1400
@@ -2108,6 +2123,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2108 fcntl (outchannel, F_SETFL, O_NONBLOCK); 2123 fcntl (outchannel, F_SETFL, O_NONBLOCK);
2109 2124
2110 /* Record this as an active process, with its channels. */ 2125 /* Record this as an active process, with its channels. */
2126 eassert (0 <= inchannel && inchannel < FD_SETSIZE);
2111 chan_process[inchannel] = process; 2127 chan_process[inchannel] = process;
2112 p->infd = inchannel; 2128 p->infd = inchannel;
2113 p->outfd = outchannel; 2129 p->outfd = outchannel;
@@ -2215,6 +2231,7 @@ create_pty (Lisp_Object process)
2215 2231
2216 /* Record this as an active process, with its channels. 2232 /* Record this as an active process, with its channels.
2217 As a result, child_setup will close Emacs's side of the pipes. */ 2233 As a result, child_setup will close Emacs's side of the pipes. */
2234 eassert (0 <= pty_fd && pty_fd < FD_SETSIZE);
2218 chan_process[pty_fd] = process; 2235 chan_process[pty_fd] = process;
2219 p->infd = pty_fd; 2236 p->infd = pty_fd;
2220 p->outfd = pty_fd; 2237 p->outfd = pty_fd;
@@ -2308,6 +2325,7 @@ usage: (make-pipe-process &rest ARGS) */)
2308#endif 2325#endif
2309 2326
2310 /* Record this as an active process, with its channels. */ 2327 /* Record this as an active process, with its channels. */
2328 eassert (0 <= inchannel && inchannel < FD_SETSIZE);
2311 chan_process[inchannel] = proc; 2329 chan_process[inchannel] = proc;
2312 p->infd = inchannel; 2330 p->infd = inchannel;
2313 p->outfd = outchannel; 2331 p->outfd = outchannel;
@@ -2637,6 +2655,7 @@ set up yet, this function will block until socket setup has completed. */)
2637 return Qnil; 2655 return Qnil;
2638 2656
2639 channel = XPROCESS (process)->infd; 2657 channel = XPROCESS (process)->infd;
2658 eassert (0 <= channel && channel < FD_SETSIZE);
2640 return conv_sockaddr_to_lisp (datagram_address[channel].sa, 2659 return conv_sockaddr_to_lisp (datagram_address[channel].sa,
2641 datagram_address[channel].len); 2660 datagram_address[channel].len);
2642} 2661}
@@ -2665,6 +2684,7 @@ set up yet, this function will block until socket setup has completed. */)
2665 channel = XPROCESS (process)->infd; 2684 channel = XPROCESS (process)->infd;
2666 2685
2667 len = get_lisp_to_sockaddr_size (address, &family); 2686 len = get_lisp_to_sockaddr_size (address, &family);
2687 eassert (0 <= channel && channel < FD_SETSIZE);
2668 if (len == 0 || datagram_address[channel].len != len) 2688 if (len == 0 || datagram_address[channel].len != len)
2669 return Qnil; 2689 return Qnil;
2670 conv_lisp_to_sockaddr (family, address, datagram_address[channel].sa, len); 2690 conv_lisp_to_sockaddr (family, address, datagram_address[channel].sa, len);
@@ -3043,6 +3063,7 @@ usage: (make-serial-process &rest ARGS) */)
3043 p->outfd = fd; 3063 p->outfd = fd;
3044 if (fd > max_desc) 3064 if (fd > max_desc)
3045 max_desc = fd; 3065 max_desc = fd;
3066 eassert (0 <= fd && fd < FD_SETSIZE);
3046 chan_process[fd] = proc; 3067 chan_process[fd] = proc;
3047 3068
3048 buffer = Fplist_get (contact, QCbuffer); 3069 buffer = Fplist_get (contact, QCbuffer);
@@ -3213,6 +3234,7 @@ finish_after_tls_connection (Lisp_Object proc)
3213 Fplist_get (contact, QChost), 3234 Fplist_get (contact, QChost),
3214 Fplist_get (contact, QCservice)); 3235 Fplist_get (contact, QCservice));
3215 3236
3237 eassert (p->outfd < FD_SETSIZE);
3216 if (NILP (result)) 3238 if (NILP (result))
3217 { 3239 {
3218 pset_status (p, list2 (Qfailed, 3240 pset_status (p, list2 (Qfailed,
@@ -3463,6 +3485,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3463#ifdef DATAGRAM_SOCKETS 3485#ifdef DATAGRAM_SOCKETS
3464 if (p->socktype == SOCK_DGRAM) 3486 if (p->socktype == SOCK_DGRAM)
3465 { 3487 {
3488 eassert (0 <= s && s < FD_SETSIZE);
3466 if (datagram_address[s].sa) 3489 if (datagram_address[s].sa)
3467 emacs_abort (); 3490 emacs_abort ();
3468 3491
@@ -3527,6 +3550,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3527 inch = s; 3550 inch = s;
3528 outch = s; 3551 outch = s;
3529 3552
3553 eassert (0 <= inch && inch < FD_SETSIZE);
3530 chan_process[inch] = proc; 3554 chan_process[inch] = proc;
3531 3555
3532 fcntl (inch, F_SETFL, O_NONBLOCK); 3556 fcntl (inch, F_SETFL, O_NONBLOCK);
@@ -3553,6 +3577,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3553 if (! (connecting_status (p->status) 3577 if (! (connecting_status (p->status)
3554 && EQ (XCDR (p->status), addrinfos))) 3578 && EQ (XCDR (p->status), addrinfos)))
3555 pset_status (p, Fcons (Qconnect, addrinfos)); 3579 pset_status (p, Fcons (Qconnect, addrinfos));
3580 eassert (0 <= inch && inch < FD_SETSIZE);
3556 if ((fd_callback_info[inch].flags & NON_BLOCKING_CONNECT_FD) == 0) 3581 if ((fd_callback_info[inch].flags & NON_BLOCKING_CONNECT_FD) == 0)
3557 add_non_blocking_write_fd (inch); 3582 add_non_blocking_write_fd (inch);
3558 } 3583 }
@@ -4620,6 +4645,7 @@ deactivate_process (Lisp_Object proc)
4620 close_process_fd (&p->open_fd[i]); 4645 close_process_fd (&p->open_fd[i]);
4621 4646
4622 inchannel = p->infd; 4647 inchannel = p->infd;
4648 eassert (inchannel < FD_SETSIZE);
4623 if (inchannel >= 0) 4649 if (inchannel >= 0)
4624 { 4650 {
4625 p->infd = -1; 4651 p->infd = -1;
@@ -4853,6 +4879,7 @@ server_accept_connection (Lisp_Object server, int channel)
4853 Lisp_Object name = Fformat (nargs, args); 4879 Lisp_Object name = Fformat (nargs, args);
4854 Lisp_Object proc = make_process (name); 4880 Lisp_Object proc = make_process (name);
4855 4881
4882 eassert (0 <= s && s < FD_SETSIZE);
4856 chan_process[s] = proc; 4883 chan_process[s] = proc;
4857 4884
4858 fcntl (s, F_SETFL, O_NONBLOCK); 4885 fcntl (s, F_SETFL, O_NONBLOCK);
@@ -5132,6 +5159,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5132 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) 5159 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
5133 break; 5160 break;
5134 5161
5162 eassert (max_desc < FD_SETSIZE);
5163
5135#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS 5164#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS
5136 { 5165 {
5137 Lisp_Object process_list_head, aproc; 5166 Lisp_Object process_list_head, aproc;
@@ -5875,6 +5904,7 @@ read_process_output (Lisp_Object proc, int channel)
5875{ 5904{
5876 ssize_t nbytes; 5905 ssize_t nbytes;
5877 struct Lisp_Process *p = XPROCESS (proc); 5906 struct Lisp_Process *p = XPROCESS (proc);
5907 eassert (0 <= channel && channel < FD_SETSIZE);
5878 struct coding_system *coding = proc_decode_coding_system[channel]; 5908 struct coding_system *coding = proc_decode_coding_system[channel];
5879 int carryover = p->decoding_carryover; 5909 int carryover = p->decoding_carryover;
5880 ptrdiff_t readmax = clip_to_bounds (1, read_process_output_max, PTRDIFF_MAX); 5910 ptrdiff_t readmax = clip_to_bounds (1, read_process_output_max, PTRDIFF_MAX);
@@ -6039,6 +6069,7 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
6039 proc_encode_coding_system[p->outfd] surely points to a 6069 proc_encode_coding_system[p->outfd] surely points to a
6040 valid memory because p->outfd will be changed once EOF is 6070 valid memory because p->outfd will be changed once EOF is
6041 sent to the process. */ 6071 sent to the process. */
6072 eassert (p->outfd < FD_SETSIZE);
6042 if (NILP (p->encode_coding_system) && p->outfd >= 0 6073 if (NILP (p->encode_coding_system) && p->outfd >= 0
6043 && proc_encode_coding_system[p->outfd]) 6074 && proc_encode_coding_system[p->outfd])
6044 { 6075 {
@@ -6278,6 +6309,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
6278 if (p->outfd < 0) 6309 if (p->outfd < 0)
6279 error ("Output file descriptor of %s is closed", SDATA (p->name)); 6310 error ("Output file descriptor of %s is closed", SDATA (p->name));
6280 6311
6312 eassert (p->outfd < FD_SETSIZE);
6281 coding = proc_encode_coding_system[p->outfd]; 6313 coding = proc_encode_coding_system[p->outfd];
6282 Vlast_coding_system_used = CODING_ID_NAME (coding->id); 6314 Vlast_coding_system_used = CODING_ID_NAME (coding->id);
6283 6315
@@ -6387,6 +6419,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
6387 /* Send this batch, using one or more write calls. */ 6419 /* Send this batch, using one or more write calls. */
6388 ptrdiff_t written = 0; 6420 ptrdiff_t written = 0;
6389 int outfd = p->outfd; 6421 int outfd = p->outfd;
6422 eassert (0 <= outfd && outfd < FD_SETSIZE);
6390#ifdef DATAGRAM_SOCKETS 6423#ifdef DATAGRAM_SOCKETS
6391 if (DATAGRAM_CHAN_P (outfd)) 6424 if (DATAGRAM_CHAN_P (outfd))
6392 { 6425 {
@@ -6837,6 +6870,7 @@ traffic. */)
6837 struct Lisp_Process *p; 6870 struct Lisp_Process *p;
6838 6871
6839 p = XPROCESS (process); 6872 p = XPROCESS (process);
6873 eassert (p->infd < FD_SETSIZE);
6840 if (EQ (p->command, Qt) 6874 if (EQ (p->command, Qt)
6841 && p->infd >= 0 6875 && p->infd >= 0
6842 && (!EQ (p->filter, Qt) || EQ (p->status, Qlisten))) 6876 && (!EQ (p->filter, Qt) || EQ (p->status, Qlisten)))
@@ -6964,6 +6998,7 @@ process has been transmitted to the serial port. */)
6964 6998
6965 6999
6966 outfd = XPROCESS (proc)->outfd; 7000 outfd = XPROCESS (proc)->outfd;
7001 eassert (outfd < FD_SETSIZE);
6967 if (outfd >= 0) 7002 if (outfd >= 0)
6968 coding = proc_encode_coding_system[outfd]; 7003 coding = proc_encode_coding_system[outfd];
6969 7004
@@ -7011,11 +7046,13 @@ process has been transmitted to the serial port. */)
7011 p->open_fd[WRITE_TO_SUBPROCESS] = new_outfd; 7046 p->open_fd[WRITE_TO_SUBPROCESS] = new_outfd;
7012 p->outfd = new_outfd; 7047 p->outfd = new_outfd;
7013 7048
7049 eassert (0 <= new_outfd && new_outfd < FD_SETSIZE);
7014 if (!proc_encode_coding_system[new_outfd]) 7050 if (!proc_encode_coding_system[new_outfd])
7015 proc_encode_coding_system[new_outfd] 7051 proc_encode_coding_system[new_outfd]
7016 = xmalloc (sizeof (struct coding_system)); 7052 = xmalloc (sizeof (struct coding_system));
7017 if (old_outfd >= 0) 7053 if (old_outfd >= 0)
7018 { 7054 {
7055 eassert (old_outfd < FD_SETSIZE);
7019 *proc_encode_coding_system[new_outfd] 7056 *proc_encode_coding_system[new_outfd]
7020 = *proc_encode_coding_system[old_outfd]; 7057 = *proc_encode_coding_system[old_outfd];
7021 memset (proc_encode_coding_system[old_outfd], 0, 7058 memset (proc_encode_coding_system[old_outfd], 0,
@@ -7464,6 +7501,7 @@ DEFUN ("process-filter-multibyte-p", Fprocess_filter_multibyte_p,
7464 struct Lisp_Process *p = XPROCESS (process); 7501 struct Lisp_Process *p = XPROCESS (process);
7465 if (p->infd < 0) 7502 if (p->infd < 0)
7466 return Qnil; 7503 return Qnil;
7504 eassert (p->infd < FD_SETSIZE);
7467 struct coding_system *coding = proc_decode_coding_system[p->infd]; 7505 struct coding_system *coding = proc_decode_coding_system[p->infd];
7468 return (CODING_FOR_UNIBYTE (coding) ? Qnil : Qt); 7506 return (CODING_FOR_UNIBYTE (coding) ? Qnil : Qt);
7469} 7507}
@@ -7497,6 +7535,7 @@ keyboard_bit_set (fd_set *mask)
7497{ 7535{
7498 int fd; 7536 int fd;
7499 7537
7538 eassert (max_desc < FD_SETSIZE);
7500 for (fd = 0; fd <= max_desc; fd++) 7539 for (fd = 0; fd <= max_desc; fd++)
7501 if (FD_ISSET (fd, mask) 7540 if (FD_ISSET (fd, mask)
7502 && ((fd_callback_info[fd].flags & (FOR_READ | KEYBOARD_FD)) 7541 && ((fd_callback_info[fd].flags & (FOR_READ | KEYBOARD_FD))
@@ -7744,6 +7783,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
7744void 7783void
7745add_timer_wait_descriptor (int fd) 7784add_timer_wait_descriptor (int fd)
7746{ 7785{
7786 eassert (0 <= fd && fd < FD_SETSIZE);
7747 add_read_fd (fd, timerfd_callback, NULL); 7787 add_read_fd (fd, timerfd_callback, NULL);
7748 fd_callback_info[fd].flags &= ~KEYBOARD_FD; 7788 fd_callback_info[fd].flags &= ~KEYBOARD_FD;
7749} 7789}
@@ -7806,6 +7846,7 @@ setup_process_coding_systems (Lisp_Object process)
7806 if (inch < 0 || outch < 0) 7846 if (inch < 0 || outch < 0)
7807 return; 7847 return;
7808 7848
7849 eassert (0 <= inch && inch < FD_SETSIZE);
7809 if (!proc_decode_coding_system[inch]) 7850 if (!proc_decode_coding_system[inch])
7810 proc_decode_coding_system[inch] = xmalloc (sizeof (struct coding_system)); 7851 proc_decode_coding_system[inch] = xmalloc (sizeof (struct coding_system));
7811 coding_system = p->decode_coding_system; 7852 coding_system = p->decode_coding_system;
@@ -7817,6 +7858,7 @@ setup_process_coding_systems (Lisp_Object process)
7817 } 7858 }
7818 setup_coding_system (coding_system, proc_decode_coding_system[inch]); 7859 setup_coding_system (coding_system, proc_decode_coding_system[inch]);
7819 7860
7861 eassert (0 <= outch && outch < FD_SETSIZE);
7820 if (!proc_encode_coding_system[outch]) 7862 if (!proc_encode_coding_system[outch])
7821 proc_encode_coding_system[outch] = xmalloc (sizeof (struct coding_system)); 7863 proc_encode_coding_system[outch] = xmalloc (sizeof (struct coding_system));
7822 setup_coding_system (p->encode_coding_system, 7864 setup_coding_system (p->encode_coding_system,