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=779bb95d52ac54bc7c431663de55b8ebcdb4e352

commit 779bb95d52ac54bc7c431663de55b8ebcdb4e352
Author: Guillem Jover <guil...@debian.org>
AuthorDate: Tue Nov 21 01:43:18 2023 +0100

    libdpkg: Refactor file_readlink() function
    
    This function will read a symlink target into a varbuf.
---
 lib/dpkg/file.c      | 19 +++++++++++++++++++
 lib/dpkg/file.h      |  3 +++
 lib/dpkg/libdpkg.map |  1 +
 src/main/archives.c  | 21 +++++++--------------
 src/main/configure.c |  6 +-----
 5 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/lib/dpkg/file.c b/lib/dpkg/file.c
index 4d02520d8..0da51d628 100644
--- a/lib/dpkg/file.c
+++ b/lib/dpkg/file.c
@@ -36,6 +36,25 @@
 #include <dpkg/buffer.h>
 #include <dpkg/file.h>
 
+/**
+ * Read the symlink content into a varbuf.
+ *
+ */
+ssize_t
+file_readlink(const char *slink, struct varbuf *content, size_t content_len)
+{
+       ssize_t linksize;
+
+       varbuf_reset(content);
+       varbuf_grow(content, content_len + 1);
+
+       linksize = readlink(slink, content->buf, content->size);
+       varbuf_trunc(content, linksize);
+       varbuf_end_str(content);
+
+       return linksize;
+}
+
 /**
  * Check whether a filename is executable.
  *
diff --git a/lib/dpkg/file.h b/lib/dpkg/file.h
index 0136f6901..c1c25fa9d 100644
--- a/lib/dpkg/file.h
+++ b/lib/dpkg/file.h
@@ -48,6 +48,9 @@ struct file_stat {
        char *gname;
 };
 
+ssize_t
+file_readlink(const char *slink, struct varbuf *content, size_t content_len);
+
 bool file_is_exec(const char *filename);
 
 void file_copy_perms(const char *src, const char *dst);
diff --git a/lib/dpkg/libdpkg.map b/lib/dpkg/libdpkg.map
index e0b11520d..b7bedeffd 100644
--- a/lib/dpkg/libdpkg.map
+++ b/lib/dpkg/libdpkg.map
@@ -161,6 +161,7 @@ LIBDPKG_PRIVATE {
        treewalk_close;
        treewalk;
 
+       file_readlink;
        file_is_exec;
        file_copy_perms;
        file_show;
diff --git a/src/main/archives.c b/src/main/archives.c
index 0f3549b45..b6ca2880d 100644
--- a/src/main/archives.c
+++ b/src/main/archives.c
@@ -534,8 +534,9 @@ tarobject_matches(struct tarcontext *tc,
                   const char *fn_new, struct tar_entry *te,
                   struct fsys_namenode *namenode)
 {
-  char *linkname;
+  struct varbuf linkname = VARBUF_INIT;
   ssize_t linksize;
+  bool linkmatch;
 
   debug(dbg_eachfiledetail, "tarobject matches on-disk object?");
 
@@ -548,8 +549,7 @@ tarobject_matches(struct tarcontext *tc,
      * remain real symlinks where we can compare the target. */
     if (!S_ISLNK(stab->st_mode))
       break;
-    linkname = m_malloc(stab->st_size + 1);
-    linksize = readlink(fn_old, linkname, stab->st_size + 1);
+    linksize = file_readlink(fn_old, &linkname, stab->st_size);
     if (linksize < 0)
       ohshite(_("unable to read link '%.255s'"), fn_old);
     else if (linksize > stab->st_size)
@@ -558,13 +558,10 @@ tarobject_matches(struct tarcontext *tc,
     else if (linksize < stab->st_size)
       warning(_("symbolic link '%.250s' size has changed from %jd to %zd"),
              fn_old, (intmax_t)stab->st_size, linksize);
-    linkname[linksize] = '\0';
-    if (strcmp(linkname, te->linkname) == 0) {
-      free(linkname);
+    linkmatch = strcmp(linkname.buf, te->linkname) == 0;
+    varbuf_destroy(&linkname);
+    if (linkmatch)
       return;
-    } else {
-      free(linkname);
-    }
     break;
   case TAR_FILETYPE_CHARDEV:
     if (S_ISCHR(stab->st_mode) && stab->st_rdev == te->dev)
@@ -1050,9 +1047,7 @@ tarobject(struct tar_archive *tar, struct tar_entry *ti)
       /* We can't make a symlink with two hardlinks, so we'll have to
        * copy it. (Pretend that making a copy of a symlink is the same
        * as linking to it.) */
-      varbuf_reset(&symlinkfn);
-      varbuf_grow(&symlinkfn, stab.st_size + 1);
-      linksize = readlink(fnamevb.buf, symlinkfn.buf, symlinkfn.size);
+      linksize = file_readlink(fnamevb.buf, &symlinkfn, stab.st_size);
       if (linksize < 0)
         ohshite(_("unable to read link '%.255s'"), ti->name);
       else if (linksize > stab.st_size)
@@ -1061,8 +1056,6 @@ tarobject(struct tar_archive *tar, struct tar_entry *ti)
       else if (linksize < stab.st_size)
         warning(_("symbolic link '%.250s' size has changed from %jd to %zd"),
                fnamevb.buf, (intmax_t)stab.st_size, linksize);
-      varbuf_trunc(&symlinkfn, linksize);
-      varbuf_end_str(&symlinkfn);
       if (symlink(symlinkfn.buf,fnametmpvb.buf))
         ohshite(_("unable to make backup symlink for '%.255s'"), ti->name);
       rc = lchown(fnametmpvb.buf, stab.st_uid, stab.st_gid);
diff --git a/src/main/configure.c b/src/main/configure.c
index 2b48ce7bb..f2c9227ad 100644
--- a/src/main/configure.c
+++ b/src/main/configure.c
@@ -735,9 +735,7 @@ conffderef(struct pkginfo *pkg, struct varbuf *result, 
const char *in)
                                return -1;
                        }
 
-                       varbuf_reset(&target);
-                       varbuf_grow(&target, stab.st_size + 1);
-                       linksize = readlink(result->buf, target.buf, 
target.size);
+                       linksize = file_readlink(result->buf, &target, 
stab.st_size);
                        if (linksize < 0) {
                                warning(_("%s: unable to readlink conffile 
'%s'\n"
                                          " (= '%s'): %s"),
@@ -754,8 +752,6 @@ conffderef(struct pkginfo *pkg, struct varbuf *result, 
const char *in)
                                if (linksize > stab.st_size)
                                        return -1;
                        }
-                       varbuf_trunc(&target, linksize);
-                       varbuf_end_str(&target);
 
                        debug(dbg_conffdetail,
                              "conffderef readlink gave %zd, '%s'",

-- 
Dpkg.Org's dpkg

Reply via email to