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