commit 47367e6f8624effc2735a592094acf41b814f42f
parent fa9721fc35ae7afa230f86ed6fbb10ba6c12a4f1
Author: Wim Dupont <wim@wimdupont.com>
Date: Mon, 6 Apr 2026 18:12:08 +0200
added safety checks
Diffstat:
3 files changed, 49 insertions(+), 20 deletions(-)
diff --git a/Makefile b/Makefile
@@ -5,10 +5,10 @@ SRC = cex.c
OBJ = ${SRC:.c=.o}
MAN1 = ${BIN:=.1}
-${OBJ}: config.h
-
all: ${BIN}
+${OBJ}: config.h
+
LDFLAGS=-lncurses $(LIBGIT2_LDFLAGS)
.c.o:
@@ -23,6 +23,9 @@ config.h:
clean:
rm -f ${BIN} ${OBJ}
+strict: config.h
+ ${CC} -g -c ${STRICTCFLAGS} ${SRC} -o /tmp/${OBJ}
+
install: all
mkdir -p ${DESTDIR}${PREFIX}/bin
cp -f ${BIN} "${DESTDIR}${PREFIX}/bin"
@@ -36,4 +39,4 @@ uninstall:
"${DESTDIR}${PREFIX}/bin/${BIN}"\
"${DESTDIR}${MANPREFIX}/man1/${MAN1}"
-.PHONY: all clean install uninstall
+.PHONY: all clean install strict uninstall
diff --git a/cex.c b/cex.c
@@ -115,7 +115,7 @@ static char *human_readable_bytes(char *buf, intmax_t bytes);
static char *prompt_answer(char *buf, size_t size, const char *question);
static char *cpstr(char *dest, const char *src);
static char *substr(char *buf, const char *haystack, const char *needle, const bool casesens);
-static char *get_file_info(char *buf, const char *filepath);
+static char *get_file_info(char *buf, size_t bufsize, const char *filepath);
static char *get_fullpath(char *buf, DirWin *dirwin, size_t index);
static char *get_dirname(char *buf, const char *path);
static char *replace_home(char *buf, const char *path);
@@ -564,6 +564,8 @@ set_win_message(DirWin *dirwin, char *message)
void
print_win(DirWin *dirwin)
{
+ const char *curbase;
+
if (dirwin->holdupdate)
return;
@@ -586,11 +588,16 @@ print_win(DirWin *dirwin)
wattroff(dirwin->window, COLOR_PAIR(CHILDWIN_MESSAGE_COLOR));
}
} else if (dirwin->winfiles != NULL) {
+ curbase = strrchr(curwin.path, '/');
+ if (curbase != NULL && curbase != curwin.path)
+ curbase++;
+ else if (curbase == NULL)
+ curbase = curwin.path;
while (!dirwin->usehighlight) {
for (int i = 0; i < dirwin->filecount; ++i) {
memcpy(name, dirwin->winfiles[i].d_name, size);
name[size] = '\0';
- if (strcmp(basename(curwin.path), dirwin->winfiles[i].d_name) == 0) {
+ if (strcmp(curbase, dirwin->winfiles[i].d_name) == 0) {
dirwin->usehighlight = TRUE;
dirwin->highlight = i;
set_startpr(dirwin);
@@ -694,18 +701,23 @@ update_child_win(void)
void
print_top_title(void)
{
- char path[PATH_MAX + sizeof(curwin.path)];
+ char path[PATH_MAX];
move(0, 0);
clrtoeol();
- snprintf(path, sizeof(path), "%s/%s", curwin.path, curwin.winfiles[curwin.highlight].d_name);
+ if (curwin.filecount == 0) {
+ cpstr(path, curwin.path);
+ if (strcmp(path, "/") != 0)
+ strcat(path, "/");
+ } else
+ get_fullpath(path, &curwin, curwin.highlight);
attron(COLOR_PAIR(TOP_TITLE_COLOR));
#if GIT_INFO
truncate_buf_prefix(path, sizeof(path), maxx - strlen(username) - 2 - strlen(gitbranch));
printw("%s:%s", username, path);
attron(COLOR_PAIR(GIT_BRANCH_COLOR));
- printw(gitbranch);
+ printw("%s", gitbranch);
attroff(COLOR_PAIR(GIT_BRANCH_COLOR));
#else
truncate_buf_prefix(path, sizeof(path), maxx - strlen(username) - 2);
@@ -717,11 +729,13 @@ print_top_title(void)
void
print_bot_title(void)
{
- char pathbuf[PATH_MAX], fileinf[maxx];
+ char pathbuf[PATH_MAX], fileinf[maxx + 1];
- get_fullpath(pathbuf, &curwin, curwin.highlight);
- memcpy(fileinf, get_file_info(fileinf, pathbuf), maxx);
- fileinf[maxx] = '\0';
+ if (curwin.filecount == 0)
+ fileinf[0] = '\0';
+ else
+ get_file_info(fileinf, sizeof(fileinf),
+ get_fullpath(pathbuf, &curwin, curwin.highlight));
move(maxy-1, 0);
clrtoeol();
@@ -736,7 +750,7 @@ print_bot_title(void)
}
char *
-get_file_info(char *buf, const char *filepath)
+get_file_info(char *buf, size_t bufsize, const char *filepath)
{
struct stat statbuf;
struct passwd *usr;
@@ -781,7 +795,7 @@ get_file_info(char *buf, const char *filepath)
tm = localtime(&statbuf.st_mtime);
strftime(datestr, sizeof(datestr), nl_langinfo(D_T_FMT), tm);
- sprintf(buf, "%10.10s %s %s %s %s",
+ snprintf(buf, bufsize, "%10.10s %s %s %s %s",
mods,
usr->pw_name,
grp->gr_name,
@@ -1300,9 +1314,11 @@ get_st_mode(DirWin *dirwin, size_t index)
{
struct stat statbuf;
char linkpath[PATH_MAX], abspath[PATH_MAX];
+ char *resolved;
get_fullpath(linkpath, dirwin, index);
- if (lstat(realpath(linkpath, abspath), &statbuf) >= 0)
+ resolved = realpath(linkpath, abspath);
+ if (resolved != NULL && lstat(resolved, &statbuf) >= 0)
return statbuf.st_mode;
return -1;
@@ -1375,9 +1391,12 @@ prompt_answer(char *buf, size_t size, const char *question)
addstr(question);
attroff(COLOR_PAIR(PROMPT_COLOR));
+ if (size == 0)
+ return buf;
+
echo();
curs_set(1);
- getnstr(buf, size);
+ getnstr(buf, (int) size - 1);
noecho();
curs_set(0);
@@ -1387,14 +1406,14 @@ prompt_answer(char *buf, size_t size, const char *question)
bool
prompt_confirm(size_t size, const char *fmt, ...)
{
- char response[1], question[size];
+ char response[2], question[size];
va_list ap;
va_start(ap, fmt);
vsnprintf(question, size, fmt, ap);
va_end(ap);
- prompt_answer(response, 1, question);
+ prompt_answer(response, sizeof(response), question);
return strcasecmp(response, "y") == 0;
}
@@ -1610,7 +1629,8 @@ make_chown(void)
{
struct passwd *usr;
struct group *grp;
- long len = sysconf(_SC_LOGIN_NAME_MAX);
+ long maxlogin = sysconf(_SC_LOGIN_NAME_MAX);
+ size_t len = maxlogin > 0 ? (size_t) maxlogin + 1 : 256;
char owner[len], group[len], *err;
prompt_answer(owner, len, "Owner name? ");
@@ -1633,7 +1653,7 @@ make_chown(void)
switch (errno) {
case EACCES:
case EPERM:
- sudo_chown(owner, group, len);
+ sudo_chown(owner, group, (long) len);
break;
default:
err = "Error during chown: %d.";
@@ -1783,6 +1803,11 @@ substr(char *buf, const char *haystack, const char *needle, const bool casesens)
char *
get_fullpath(char *buf, DirWin *dirwin, size_t index)
{
+ if (dirwin->filecount == 0 || dirwin->winfiles == NULL) {
+ buf[0] = '\0';
+ return buf;
+ }
+
index = MIN(index, dirwin->filecount-1);
index = MAX(index, 0);
diff --git a/config.mk b/config.mk
@@ -4,6 +4,7 @@ VERSION = 0.1
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\"
CFLAGS = -std=c99 -pedantic -Wall -Wextra -I/usr/local/include ${CPPFLAGS}
+STRICTCFLAGS = ${CFLAGS} -Wshadow -Wconversion -Wformat=2
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man