commit fcb4dcfe38932c8c4550b3f6b007d467ee5b7042
parent bab18b62da4d443665698fa3e8bc0e28fc9bbfe0
Author: lumidify <nobody@lumidify.org>
Date: Sat, 4 Nov 2023 21:18:29 +0100
Don't attempt to open non-regular files
Diffstat:
M | ledit.c | | | 50 | +++++++++++++++++++++++++++++++++++++++++--------- |
1 file changed, 41 insertions(+), 9 deletions(-)
diff --git a/ledit.c b/ledit.c
@@ -600,42 +600,59 @@ setup(int argc, char *argv[]) {
clock_gettime(CLOCK_MONOTONIC, &last);
#endif
+ /* FIXME: Technically, there's a race condition between checking stat and actually
+ opening the files. This is mainly important when checking if the file is not a regular
+ file because that is not an error for functions like fopen, so bad things will happen
+ if a non-regular file (e.g. a directory) is given to one of the file reading
+ functions. However, I don't know of any portable way to have one of the open functions
+ check that, so this is the best I can do. */
char *stat_errstr = NULL, *load_errstr = NULL, *load_default_errstr = NULL;
char *cfgfile = NULL;
if (!opt_filename) {
uid_t uid = getuid();
struct passwd *pw = getpwuid(uid);
if (!pw) {
- fprintf(stderr, "Unable to determine home directory\n");
+ stat_errstr = ledit_strdup("Unable to determine home directory to load default configuration file.");
} else {
cfgfile = ledit_strcat(pw->pw_dir, "/.leditrc");
struct stat cfgst;
- /* FIXME: maybe only when ENOENT? */
if (stat(cfgfile, &cfgst)) {
free(cfgfile);
cfgfile = NULL;
+ if (errno != ENOENT) {
+ stat_errstr = print_fmt("Unable to load configuration file '~/.leditrc': %s", strerror(errno));
+ }
+ } else if (!S_ISREG(cfgst.st_mode)) {
+ stat_errstr = ledit_strdup("Unable to load configuration file '~/.leditrc': Is not a regular file.");
+ free(cfgfile);
+ cfgfile = NULL;
}
}
} else {
struct stat cfgst;
if (stat(opt_filename, &cfgst)) {
- stat_errstr = print_fmt("Unable to load configuration file '%s'", opt_filename);
- fprintf(stderr, "%s\n", stat_errstr);
+ stat_errstr = print_fmt("Unable to load configuration file '%s': %s", opt_filename, strerror(errno));
+ } else if (!S_ISREG(cfgst.st_mode)) {
+ stat_errstr = print_fmt("Unable to load configuration file '%s': Is not a regular file.", opt_filename);
} else {
cfgfile = ledit_strdup(opt_filename);
}
}
+ if (stat_errstr)
+ fprintf(stderr, "%s\n", stat_errstr);
if (config_loadfile(&common, cfgfile, &load_errstr)) {
fprintf(stderr, "%s\n", load_errstr);
+ fprintf(stderr, "Unable to load configuration '%s'\n", cfgfile ? cfgfile : "default config");
int failure = 1;
if (cfgfile) {
/* retry with default config */
failure = config_loadfile(&common, NULL, &load_default_errstr);
}
if (failure) {
- fprintf(stderr, "Unable to load configuration: %s\n", load_errstr);
- if (load_default_errstr)
- fprintf(stderr, "Also unable to load default configuration: %s\n", load_default_errstr);
+ if (load_default_errstr) {
+ fprintf(stderr, "%s\n", load_default_errstr);
+ fprintf(stderr, "Also unable to load default configuration\n");
+ }
free(stat_errstr);
free(load_errstr);
free(load_default_errstr);
@@ -683,6 +700,8 @@ setup(int argc, char *argv[]) {
int readonly = 0;
int error = 0;
/* FIXME: maybe copy vi and open file in /tmp by default? */
+ /* FIXME: when other methods of opening files (:r, etc.) are supported,
+ all this checking needs to be moved to a place where it can be reused */
if (stat(argv[0], &sb)) {
if (errno == ENOENT) {
/* note that there may still be a failure
@@ -690,18 +709,32 @@ setup(int argc, char *argv[]) {
the path does not exist */
newfile = 1;
} else {
+ fprintf(
+ stderr, "Error opening file '%s': %s\n",
+ argv[0], strerror(errno)
+ );
window_show_message_fmt(
view->window, "Error opening file '%s': %s",
argv[0], strerror(errno)
);
error = 1;
}
+ } else if (!S_ISREG(sb.st_mode)) {
+ fprintf(stderr, "Error opening file '%s': Is not a regular file\n", argv[0]);
+ window_show_message_fmt(
+ view->window, "Error opening file '%s': Is not a regular file", argv[0]
+ );
+ error = 1;
}
if (access(argv[0], W_OK)) {
readonly = 1;
}
- if (!newfile) {
+ if (!newfile && !error) {
if (buffer_load_file(buffer, argv[0], 0, &load_err)) {
+ fprintf(
+ stderr, "Error opening file '%s': %s\n",
+ argv[0], load_err
+ );
window_show_message_fmt(
view->window, "Error opening file '%s': %s",
argv[0], load_err
@@ -712,7 +745,6 @@ setup(int argc, char *argv[]) {
}
if (!error) {
buffer->filename = ledit_strdup(argv[0]);
- /* FIXME: show this *in addition* to error */
if (!show_error) {
if (newfile) {
window_show_message_fmt(view->window, "%s: new file", argv[0]);