This is an automated email from the git hooks/post-receive script.

guillem pushed a commit to branch main
in repository dpkg.

View the commit online:
https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=a47530f1649b81d9feb85fefff1e96ee468bd768

commit a47530f1649b81d9feb85fefff1e96ee468bd768
Author: Guillem Jover <[email protected]>
AuthorDate: Sat Apr 20 02:06:05 2024 +0200

    libdpkg: Add new file_realpath() function
    
    This function wraps the system realpath(3) function and handles whether
    it supports the POSIX.1-2008 semantics where passing a NULL argument for
    the resolved pathname makes the function allocate the necessary memory.
    
    We key this legacy fallback on whether PATH_MAX is defined, as the
    systems that might not have the required semantics do define that macro,
    even if POSIX specifies that defining it is optional.
---
 lib/dpkg/file.c      | 40 ++++++++++++++++++++++++++++++++++++++++
 lib/dpkg/file.h      |  3 +++
 lib/dpkg/libdpkg.map |  1 +
 lib/dpkg/t/t-file.c  | 21 ++++++++++++++++++++-
 4 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/lib/dpkg/file.c b/lib/dpkg/file.c
index f664feb94..8415572d5 100644
--- a/lib/dpkg/file.c
+++ b/lib/dpkg/file.c
@@ -27,6 +27,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <stdlib.h>
 #include <unistd.h>
 
 #include <dpkg/dpkg.h>
@@ -51,6 +52,45 @@ file_getcwd(struct varbuf *cwd)
        varbuf_trunc(cwd, strlen(cwd->buf));
 }
 
+/*
+ * Handle pre-POSIX-1.2008 realpath() semantics, by using a fixed size buffer
+ * based on PATH_MAX, which we expect to be defined on the systems that have
+ * no proper behavior for this function.
+ */
+#ifdef PATH_MAX
+static char *
+file_realpath_legacy(const char *pathname)
+{
+       char resolved_path_buf[PATH_MAX];
+       char *resolved_path;
+
+       resolved_path = realpath(pathname, resolved_path_buf);
+       if (resolved_path == NULL && errno != ENOENT)
+               ohshite(_("cannot canonicalize pathname %s"), pathname);
+
+       if (resolved_path)
+               return m_strdup(resolved_path);
+       return NULL;
+}
+#endif
+
+char *
+file_realpath(const char *pathname)
+{
+       char *resolved_path;
+
+       resolved_path = realpath(pathname, NULL);
+       if (resolved_path == NULL && errno != ENOENT) {
+#ifdef PATH_MAX
+               if (errno == EINVAL)
+                       return file_realpath_legacy(pathname);
+#endif
+               ohshite(_("cannot canonicalize pathname %s"), pathname);
+       }
+
+       return resolved_path;
+}
+
 /**
  * Read the symlink content into a varbuf.
  *
diff --git a/lib/dpkg/file.h b/lib/dpkg/file.h
index f5bc50d1a..7f7b8530f 100644
--- a/lib/dpkg/file.h
+++ b/lib/dpkg/file.h
@@ -51,6 +51,9 @@ struct file_stat {
 void
 file_getcwd(struct varbuf *cwd);
 
+char *
+file_realpath(const char *pathname);
+
 ssize_t
 file_readlink(const char *slink, struct varbuf *content, size_t content_len);
 
diff --git a/lib/dpkg/libdpkg.map b/lib/dpkg/libdpkg.map
index 6185377ed..8e0b9c0ab 100644
--- a/lib/dpkg/libdpkg.map
+++ b/lib/dpkg/libdpkg.map
@@ -174,6 +174,7 @@ LIBDPKG_PRIVATE {
        treewalk;
 
        file_getcwd;
+       file_realpath;
        file_readlink;
        file_is_exec;
        file_copy_perms;
diff --git a/lib/dpkg/t/t-file.c b/lib/dpkg/t/t-file.c
index 16114f061..ccaecbb7a 100644
--- a/lib/dpkg/t/t-file.c
+++ b/lib/dpkg/t/t-file.c
@@ -53,6 +53,24 @@ test_file_getcwd(void)
        varbuf_destroy(&cwd);
 }
 
+static void
+test_file_realpath(void)
+{
+       char *path;
+
+       path = file_realpath("/");
+       test_str(path, ==, "/");
+       free(path);
+
+       path = file_realpath("///");
+       test_str(path, ==, "/");
+       free(path);
+
+       path = file_realpath("//./..///../././..///..");
+       test_str(path, ==, "/");
+       free(path);
+}
+
 static void
 test_file_slurp(void)
 {
@@ -114,8 +132,9 @@ test_file_slurp(void)
 
 TEST_ENTRY(test)
 {
-       test_plan(33);
+       test_plan(36);
 
        test_file_getcwd();
+       test_file_realpath();
        test_file_slurp();
 }

-- 
Dpkg.Org's dpkg

Reply via email to