From 881d788bee20e337428c566784977b1e7a3f2b29 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 21 Sep 2023 23:09:05 +0100 Subject: [PATCH] action: do not expand env vars in Exec action ... argument (but still resolve tilde). This makes it easier to write sh -c '' constructs without turning labwc into a shell parser in order to expand environment variables, whilst respecting single quotes and escaped characters as well as ignoring subshells syntax like $(foo) and backticks. Also, fix bug where buffer length+alloc get out-of-sync --- docs/labwc-actions.5.scd | 1 + docs/labwc-config.5.scd | 2 ++ include/common/buf.h | 8 +++++++- src/action.c | 2 +- src/common/buf.c | 42 ++++++++++++++++++++++++++++++---------- src/config/session.c | 1 + 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index b5daf093..287eb28e 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -19,6 +19,7 @@ Actions are used in menus and keyboard/mouse bindings. Execute command. Note that in the interest of backward compatibility, labwc supports as an alternative to even though openbox documentation states that it is deprecated. + Note: Tilde (~) is expanded in the command before passing to execvp() ** Exit labwc. diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 023f0578..79448374 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -32,6 +32,8 @@ variables accordingly. It is recommended to specify keyboard layout settings and cursor size/theme here; see environment variable section below for details. Note that the environment file is treated differently by openbox where it is simply sourced prior to running openbox. +Note: Tilde (~) and environment variables in the value are expanded, but +subshell syntax and apostrophes are ignored. The *menu.xml* file defines the context/root-menus and is described in labwc-menu(5). diff --git a/include/common/buf.h b/include/common/buf.h index 9fcb5206..64310c9a 100644 --- a/include/common/buf.h +++ b/include/common/buf.h @@ -19,7 +19,13 @@ struct buf { }; /** - * buf_expand_shell_variables - expand $foo, ${foo} and ~ in buffer + * buf_expand_tilde - expand ~ in buffer + * @s: buffer + */ +void buf_expand_tilde(struct buf *s); + +/** + * buf_expand_shell_variables - expand $foo and ${foo} in buffer * @s: buffer * Note: $$ is not handled */ diff --git a/src/action.c b/src/action.c index c04e1c54..e114d193 100644 --- a/src/action.c +++ b/src/action.c @@ -564,7 +564,7 @@ actions_run(struct view *activator, struct server *server, struct buf cmd; buf_init(&cmd); buf_add(&cmd, action_str_from_arg(arg)); - buf_expand_shell_variables(&cmd); + buf_expand_tilde(&cmd); spawn_async_no_shell(cmd.buf); free(cmd.buf); } diff --git a/src/common/buf.c b/src/common/buf.c index 90a180dc..6311def9 100644 --- a/src/common/buf.c +++ b/src/common/buf.c @@ -4,6 +4,35 @@ #include "common/buf.h" #include "common/mem.h" +static void +buf_add_one_char(struct buf *s, char ch) +{ + if (s->alloc <= s->len + 1) { + s->alloc = s->alloc * 3 / 2 + 16; + s->buf = xrealloc(s->buf, s->alloc); + } + s->buf[s->len++] = ch; + s->buf[s->len] = '\0'; +} + +void +buf_expand_tilde(struct buf *s) +{ + struct buf new; + buf_init(&new); + for (int i = 0 ; i < s->len ; i++) { + if (s->buf[i] == '~') { + buf_add(&new, getenv("HOME")); + } else { + buf_add_one_char(&new, s->buf[i]); + } + } + free(s->buf); + s->buf = new.buf; + s->len = new.len; + s->alloc = new.alloc; +} + static void strip_curly_braces(char *s) { @@ -46,22 +75,15 @@ buf_expand_shell_variables(struct buf *s) if (p) { buf_add(&new, p); } - } else if (s->buf[i] == '~') { - /* expand tilde */ - buf_add(&new, getenv("HOME")); } else { - /* just add one character at a time */ - if (new.alloc <= new.len + 1) { - new.alloc = new.alloc * 3 / 2 + 16; - new.buf = xrealloc(new.buf, new.alloc); - } - new.buf[new.len++] = s->buf[i]; - new.buf[new.len] = '\0'; + buf_add_one_char(&new, s->buf[i]); } } free(environment_variable.buf); free(s->buf); s->buf = new.buf; + s->len = new.len; + s->alloc = new.alloc; } void diff --git a/src/config/session.c b/src/config/session.c index 1a528d18..d7c37b6b 100644 --- a/src/config/session.c +++ b/src/config/session.c @@ -38,6 +38,7 @@ process_line(char *line) buf_init(&value); buf_add(&value, string_strip(++p)); buf_expand_shell_variables(&value); + buf_expand_tilde(&value); if (string_empty(key) || !value.len) { goto error; }