sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 27b35128a5565d89a4c9caf7b305d831bd772d90
parent 6a40624555b5ba2a51a98abc50242df65e894432
Author: NRK <nrk@disroot.org>
Date:   Tue, 23 Aug 2022 02:50:20 +0600

[dmenu][separator]: rebase + fix invalid free()

when `separator_reverse` is active `items.text_output` and `items.text`
will be swapped leading to trying to free a pointer that wasn't
allocated.

this was not a problem before b43ec05 since `items` were not being
free-ed at cleanup() before that commit.

also rm `separator_greedy` and use a function pointer instead.

Diffstat:
Dtools.suckless.org/dmenu/patches/separator/dmenu-separator-20210904-d78ff08.diff | 101-------------------------------------------------------------------------------
Atools.suckless.org/dmenu/patches/separator/dmenu-separator-e35976f.diff | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtools.suckless.org/dmenu/patches/separator/index.md | 7+++----
3 files changed, 112 insertions(+), 105 deletions(-)

diff --git a/tools.suckless.org/dmenu/patches/separator/dmenu-separator-20210904-d78ff08.diff b/tools.suckless.org/dmenu/patches/separator/dmenu-separator-20210904-d78ff08.diff @@ -1,101 +0,0 @@ -diff --git a/dmenu.1 b/dmenu.1 -index 323f93c..d511148 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -22,6 +22,10 @@ dmenu \- dynamic menu - .IR color ] - .RB [ \-w - .IR windowid ] -+.RB [ \-d -+.IR separator ] -+.RB [ \-D -+.IR separator ] - .P - .BR dmenu_run " ..." - .SH DESCRIPTION -@@ -80,6 +84,14 @@ prints version information to stdout, then exits. - .TP - .BI \-w " windowid" - embed into windowid. -+.TP -+.BI \-d " separator" -+separate the input into two halves on the first occurrence of the given charcter. -+Display only the first half in dmenu and print the second half to stdout upon selection. -+Appending '|' to the separator reverses the display/printing order. -+.TP -+.BI \-D " separator" -+same as \-d but separate based on the last occurrence. - .SH USAGE - dmenu is completely controlled by the keyboard. Items are selected using the - arrow keys, page up, page down, home, and end. -diff --git a/dmenu.c b/dmenu.c -index 98507d9..82227c8 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -30,12 +30,16 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ - - struct item { - char *text; -+ char *text_output; - struct item *left, *right; - int out; - }; - - static char text[BUFSIZ] = ""; - static char *embed; -+static char separator; -+static int separator_greedy; -+static int separator_reverse; - static int bh, mw, mh; - static int inputw = 0, promptw; - static int lrpad; /* sum of left and right padding */ -@@ -473,7 +477,7 @@ insert: - break; - case XK_Return: - case XK_KP_Enter: -- puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); -+ puts((sel && !(ev->state & ShiftMask)) ? sel->text_output : text); - if (!(ev->state & ControlMask)) { - cleanup(); - exit(0); -@@ -545,6 +549,18 @@ readstdin(void) - *p = '\0'; - if (!(items[i].text = strdup(buf))) - die("cannot strdup %u bytes:", strlen(buf) + 1); -+ if (separator && (p = separator_greedy ? -+ strrchr(items[i].text, separator) : strchr(items[i].text, separator))) { -+ *p = '\0'; -+ items[i].text_output = ++p; -+ } else { -+ items[i].text_output = items[i].text; -+ } -+ if (separator_reverse) { -+ p = items[i].text; -+ items[i].text = items[i].text_output; -+ items[i].text_output = p; -+ } - items[i].out = 0; - drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL); - if (tmpmax > inputw) { -@@ -701,7 +717,8 @@ static void - usage(void) - { - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" -- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); -+ " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n" -+ " [-d separator] [-D separator]\n", stderr); - exit(1); - } - -@@ -744,6 +761,11 @@ main(int argc, char *argv[]) - colors[SchemeSel][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-w")) /* embedding window id */ - embed = argv[++i]; -+ else if (!strcmp(argv[i], "-d") || /* field separator */ -+ (separator_greedy = !strcmp(argv[i], "-D"))) { -+ separator = argv[++i][0]; -+ separator_reverse = argv[i][1] == '|'; -+ } - else - usage(); - diff --git a/tools.suckless.org/dmenu/patches/separator/dmenu-separator-e35976f.diff b/tools.suckless.org/dmenu/patches/separator/dmenu-separator-e35976f.diff @@ -0,0 +1,109 @@ +diff --git a/dmenu.1 b/dmenu.1 +index 323f93c..d511148 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -22,6 +22,10 @@ dmenu \- dynamic menu + .IR color ] + .RB [ \-w + .IR windowid ] ++.RB [ \-d ++.IR separator ] ++.RB [ \-D ++.IR separator ] + .P + .BR dmenu_run " ..." + .SH DESCRIPTION +@@ -80,6 +84,14 @@ prints version information to stdout, then exits. + .TP + .BI \-w " windowid" + embed into windowid. ++.TP ++.BI \-d " separator" ++separate the input into two halves on the first occurrence of the given charcter. ++Display only the first half in dmenu and print the second half to stdout upon selection. ++Appending '|' to the separator reverses the display/printing order. ++.TP ++.BI \-D " separator" ++same as \-d but separate based on the last occurrence. + .SH USAGE + dmenu is completely controlled by the keyboard. Items are selected using the + arrow keys, page up, page down, home, and end. +diff --git a/dmenu.c b/dmenu.c +index 571bc35..f2add3b 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -30,12 +30,15 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ + + struct item { + char *text; ++ char *text_output; + struct item *left, *right; + int out; + }; + + static char text[BUFSIZ] = ""; + static char *embed; ++static char separator, separator_reverse; ++static char * (*sepchr)(const char *, int); + static int bh, mw, mh; + static int inputw = 0, promptw; + static int lrpad; /* sum of left and right padding */ +@@ -105,7 +108,7 @@ cleanup(void) + for (i = 0; i < SchemeLast; i++) + free(scheme[i]); + for (i = 0; items && items[i].text; ++i) +- free(items[i].text); ++ free(separator_reverse ? items[i].text_output : items[i].text); + free(items); + drw_free(drw); + XSync(dpy, False); +@@ -490,7 +493,7 @@ insert: + break; + case XK_Return: + case XK_KP_Enter: +- puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); ++ puts((sel && !(ev->state & ShiftMask)) ? sel->text_output : text); + if (!(ev->state & ControlMask)) { + cleanup(); + exit(0); +@@ -561,6 +564,17 @@ readstdin(void) + *p = '\0'; + if (!(items[i].text = strdup(buf))) + die("cannot strdup %zu bytes:", strlen(buf) + 1); ++ if (separator && (p = sepchr(items[i].text, separator)) != NULL) { ++ *p = '\0'; ++ items[i].text_output = ++p; ++ } else { ++ items[i].text_output = items[i].text; ++ } ++ if (separator_reverse) { ++ p = items[i].text; ++ items[i].text = items[i].text_output; ++ items[i].text_output = p; ++ } + items[i].out = 0; + } + if (items) +@@ -711,7 +725,8 @@ static void + usage(void) + { + fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" +- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); ++ " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n" ++ " [-d separator] [-D separator]\n", stderr); + exit(1); + } + +@@ -754,6 +769,12 @@ main(int argc, char *argv[]) + colors[SchemeSel][ColFg] = argv[++i]; + else if (!strcmp(argv[i], "-w")) /* embedding window id */ + embed = argv[++i]; ++ else if (!strcmp(argv[i], "-d") || /* field separator */ ++ !strcmp(argv[i], "-D")) { ++ sepchr = argv[i][1] == 'D' ? strrchr : strchr; ++ separator = argv[++i][0]; ++ separator_reverse = argv[i][1] == '|'; ++ } + else + usage(); + diff --git a/tools.suckless.org/dmenu/patches/separator/index.md b/tools.suckless.org/dmenu/patches/separator/index.md @@ -8,9 +8,7 @@ The following example will split the input into two halves on the _first_ occurrence of ' ' (space). Meaning "alpha" will be displayed on dmenu, and "beta charlie" will be printed to stdout upon selection. -` -echo "alpha beta charlie" | dmenu -d ' ' -` + echo "alpha beta charlie" | dmenu -d ' ' `-D` is similar but it separates the input based on the _last_ occurrence instead. @@ -20,7 +18,8 @@ and display the latter half on dmenu while printing the first half upon selectio Download -------- -* [dmenu-separator-20210904-d78ff08.diff](dmenu-separator-20210904-d78ff08.diff) + +* [dmenu-separator-e35976f.diff](dmenu-separator-e35976f.diff) Author ------