diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2024-10-13 20:42:58 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2024-10-13 21:02:01 -0400 |
commit | b89f22cbf250958a802915eb7b6bf0e5f38376ca (patch) | |
tree | 3eb0b29016e9807941ec9672fbd32e333982725d | |
parent | 295ae76099e51ba579a6877af920c1f02f52cf7c (diff) | |
download | bfs-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")
-rw-r--r-- | src/color.c | 19 | ||||
-rw-r--r-- | tests/bfs/color_notdir_slash_error.out | 0 | ||||
-rw-r--r-- | tests/bfs/color_notdir_slash_error.sh | 2 |
3 files changed, 13 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: diff --git a/tests/bfs/color_notdir_slash_error.out b/tests/bfs/color_notdir_slash_error.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/bfs/color_notdir_slash_error.out diff --git a/tests/bfs/color_notdir_slash_error.sh b/tests/bfs/color_notdir_slash_error.sh new file mode 100644 index 0000000..ca26d50 --- /dev/null +++ b/tests/bfs/color_notdir_slash_error.sh @@ -0,0 +1,2 @@ +# Regression test: infinite loop printing the error message for .../notdir/nowhere +! bfs_diff -color links/notdir/nowhere |