From ffe483fb948d178b01bdc4d43241137f9f206807 Mon Sep 17 00:00:00 2001 From: Yasuhiro Ohara Date: Fri, 29 Sep 2023 05:17:15 +0900 Subject: [PATCH] fix buffer-related output corruption of vty_out(). Signed-off-by: Yasuhiro Ohara --- lib/buffer.c | 25 +++++++++++++++++++++++++ lib/buffer.h | 2 ++ lib/vty.c | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/buffer.c b/lib/buffer.c index fdb77f4bc396..d41ff69833c1 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -154,6 +154,31 @@ void buffer_put(struct buffer *b, const void *p, size_t size) } } +/* buffer_put() and terminate the buffer with '\0' */ +void buffer_put_strnul(struct buffer *b, const void *p, size_t size) +{ + struct buffer_data *data = b->tail; + const char *ptr = p; + + /* We use even last one byte of data buffer. */ + while (size) { + size_t chunk; + + /* If there is no data buffer add it. */ + if (data == NULL || data->cp + 1 == b->size) + data = buffer_add(b); + + chunk = ((size <= (b->size - data->cp - 1)) ? + size : (b->size - data->cp - 1)); + memcpy((data->data + data->cp), ptr, chunk); + size -= chunk; + ptr += chunk; + data->cp += chunk; + data->data[data->cp] = '\0'; + } +} + + /* Insert character into the buffer. */ void buffer_putc(struct buffer *b, uint8_t c) { diff --git a/lib/buffer.h b/lib/buffer.h index 5d1f4ff9522b..8643df098d15 100644 --- a/lib/buffer.h +++ b/lib/buffer.h @@ -25,6 +25,8 @@ extern void buffer_free(struct buffer *); /* Add the given data to the end of the buffer. */ extern void buffer_put(struct buffer *, const void *, size_t); +/* Add the given data to the end of the buffer, terminate with NUL. */ +extern void buffer_put_strnul(struct buffer *, const void *, size_t); /* Add a single character to the end of the buffer. */ extern void buffer_putc(struct buffer *, uint8_t); /* Add a NUL-terminated string to the end of the buffer. */ diff --git a/lib/vty.c b/lib/vty.c index 78eb642ded71..b1c16a33ebfd 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -452,7 +452,7 @@ int vty_out(struct vty *vty, const char *format, ...) nlines--; vty->vtysh_lines += nlines; } - buffer_put(vty->obuf, (uint8_t *)filtered, strlen(filtered)); + buffer_put_strnul(vty->obuf, (uint8_t *)filtered, strlen(filtered)); break; case VTY_SHELL_SERV: case VTY_FILE: