commit 689d9bfcf6859e5ce85c296ff0f23b5c08b1fedc
Author:     NRK <[email protected]>
AuthorDate: Mon Oct 31 00:10:45 2022 +0600
Commit:     Hiltjo Posthuma <[email protected]>
CommitDate: Mon Oct 31 11:40:35 2022 +0100

    fix leak when getline fails
    
    according to the getline(3) documentation, the calling code needs to
    free the buffer even if getline fails.
    
    dmenu currently doesn't do that which results in a small leak in case of
    failure (e.g when piped /dev/null)
    
            $ ./dmenu < /dev/null
            ==8201==ERROR: LeakSanitizer: detected memory leaks
            Direct leak of 120 byte(s) in 1 object(s) allocated from:
                #0 0x7f6bf5785ef7 in malloc
                #1 0x7f6bf538ec84 in __getdelim
                #2 0x405d0c in readstdin dmenu.c:557
    
    moving `line = NULL` inside the loop body wasn't strictly necessary, but
    IMO it makes it more apparent that `line` is getting cleared to NULL
    after each successful iteration.

diff --git a/dmenu.c b/dmenu.c
index e7be8af..e786d7a 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -554,7 +554,7 @@ readstdin(void)
        ssize_t len;
 
        /* read each line from stdin and add it to the item list */
-       for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++, line = 
NULL) {
+       for (i = 0; (len = getline(&line, &junk, stdin)) != -1; i++) {
                if (i + 1 >= size / sizeof *items)
                        if (!(items = realloc(items, (size += BUFSIZ))))
                                die("cannot realloc %zu bytes:", size);
@@ -562,7 +562,9 @@ readstdin(void)
                        line[len - 1] = '\0';
                items[i].text = line;
                items[i].out = 0;
+               line = NULL;
        }
+       free(line);
        if (items)
                items[i].text = NULL;
        lines = MIN(lines, i);

Reply via email to