From ff139a7eb8dcecf465fe516e6042158ebc355827 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Wed, 3 Apr 2024 01:48:31 +1000 Subject: [PATCH] unlink_file: restore trailing slash on directory before checking mountpoint The dir_is_mountpoint() function has the explicit requirement that the trailing slash of the directory is present. We strip the trailing slash in unlink_file() to handle directories replaced with symlinks, but that then affects the dir_is_mountpoint() check. Add the trailing slash when we have established we are dealing with a directory. Note this may fail in the case of a file managed by pacmane with name length of PATH_MAX that has been replaced by a directory on the file system. Bail on this unlikely scenario. In addtion, be less fancy with adjusting length of the file char array. Signed-off-by: Allan McRae (cherry picked from commit f86c15e7804311df6469e020f07e4bc8b2644bb6) --- lib/libalpm/remove.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index f44eac7f..e7634994 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -451,10 +451,11 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *oldpkg, _alpm_log(handle, ALPM_LOG_DEBUG, "path too long to unlink %s%s\n", handle->root, fileobj->name); return -1; - } else if(file[file_len-1] == '/') { + } else if(file[file_len - 1] == '/') { /* trailing slashes cause errors and confusing messages if the user has * replaced a directory with a symlink */ - file[--file_len] = '\0'; + file[file_len - 1] = '\0'; + file_len--; } if(llstat(file, &buf)) { @@ -463,9 +464,22 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *oldpkg, } if(S_ISDIR(buf.st_mode)) { - ssize_t files = _alpm_files_in_directory(handle, file, 0); - /* if we have files, no need to remove the directory */ + ssize_t files; + + /* restore/add trailing slash */ + if(file_len < PATH_MAX - 1) { + file[file_len] = '/'; + file_len++; + file[file_len] = '\0'; + } else { + _alpm_log(handle, ALPM_LOG_DEBUG, "path too long to unlink %s%s\n", + handle->root, fileobj->name); + return -1; + } + + files = _alpm_files_in_directory(handle, file, 0); if(files > 0) { + /* if we have files, no need to remove the directory */ _alpm_log(handle, ALPM_LOG_DEBUG, "keeping directory %s (contains files)\n", file); } else if(files < 0) {