Generate digest lists before calling genCpioAndHeader

This commit is contained in:
nettingsisyphus 2021-02-27 10:48:58 +08:00
parent 3289ad29da
commit 25dc02de40
2 changed files with 265 additions and 1 deletions

View File

@ -0,0 +1,256 @@
From 6b50298b38da203d4402855bf0caea61bcc5e8d6 Mon Sep 17 00:00:00 2001
From: Roberto Sassu <roberto.sassu@huawei.com>
Date: Wed, 12 Aug 2020 18:23:42 +0200
Subject: [PATCH] Generate digest lists before calling genCpioListAndHeader()
---
build/files.c | 184 ++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 148 insertions(+), 36 deletions(-)
diff --git a/build/files.c b/build/files.c
index ab6938d8c..454ce23bf 100644
--- a/build/files.c
+++ b/build/files.c
@@ -987,19 +987,149 @@ static int seenHardLink(FileRecords files, FileListRec flp, rpm_ino_t *fileid)
* @param pkg (sub) package
* @param isSrc pass 1 for source packages 0 otherwise
*/
-static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
+static void genDigestListInput(FileList fl, Package pkg, int isSrc)
{
FileListRec flp;
char buf[BUFSIZ];
char file_info[BUFSIZ];
char file_digest[128 * 2 + 1];
+ int i;
+ uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo;
+ Header h = pkg->header; /* just a shortcut */
+
+ /*
+ * See if non-md5 file digest algorithm is requested. If not
+ * specified, quietly assume md5. Otherwise check if supported type.
+ */
+ digestalgo = rpmExpandNumeric(isSrc ? "%{_source_filedigest_algorithm}" :
+ "%{_binary_filedigest_algorithm}");
+ if (digestalgo == 0) {
+ digestalgo = defaultalgo;
+ }
+
+ if (rpmDigestLength(digestalgo) == 0) {
+ rpmlog(RPMLOG_WARNING,
+ _("Unknown file digest algorithm %u, falling back to MD5\n"),
+ digestalgo);
+ digestalgo = defaultalgo;
+ }
+
+ /* Sort the big list */
+ if (fl->files.recs) {
+ qsort(fl->files.recs, fl->files.used,
+ sizeof(*(fl->files.recs)), compareFileListRecs);
+ }
+
+ /* Generate the header. */
+ for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) {
+ /* Merge duplicate entries. */
+ while (i < (fl->files.used - 1) &&
+ rstreq(flp->cpioPath, flp[1].cpioPath)) {
+
+ /* Two entries for the same file found, merge the entries. */
+ /* Note that an %exclude is a duplication of a file reference */
+
+ /* file flags */
+ flp[1].flags |= flp->flags;
+
+ if (!(flp[1].flags & RPMFILE_EXCLUDE))
+ rpmlog(RPMLOG_WARNING, _("File listed twice: %s\n"),
+ flp->cpioPath);
+
+ /* file mode */
+ if (S_ISDIR(flp->fl_mode)) {
+ if ((flp[1].specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)) <
+ (flp->specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)))
+ flp[1].fl_mode = flp->fl_mode;
+ } else {
+ if ((flp[1].specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)) <
+ (flp->specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)))
+ flp[1].fl_mode = flp->fl_mode;
+ }
+
+ /* uid */
+ if ((flp[1].specdFlags & (SPECD_UID | SPECD_DEFUID)) <
+ (flp->specdFlags & (SPECD_UID | SPECD_DEFUID)))
+ {
+ flp[1].fl_uid = flp->fl_uid;
+ flp[1].uname = flp->uname;
+ }
+
+ /* gid */
+ if ((flp[1].specdFlags & (SPECD_GID | SPECD_DEFGID)) <
+ (flp->specdFlags & (SPECD_GID | SPECD_DEFGID)))
+ {
+ flp[1].fl_gid = flp->fl_gid;
+ flp[1].gname = flp->gname;
+ }
+
+ /* verify flags */
+ if ((flp[1].specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)) <
+ (flp->specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)))
+ flp[1].verifyFlags = flp->verifyFlags;
+
+ /* XXX to-do: language */
+
+ flp++; i++;
+ }
+
+ /* Skip files that were marked with %exclude. */
+ if (flp->flags & RPMFILE_EXCLUDE)
+ {
+ argvAdd(&pkg->fileExcludeList, flp->cpioPath);
+ continue;
+ }
+
+ buf[0] = '\0';
+ if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST))
+ (void) rpmDoDigest(digestalgo, flp->diskPath, 1,
+ (unsigned char *)buf);
+ headerPutString(h, RPMTAG_FILEDIGESTS, buf);
+ snprintf(file_digest, sizeof(file_digest), "%s", buf);
+
+ if (check_fileList_bin_pkg && S_ISREG(flp->fl_mode) &&
+ !(flp->flags & RPMFILE_GHOST)) {
+ appendStringBuf(check_fileList_bin_pkg, "path=");
+ appendStringBuf(check_fileList_bin_pkg, flp->diskPath);
+ snprintf(file_info, sizeof(file_info),
+ "|digestalgopgp=%d|digest=%s|mode=%d"
+ "|uname=%s|gname=%s|caps=%s\n",
+ digestalgo, file_digest, flp->fl_mode,
+ rpmstrPoolStr(fl->pool, flp->uname),
+ rpmstrPoolStr(fl->pool, flp->gname), flp->caps &&
+ strlen(flp->caps) ? flp->caps : "");
+ appendStringBuf(check_fileList_bin_pkg, file_info);
+ }
+ }
+
+ if (genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0)
+ fl->processingFailed = 1;
+}
+
+/**
+ * Add file entries to header.
+ * @todo Should directories have %doc/%config attributes? (#14531)
+ * @todo Remove RPMTAG_OLDFILENAMES, add dirname/basename instead.
+ * @param fl package file tree walk data
+ * @param pkg (sub) package
+ * @param isSrc pass 1 for source packages 0 otherwise
+ */
+static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
+{
+ FileListRec flp;
+ char buf[BUFSIZ];
int i, npaths = 0;
uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo;
rpm_loff_t totalFileSize = 0;
Header h = pkg->header; /* just a shortcut */
- int override_date = 0, processed = 0;
+ int override_date = 0;
time_t source_date_epoch;
char *srcdate = getenv("SOURCE_DATE_EPOCH");
+ struct rpmtd_s oldfiledigests;
+
+ headerGet(h, RPMTAG_FILEDIGESTS, &oldfiledigests, HEADERGET_ALLOC);
+ headerDel(h, RPMTAG_FILEDIGESTS);
+ rpmtdInit(&oldfiledigests);
/* Limit the maximum date to SOURCE_DATE_EPOCH if defined
* similar to the tar --clamp-mtime option
@@ -1067,9 +1197,8 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc)
pkg->dpaths = xmalloc((fl->files.used + 1) * sizeof(*pkg->dpaths));
-process_files:
/* Generate the header. */
- for (i = processed, flp = fl->files.recs + processed; i < fl->files.used; i++, flp++) {
+ for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) {
rpm_ino_t fileid = flp - fl->files.recs;
/* Merge duplicate entries. */
@@ -1194,13 +1323,17 @@ process_files:
if (fl->haveCaps) {
headerPutString(h, RPMTAG_FILECAPS, flp->caps);
}
-
+
buf[0] = '\0';
- if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST))
- (void) rpmDoDigest(digestalgo, flp->diskPath, 1,
- (unsigned char *)buf);
- headerPutString(h, RPMTAG_FILEDIGESTS, buf);
- snprintf(file_digest, sizeof(file_digest), "%s", buf);
+ if (strstr(flp->diskPath, DIGEST_LIST_DIR) || !oldfiledigests.count) {
+ if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST))
+ (void) rpmDoDigest(digestalgo, flp->diskPath, 1,
+ (unsigned char *)buf);
+ headerPutString(h, RPMTAG_FILEDIGESTS, buf);
+ } else {
+ headerPutString(h, RPMTAG_FILEDIGESTS,
+ rpmtdNextString(&oldfiledigests));
+ }
buf[0] = '\0';
if (S_ISLNK(flp->fl_mode)) {
@@ -1241,33 +1374,7 @@ process_files:
flp->flags &= PARSEATTR_MASK;
headerPutUint32(h, RPMTAG_FILEFLAGS, &(flp->flags) ,1);
-
- if (!processed && check_fileList_bin_pkg && S_ISREG(flp->fl_mode) &&
- !(flp->flags & RPMFILE_GHOST)) {
- appendStringBuf(check_fileList_bin_pkg, "path=");
- appendStringBuf(check_fileList_bin_pkg, flp->diskPath);
- snprintf(file_info, sizeof(file_info),
- "|digestalgopgp=%d|digest=%s|mode=%d"
- "|uname=%s|gname=%s|caps=%s\n",
- digestalgo, file_digest, flp->fl_mode,
- rpmstrPoolStr(fl->pool, flp->uname),
- rpmstrPoolStr(fl->pool, flp->gname), flp->caps &&
- strlen(flp->caps) ? flp->caps : "");
- appendStringBuf(check_fileList_bin_pkg, file_info);
- }
- }
-
- if (!processed) {
- if (genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0) {
- fl->processingFailed = 1;
- } else if (i < fl->files.used) {
- pkg->dpaths = xrealloc(pkg->dpaths,
- (fl->files.used + 1) * sizeof(*pkg->dpaths));
- processed = i;
- goto process_files;
- }
}
-
pkg->dpaths[npaths] = NULL;
if (totalFileSize < UINT32_MAX) {
@@ -1306,6 +1413,7 @@ process_files:
/* Binary packages with dirNames cannot be installed by legacy rpm. */
(void) rpmlibNeedsFeature(pkg, "CompressedFileNames", "3.0.4-1");
}
+ rpmtdFreeData(&oldfiledigests);
}
static FileRecords FileRecordsFree(FileRecords files)
@@ -2776,6 +2884,10 @@ static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
if (checkHardLinks(&fl.files))
(void) rpmlibNeedsFeature(pkg, "PartialHardlinkSets", "4.0.4-1");
+ genDigestListInput(&fl, pkg, 0);
+ if (fl.processingFailed)
+ goto exit;
+
genCpioListAndHeader(&fl, pkg, 0);
exit:
--
2.27.GIT

View File

@ -1,6 +1,6 @@
Name: rpm
Version: 4.15.1
Release: 20
Release: 21
Summary: RPM Package Manager
License: GPLv2+
URL: http://www.rpm.org/
@ -78,6 +78,8 @@ Patch66: backport-Always-open-and-initialize-the-entire-database-at-on.patch
Patch67: backport-Stop-on-first-failure-when-trying-to-open-a-database.patch
Patch68: backport-Only-attempt-loading-the-keyring-once-the-rpmdb-is-o.patch
Patch69: Generate-digest-lists-before-calling-genCpioAndHeader.patch
BuildRequires: gcc autoconf automake libtool make gawk popt-devel openssl-devel readline-devel
BuildRequires: zlib-devel libzstd-devel xz-devel bzip2-devel libarchive-devel ima-evm-utils-devel
BuildRequires: dbus-devel fakechroot elfutils-devel elfutils-libelf-devel ima-evm-utils
@ -344,6 +346,12 @@ make check || (cat tests/rpmtests.log; exit 0)
%{_mandir}/man1/gendiff.1*
%changelog
* Sat Feb 27 2021 Anakin Zhang <benjamin93@163.com> - 4.15.1-21
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:reorder digest lists to fix anaconda build failure
* Tue Jan 12 2021 panxiaohe <panxiaohe@huawei.com> - 4.15.1-20
- Type:enhancement
- ID:NA