Source-Changes-HG archive

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

[src/trunk]: src/tests/lib/libcurses/slave tests/libcurses: fix reading from ...



details:   https://anonhg.NetBSD.org/src/rev/00ca257efa21
branches:  trunk
changeset: 959418:00ca257efa21
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sat Feb 13 09:28:27 2021 +0000

description:
tests/libcurses: fix reading from the parent process

In case of a short read, processing the incomplete data invoked
undefined behavior.

diffstat:

 tests/lib/libcurses/slave/slave.c |  52 ++++++++++++++++++++++++--------------
 1 files changed, 33 insertions(+), 19 deletions(-)

diffs (107 lines):

diff -r dddf1805e3b3 -r 00ca257efa21 tests/lib/libcurses/slave/slave.c
--- a/tests/lib/libcurses/slave/slave.c Sat Feb 13 09:18:12 2021 +0000
+++ b/tests/lib/libcurses/slave/slave.c Sat Feb 13 09:28:27 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: slave.c,v 1.14 2021/02/13 09:18:12 rillig Exp $        */
+/*     $NetBSD: slave.c,v 1.15 2021/02/13 09:28:27 rillig Exp $        */
 
 /*-
  * Copyright 2009 Brett Lymn <blymn%NetBSD.org@localhost>
@@ -32,6 +32,7 @@
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <err.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -50,6 +51,31 @@
 };
 #endif
 
+static bool
+try_read_from_director(void *data, size_t n)
+{
+       ssize_t nread = read(from_director, data, n);
+       if (nread < 0)
+               err(2, "error reading from command pipe");
+       if (nread == 0)
+               return false;
+       if ((size_t)nread != n)
+               errx(2, "short read from command pipe: expected %zu, got %zu",
+                   n, (size_t)nread);
+       return true;
+}
+
+static void
+read_from_director(void *data, size_t n)
+{
+       ssize_t nread = read(from_director, data, n);
+       if (nread < 0)
+               err(2, "error reading from command pipe");
+       if ((size_t)nread != n)
+               errx(2, "short read from command pipe: expected %zu, got %zu",
+                   n, (size_t)nread);
+}
+
 /*
  * Read the command pipe for the function to execute, gather the args
  * and then process the command.
@@ -59,23 +85,16 @@
 {
        int len, maxlen, argslen, i, ret, type;
        char *cmdbuf, *tmpbuf, **args, **tmpargs;
-       ssize_t nread;
 
        len = maxlen = 30;
        if ((cmdbuf = malloc(maxlen)) == NULL)
                err(1, "slave cmdbuf malloc failed");
 
-       for (;;) {
-               if ((nread = read(from_director, &type, sizeof(int))) < 0)
-                       err(1, "slave command type read failed");
-               if (nread == 0)
-                       break;
-
+       while (try_read_from_director(&type, sizeof type)) {
                if (type != data_string)
                        errx(1, "Unexpected type for command, got %d", type);
 
-               if (read(from_director, &len, sizeof(int)) < 0)
-                       err(1, "slave command len read failed");
+               read_from_director(&len, sizeof len);
 
                if ((len + 1) > maxlen) {
                        maxlen = len + 1;
@@ -85,18 +104,14 @@
                        cmdbuf = tmpbuf;
                }
 
-               if (read(from_director, cmdbuf, len) < 0)
-                       err(1, "slave command read failed");
+               read_from_director(cmdbuf, len);
                cmdbuf[len] = '\0';
                argslen = 0;
                args = NULL;
 
                do {
-                       if (read(from_director, &type, sizeof(int)) < 0)
-                               err(1, "slave arg type read failed");
-
-                       if (read(from_director, &len, sizeof(int)) < 0)
-                               err(1, "slave arg len read failed");
+                       read_from_director(&type, sizeof type);
+                       read_from_director(&len, sizeof len);
 
                        if (len >= 0) {
                                tmpargs = realloc(args,
@@ -120,8 +135,7 @@
                                        else
                                                args[argslen][0] = '\0';
                                } else {
-                                       read(from_director, args[argslen],
-                                            len);
+                                       read_from_director(args[argslen], len);
                                        if (type != data_byte)
                                                args[argslen][len] = '\0';
 



Home | Main Index | Thread Index | Old Index