Hi, Last week I discovered an issue with dpkg-query -S and the usrmerge with the phpmyadmin docker container; I proposed a fix for the phpmyadmin container and it turned out a lot of other containers have the same pattern and were likewise affected by this (see https://github.com/docker-library/official-images/pull/14960)
The rootcause of the issue is that dpkg-query -S only supports searching on the paths that listed in the package; it does not know/care about symlinks; so with the usrmerge /lib and /usr/lib are now the same; but some libs install to /lib while others install to /usr/lib. This causes issues with scripts that rely on dpkg-query -S to find out the package an installed library belongs to. Especially if you try to find the package of a dependency with ldd and dpkg-query -S (as ldd will prefer the /lib entry it finds) I proposed a workaround/fix for this in https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=848622#27 and I now have a proof of concept implementation of this. The idea is simple: if you specify you want to match on realpath (for now by prefixing the path with "realpath:"); it will search for files matching the basename of the given path and does an extra check to only return matches where the realpath of the given path will match the realpath of the partial match it found. This way you minimize the number of realpath calls that need to be done and don't need to hardcode any path mappings into dpkg-query. I don't think this implementation is particularly pretty (especially the "realpath:" prefix to trigger it); but this was the easiest way for me to prototype this. It is meant as a starting point for the conversation if this is something you'd consider supporting in dpkg-query; I am happy to make any changes based on your suggestions. I have attached the patch; but also have a github repo available: https://github.com/ederuiter/dpkg/tree/fix/bug-848622-realpath -- Best regards, Eric de Ruiter
From 224e5bf5345d6fdc2bb6d865c44a75ac92ae462e Mon Sep 17 00:00:00 2001 From: Eric de Ruiter <e...@thisisdevelopment.nl> Date: Sat, 8 Jul 2023 13:06:49 +0200 Subject: [PATCH] [WIP] proof-of-concept implementatin for realpath support in dpkg-query -S (fixes #848622 & #858331) --- src/query/main.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/query/main.c b/src/query/main.c index 24dccc8c4..c7ce60f4a 100644 --- a/src/query/main.c +++ b/src/query/main.c @@ -331,6 +331,43 @@ searchoutput(struct fsys_namenode *namenode) return found + (namenode->divert ? 1 : 0); } +static int +searchfile_realpath(const char *file) +{ + struct fsys_hash_iter *iter; + char *real, *resolved, *namenode_real; + struct varbuf path = VARBUF_INIT; + struct fsys_namenode *namenode; + int found = 0; + + varbuf_reset(&path); + varbuf_add_str(&path, "*/"); + varbuf_add_str(&path, path_basename(file)); + varbuf_end_str(&path); + + real = realpath(file, NULL); + if (real == NULL) { + notice(_("unable to get realpath of %s; results might not be complete"), file); + return found; + } + iter = fsys_hash_iter_new(); + resolved = malloc(PATH_MAX); + while ((namenode = fsys_hash_iter_next(iter)) != NULL) { + if (fnmatch(path.buf,namenode->name,0)) continue; + namenode_real = realpath(namenode->name, resolved); + if (namenode_real == NULL) { + notice(_("unable to get realpath of %s; results might not be complete"), namenode->name); + } + if (strcmp(real, namenode_real) != 0) continue; + found+= searchoutput(namenode); + } + fsys_hash_iter_free(iter); + free(real); + free(resolved); + varbuf_destroy(&path); + return found; +} + static int searchfiles(const char *const *argv) { @@ -350,6 +387,9 @@ searchfiles(const char *const *argv) struct fsys_namenode *namenode; int found = 0; + if (strncmp(thisarg, "realpath:", 9) == 0) { + found += searchfile_realpath(&thisarg[9]); + } else { if (!strchr("*[?/",*thisarg)) { varbuf_reset(&vb); varbuf_add_char(&vb, '*'); @@ -378,6 +418,7 @@ searchfiles(const char *const *argv) } fsys_hash_iter_free(iter); } + } if (!found) { notice(_("no path found matching pattern %s"), thisarg); failures++; -- 2.25.1