From c44d082735adaf62cc467ab6b199ab3e2bc22757 Mon Sep 17 00:00:00 2001 From: InterLinked1 <24227567+InterLinked1@users.noreply.github.com> Date: Fri, 24 Nov 2023 19:19:28 -0500 Subject: [PATCH] pty.c: Don't attempt to write 0 bytes to node. For non-ANSI nodes, we call bbs_ansi_strip to remove all the escape sequences from the buffer before we write it to the node. However, in the case that this actually results in an empty buffer, don't attempt to write it. No nasty side effects will happen, but a warning will be thrown otherwise since we shouldn't be attempting to write 0 bytes. --- bbs/node.c | 4 ++-- bbs/pty.c | 6 ++++++ bbs/socket.c | 10 ++++------ include/ansi.h | 1 + 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/bbs/node.c b/bbs/node.c index de6389e..e2093c2 100644 --- a/bbs/node.c +++ b/bbs/node.c @@ -661,7 +661,7 @@ static int cli_nodes(struct bbs_cli_args *a) int c = 0; time_t now = time(NULL); - bbs_dprintf(a->fdout, "%3s %8s %9s %7s %-15s %-25s %15s %5s %1s %1s %7s %3s %3s %3s %3s %3s %3s %s\n", "#", "PROTOCOL", "ELAPSED", "TRM SZE", "USER", "MENU/PAGE", "IP ADDRESS", "RPORT", "E", "B", "TID", "FD", "RFD", "WFD", "MST", "SLV", "SPY", "SLV NAME"); + bbs_dprintf(a->fdout, "%3s %9s %9s %7s %-15s %-25s %15s %5s %1s %1s %7s %3s %3s %3s %3s %3s %3s %s\n", "#", "PROTOCOL", "ELAPSED", "TRM SZE", "USER", "MENU/PAGE", "IP ADDRESS", "RPORT", "E", "B", "TID", "FD", "RFD", "WFD", "MST", "SLV", "SPY", "SLV NAME"); RWLIST_RDLOCK(&nodes); RWLIST_TRAVERSE(&nodes, n, entry) { @@ -678,7 +678,7 @@ static int cli_nodes(struct bbs_cli_args *a) print_time_elapsed(n->created, now, elapsed, sizeof(elapsed)); snprintf(menufull, sizeof(menufull), "%s%s%s%s", S_IF(n->menu), n->menuitem ? " (" : "", S_IF(n->menuitem), n->menuitem ? ")" : ""); lwp = bbs_pthread_tid(n->thread); - bbs_dprintf(a->fdout, "%3d %8s %9s %3dx%3d %-15s %-25s %15s %5u %1s %1s %7d %3d %3d %3d %3d %3d %3d %s\n", + bbs_dprintf(a->fdout, "%3d %9s %9s %3dx%3d %-15s %-25s %15s %5u %1s %1s %7d %3d %3d %3d %3d %3d %3d %s\n", n->id, n->protname, elapsed, n->cols, n->rows, bbs_username(n->user), menufull, n->ip, n->rport, BBS_YN(n->echo), BBS_YN(n->buffered), lwp, n->fd, n->rfd, n->wfd, n->amaster, n->slavefd, n->spyfd, n->slavename); c++; diff --git a/bbs/pty.c b/bbs/pty.c index c56f7ee..318f1dc 100644 --- a/bbs/pty.c +++ b/bbs/pty.c @@ -707,6 +707,12 @@ void *pty_master(void *varg) writebuf[bytes_read] = '\0'; /* NUL terminate for bbs_ansi_strip */ /*! \todo XXX This should always get smaller... so couldn't this be done in place? */ if (!bbs_ansi_strip(writebuf, (size_t) bytes_read, strippedbuf, sizeof(strippedbuf), &strippedlen)) { + if (strippedlen == 0) { + bbs_debug(9, "Reduced all %lu bytes to nothing after stripping escape sequences\n", bytes_read); + /* There is nothing to write, don't even bother calling bbs_write, + * since we shouldn't call write with 0 bytes. */ + continue; + } bytes_read = strippedlen; relaybuf = strippedbuf; } /* else, failed to strip, just write the original data (possibly containing ANSI escape sequences) */ diff --git a/bbs/socket.c b/bbs/socket.c index 5987114..52b0ed5 100644 --- a/bbs/socket.c +++ b/bbs/socket.c @@ -2124,7 +2124,6 @@ static int bbs_node_ansi_write(struct bbs_node *node, const char *restrict buf, ssize_t bbs_node_write(struct bbs_node *node, const char *buf, size_t len) { struct pollfd pfd; - size_t left = len; ssize_t res; #ifdef DETECT_IMPROPER_NODE_WRITES @@ -2147,28 +2146,27 @@ ssize_t bbs_node_write(struct bbs_node *node, const char *buf, size_t len) /* So helgrind doesn't complain about data race if node is shut down * and slavefd closed during write */ bbs_node_lock(node); - res = full_write(&pfd, node->slavefd, buf, left); + res = full_write(&pfd, node->slavefd, buf, len); if (res <= 0 || res != (ssize_t) len) { bbs_debug(5, "Node %d: write returned %lu/%lu\n", node->id, res, len); } bbs_node_unlock(node); - return (int) res; + return res; } ssize_t bbs_write(int fd, const char *buf, size_t len) { struct pollfd pfd; - size_t left = len; ssize_t res; pfd.fd = fd; pfd.events = POLLOUT; - res = full_write(&pfd, fd, buf, left); + res = full_write(&pfd, fd, buf, len); if (res <= 0) { bbs_debug(5, "fd %d: write returned %ld: %s\n", fd, res, res ? strerror(errno) : ""); } - return (int) res; + return res; } ssize_t bbs_timed_write(int fd, const char *buf, size_t len, int ms) diff --git a/include/ansi.h b/include/ansi.h index f668a4a..4679a8b 100644 --- a/include/ansi.h +++ b/include/ansi.h @@ -20,5 +20,6 @@ * \param out Buffer in which the stripped string will be placed * \param outlen Size of out. Should be at least inlen, but no more than it. * \param strippedlen Will be set to the actual length of the stripped output, not including null terminator. + * \retval 0 on success, -1 on failure */ int bbs_ansi_strip(const char *restrict in, size_t inlen, char *restrict out, size_t outlen, int *restrict strippedlen);