edit-util: don't leave custom editor args around if we shall fall back (#36813)

Also, let's complain loudly if the editor acquired from envvar is not
present.

Fixes #36796
This commit is contained in:
Yu Watanabe
2025-03-21 08:48:05 +09:00
committed by GitHub
2 changed files with 27 additions and 16 deletions
+7 -4
View File
@@ -35,13 +35,16 @@ static inline void* mempcpy_safe(void *dst, const void *src, size_t n) {
return mempcpy(dst, src, n);
}
#define mempcpy_typesafe(dst, src, n) \
#define _mempcpy_typesafe(dst, src, n, sz) \
({ \
size_t _sz_; \
assert_se(MUL_SAFE(&_sz_, sizeof((dst)[0]), n)); \
(typeof((dst)[0])*) mempcpy_safe(dst, src, _sz_); \
size_t sz; \
assert_se(MUL_SAFE(&sz, sizeof((dst)[0]), n)); \
(typeof((dst)[0])*) mempcpy_safe(dst, src, sz); \
})
#define mempcpy_typesafe(dst, src, n) \
_mempcpy_typesafe(dst, src, n, UNIQ_T(sz, UNIQ))
/* Normal memcmp() requires s1 and s2 to be nonnull. We do nothing if n is 0. */
static inline int memcmp_safe(const void *s1, const void *s2, size_t n) {
if (n == 0)
+20 -12
View File
@@ -236,8 +236,7 @@ static int create_edit_temp_file(EditFile *e, const char *contents, size_t conte
}
static int run_editor_child(const EditFileContext *context) {
_cleanup_strv_free_ char **args = NULL;
const char *editor;
_cleanup_strv_free_ char **args = NULL, **editor = NULL;
int r;
assert(context);
@@ -247,15 +246,14 @@ static int run_editor_child(const EditFileContext *context) {
* If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present, we try to execute
* well known editors. */
FOREACH_STRING(e, "SYSTEMD_EDITOR", "EDITOR", "VISUAL") {
editor = empty_to_null(getenv(e));
if (editor)
break;
}
const char *m = empty_to_null(getenv(e));
if (m) {
editor = strv_split(m, WHITESPACE);
if (!editor)
return log_oom();
if (editor) {
args = strv_split(editor, WHITESPACE);
if (!args)
return log_oom();
break;
}
}
if (context->n_files == 1 && context->files[0].line > 1) {
@@ -271,8 +269,18 @@ static int run_editor_child(const EditFileContext *context) {
return log_oom();
}
if (editor)
execvp(args[0], (char* const*) args);
size_t editor_n = strv_length(editor);
if (editor_n > 0) {
/* Strings are owned by 'editor' and 'args' */
_cleanup_free_ char **cmdline = new(char*, editor_n + strv_length(args) + 1);
if (!cmdline)
return log_oom();
*mempcpy_typesafe(mempcpy_typesafe(cmdline, editor, editor_n), args, strv_length(args)) = NULL;
execvp(cmdline[0], cmdline);
log_warning_errno(errno, "Specified editor '%s' not available, trying fallbacks: %m", editor[0]);
}
bool prepended = false;
FOREACH_STRING(name, "editor", "nano", "vim", "vi") {