summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-10-13 20:42:58 -0400
committerTavian Barnes <tavianator@tavianator.com>2024-10-13 21:02:01 -0400
commitb89f22cbf250958a802915eb7b6bf0e5f38376ca (patch)
tree3eb0b29016e9807941ec9672fbd32e333982725d /src
parent295ae76099e51ba579a6877af920c1f02f52cf7c (diff)
downloadbfs-b89f22cbf250958a802915eb7b6bf0e5f38376ca.tar.xz
color: Fix an infinite loop colorizing some invalid paths
Previously, given $ touch file $ ln -s file/file notdir $ bfs notdir/file bfs would loop forever when printing the error message, since it expected stripping the trailing slash from "notdir/" to fix the ENOTDIR error, but the broken symlink still gave the same error. Fixes: b4c3201 ("color: Only highlight the trailing slash on ENOTDIR")
Diffstat (limited to 'src')
-rw-r--r--src/color.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/src/color.c b/src/color.c
index d1b36f9..a701813 100644
--- a/src/color.c
+++ b/src/color.c
@@ -998,22 +998,25 @@ static ssize_t first_broken_offset(const char *path, const struct BFTW *ftwbuf,
goto out;
}
+ size_t len = dstrlen(at_path);
while (ret > 0) {
+ dstresize(&at_path, len);
if (xfaccessat(at_fd, at_path, F_OK) == 0) {
break;
}
- size_t len = dstrlen(at_path);
- while (ret && at_path[len - 1] == '/') {
- --len, --ret;
- }
- if (errno != ENOTDIR) {
- while (ret && at_path[len - 1] != '/') {
+ // Try without trailing slashes, to distinguish "notdir/" from "notdir"
+ if (at_path[len - 1] == '/') {
+ do {
--len, --ret;
- }
+ } while (ret > 0 && at_path[len - 1] == '/');
+ continue;
}
- dstresize(&at_path, len);
+ // Remove the last component and try again
+ do {
+ --len, --ret;
+ } while (ret > 0 && at_path[len - 1] != '/');
}
out_path: