From 1475c3ce457f58b37dfdf50388d0bbd49291b022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Tempel?= Date: Sun, 4 Apr 2021 13:57:56 +0200 Subject: [PATCH] client: improve stripping of getline(3) newline The previous version of this code operated under the assumption that getline(3) lines are always \n\0 terminated. Unfortunately, this is not the case as readline will return input which is not terminated with a newline character if EOF is reached before encountering this newline. In these cases, the code would falsely strip the last character. As an example, consider the following bemenu invocation: printf foo | ./bemenu This would start bemenu with `fo` instead of `foo` as a menu item. This commit fixes this edge case and also hardens the loop body a bit by only entering it if getline wrote more than zero characters to the buffer. --- client/bemenu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/bemenu.c b/client/bemenu.c index d327f3a..6bdf797 100644 --- a/client/bemenu.c +++ b/client/bemenu.c @@ -18,10 +18,10 @@ read_items_to_menu_from_stdin(struct bm_menu *menu) size_t llen = 0; char *line = NULL; - while ((n = getline(&line, &llen, stdin)) != -1) { - // Remove trailing newline - assert(n >= 1); - line[n - 1] = '\0'; + while ((n = getline(&line, &llen, stdin)) > 0) { + // Remove trailing newline (if any) + if (line[n - 1] == '\n') + line[n - 1] = '\0'; struct bm_item *item; if (!(item = bm_item_new(line)))