mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
tokenize: strdup() each individual argv
Instead of referencing the un-tokenized “raw” command string, strdup() each argv. This way, the input string can be ‘const’.
This commit is contained in:
parent
7632e16e36
commit
42ec264075
5 changed files with 56 additions and 38 deletions
64
config.c
64
config.c
|
|
@ -501,29 +501,59 @@ str_to_pt_or_px(const char *s, struct pt_or_px *res, struct config *conf,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void NOINLINE
|
||||||
|
free_spawn_template(struct config_spawn_template *template)
|
||||||
|
{
|
||||||
|
if (template->argv == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (char **argv = template->argv; *argv != NULL; argv++)
|
||||||
|
free(*argv);
|
||||||
|
free(template->argv);
|
||||||
|
template->argv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NOINLINE
|
||||||
|
clone_spawn_template(struct config_spawn_template *dst,
|
||||||
|
const struct config_spawn_template *src)
|
||||||
|
{
|
||||||
|
if (src->argv == NULL) {
|
||||||
|
dst->argv = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t count = 0;
|
||||||
|
for (char **argv = src->argv; *argv != NULL; argv++)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
dst->argv = xmalloc((count + 1) * sizeof(dst->argv[0]));
|
||||||
|
for (char **argv_src = src->argv, **argv_dst = dst->argv;
|
||||||
|
*argv_src != NULL; argv_src++,
|
||||||
|
argv_dst++)
|
||||||
|
{
|
||||||
|
*argv_dst = xstrdup(*argv_src);
|
||||||
|
}
|
||||||
|
dst->argv[count] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static bool NOINLINE
|
static bool NOINLINE
|
||||||
str_to_spawn_template(struct config *conf,
|
str_to_spawn_template(struct config *conf,
|
||||||
const char *s, struct config_spawn_template *template,
|
const char *s, struct config_spawn_template *template,
|
||||||
const char *path, int lineno, const char *section,
|
const char *path, int lineno, const char *section,
|
||||||
const char *key)
|
const char *key)
|
||||||
{
|
{
|
||||||
free(template->raw_cmd);
|
free_spawn_template(template);
|
||||||
free(template->argv);
|
|
||||||
|
|
||||||
template->raw_cmd = NULL;
|
|
||||||
template->argv = NULL;
|
|
||||||
|
|
||||||
char *raw_cmd = xstrdup(s);
|
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
|
|
||||||
if (!tokenize_cmdline(raw_cmd, &argv)) {
|
if (!tokenize_cmdline(s, &argv)) {
|
||||||
LOG_AND_NOTIFY_ERR(
|
LOG_AND_NOTIFY_ERR(
|
||||||
"%s:%d: [%s]: %s: syntax error in command line",
|
"%s:%d: [%s]: %s: syntax error in command line",
|
||||||
path, lineno, section, key);
|
path, lineno, section, key);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template->raw_cmd = raw_cmd;
|
|
||||||
template->argv = argv;
|
template->argv = argv;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -2594,7 +2624,6 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
.urgent = false,
|
.urgent = false,
|
||||||
.notify = false,
|
.notify = false,
|
||||||
.command = {
|
.command = {
|
||||||
.raw_cmd = NULL,
|
|
||||||
.argv = NULL,
|
.argv = NULL,
|
||||||
},
|
},
|
||||||
.command_focused = false,
|
.command_focused = false,
|
||||||
|
|
@ -2671,7 +2700,6 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
.selection_target = SELECTION_TARGET_PRIMARY,
|
.selection_target = SELECTION_TARGET_PRIMARY,
|
||||||
.hold_at_exit = false,
|
.hold_at_exit = false,
|
||||||
.notify = {
|
.notify = {
|
||||||
.raw_cmd = NULL,
|
|
||||||
.argv = NULL,
|
.argv = NULL,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -2717,12 +2745,9 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conf->notify.raw_cmd = xstrdup(
|
tokenize_cmdline("notify-send -a ${app-id} -i ${app-id} ${title} ${body}",
|
||||||
"notify-send -a ${app-id} -i ${app-id} ${title} ${body}");
|
&conf->notify.argv);
|
||||||
tokenize_cmdline(conf->notify.raw_cmd, &conf->notify.argv);
|
tokenize_cmdline("xdg-open ${url}", &conf->url.launch.argv);
|
||||||
|
|
||||||
conf->url.launch.raw_cmd = xstrdup("xdg-open ${url}");
|
|
||||||
tokenize_cmdline(conf->url.launch.raw_cmd, &conf->url.launch.argv);
|
|
||||||
|
|
||||||
static const wchar_t *url_protocols[] = {
|
static const wchar_t *url_protocols[] = {
|
||||||
L"http://",
|
L"http://",
|
||||||
|
|
@ -2847,13 +2872,6 @@ config_override_apply(struct config *conf, config_override_t *overrides, bool er
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NOINLINE
|
|
||||||
free_spawn_template(struct config_spawn_template *template)
|
|
||||||
{
|
|
||||||
free(template->raw_cmd);
|
|
||||||
free(template->argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void NOINLINE
|
static void NOINLINE
|
||||||
binding_pipe_free(struct config_binding_pipe *pipe)
|
binding_pipe_free(struct config_binding_pipe *pipe)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
1
config.h
1
config.h
|
|
@ -63,7 +63,6 @@ DEFINE_LIST(struct config_mouse_binding);
|
||||||
typedef tll(char *) config_override_t;
|
typedef tll(char *) config_override_t;
|
||||||
|
|
||||||
struct config_spawn_template {
|
struct config_spawn_template {
|
||||||
char *raw_cmd;
|
|
||||||
char **argv;
|
char **argv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
4
slave.c
4
slave.c
|
|
@ -293,9 +293,7 @@ slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv,
|
||||||
char **shell_argv = NULL;
|
char **shell_argv = NULL;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
char *shell_copy = xstrdup(conf_shell);
|
if (!tokenize_cmdline(conf_shell, &_shell_argv)) {
|
||||||
if (!tokenize_cmdline(shell_copy, &_shell_argv)) {
|
|
||||||
free(shell_copy);
|
|
||||||
(void)!write(fork_pipe[1], &errno, sizeof(errno));
|
(void)!write(fork_pipe[1], &errno, sizeof(errno));
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
tokenize.c
23
tokenize.c
|
|
@ -6,9 +6,10 @@
|
||||||
#define LOG_MODULE "tokenize"
|
#define LOG_MODULE "tokenize"
|
||||||
#define LOG_ENABLE_DBG 0
|
#define LOG_ENABLE_DBG 0
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
push_argv(char ***argv, size_t *size, char *arg, size_t *argc)
|
push_argv(char ***argv, size_t *size, const char *arg, size_t len, size_t *argc)
|
||||||
{
|
{
|
||||||
if (arg != NULL && arg[0] == '%')
|
if (arg != NULL && arg[0] == '%')
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -24,21 +25,23 @@ push_argv(char ***argv, size_t *size, char *arg, size_t *argc)
|
||||||
*size = new_size;
|
*size = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*argv)[(*argc)++] = arg;
|
(*argv)[(*argc)++] = arg != NULL ? xstrndup(arg, len) : NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
tokenize_cmdline(char *cmdline, char ***argv)
|
tokenize_cmdline(const char *cmdline, char ***argv)
|
||||||
{
|
{
|
||||||
*argv = NULL;
|
*argv = NULL;
|
||||||
size_t argv_size = 0;
|
size_t argv_size = 0;
|
||||||
|
|
||||||
|
const char *final_end = cmdline + strlen(cmdline) + 1;
|
||||||
|
|
||||||
bool first_token_is_quoted = cmdline[0] == '"' || cmdline[0] == '\'';
|
bool first_token_is_quoted = cmdline[0] == '"' || cmdline[0] == '\'';
|
||||||
char delim = first_token_is_quoted ? cmdline[0] : ' ';
|
char delim = first_token_is_quoted ? cmdline[0] : ' ';
|
||||||
|
|
||||||
char *p = first_token_is_quoted ? &cmdline[1] : &cmdline[0];
|
const char *p = first_token_is_quoted ? &cmdline[1] : &cmdline[0];
|
||||||
char *search_start = p;
|
const char *search_start = p;
|
||||||
|
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
while (*p != '\0') {
|
while (*p != '\0') {
|
||||||
|
|
@ -51,8 +54,8 @@ tokenize_cmdline(char *cmdline, char ***argv)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!push_argv(argv, &argv_size, p, &idx) ||
|
if (!push_argv(argv, &argv_size, p, final_end - p, &idx) ||
|
||||||
!push_argv(argv, &argv_size, NULL, &idx))
|
!push_argv(argv, &argv_size, NULL, 0, &idx))
|
||||||
{
|
{
|
||||||
goto err;
|
goto err;
|
||||||
} else
|
} else
|
||||||
|
|
@ -68,9 +71,9 @@ tokenize_cmdline(char *cmdline, char ***argv)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
*end = '\0';
|
//*end = '\0';
|
||||||
|
|
||||||
if (!push_argv(argv, &argv_size, p, &idx))
|
if (!push_argv(argv, &argv_size, p, end - p, &idx))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
p = end + 1;
|
p = end + 1;
|
||||||
|
|
@ -88,7 +91,7 @@ tokenize_cmdline(char *cmdline, char ***argv)
|
||||||
search_start = p;
|
search_start = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!push_argv(argv, &argv_size, NULL, &idx))
|
if (!push_argv(argv, &argv_size, NULL, 0, &idx))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
bool tokenize_cmdline(char *cmdline, char ***argv);
|
bool tokenize_cmdline(const char *cmdline, char ***argv);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue