* [PATCH v8 7/9] rpm: 4.20.1 -> 6.0.1
2026-03-12 14:09 [PATCH v8 0/9] rpm: 4.20.1 -> 6.0.1 liezhi.yang
` (5 preceding siblings ...)
2026-03-12 14:09 ` [PATCH v8 6/9] target-sdk-provides-dummy: Add pkg-config to DUMMYPROVIDES liezhi.yang
@ 2026-03-12 14:09 ` liezhi.yang
2026-03-12 14:09 ` [PATCH v8 8/9] libarchive: upgrade 3.8.5 -> 3.8.6 liezhi.yang
` (2 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: liezhi.yang @ 2026-03-12 14:09 UTC (permalink / raw)
To: openembedded-core
Cc: alex.kanavin, mathieu.dubois-briand, mattware, esparlin,
peter.marko
From: Robert Yang <liezhi.yang@windriver.com>
* Add a tag to SRC_URI so that there will be errors when only change the
filename during upgrade it, as suggested by Alexander.
* Rebase the following patch:
- 0001-Add-a-color-setting-for-mips64_n32-binaries.patch
- 0001-Do-not-add-an-unsatisfiable-dependency-when-building.patch
- 0001-Do-not-read-config-files-from-HOME.patch
- 0001-Do-not-reset-the-PATH-environment-variable-before-ru.patch
- 0001-When-cross-installing-execute-package-scriptlets-wit.patch
- 0001-build-pack.c-do-not-insert-payloadflags-into-.rpm-me.patch
- 0001-lib-transaction.c-fix-file-conflicts-for-MIPS64-N32.patch
- 0002-Add-support-for-prefixing-etc-from-RPM_ETCCONFIGDIR-.patch
- 0002-rpmio-rpmglob.c-avoid-using-GLOB_BRACE-if-undefined-.patch
- 0016-rpmscript.c-change-logging-level-around-scriptlets-t.patch
* Updated 0001-Do-not-hardcode-lib-rpm-as-the-installation-path-for.patch
Remove the changes for macros.in since it doesn't work for rpmbuild, rpmbuild
is like cross build, will define the values in package_rpm.bbclass.
* Remove 0001-CMakeLists.txt-set-libdir-to-CMAKE_INSTALL_FULL_LIBD.patch, there
are no such warnings in rpm 6.0.1.
* Remove backported patch 0001-CMakeLists.txt-Fix-checking-for-CFLAGS.patch
* Add the following patches:
- 0001-tools-elfdeps.cc-Remove-format-module.patch
There is no format until gcc 13.1, so remove the format module to make it
work on hosts such as Ubuntu 22.04.
- 0001-macros.in-Set-_pkgverify_level-to-digest-as-RCPM-4.2.patch
Fixed:
GPG check FAILED
- 0001-scripts-pkgconfigdeps.sh-Use-pkg-config-from-PATH.patch
To fix "bitbake core-image-sato -cpopulate_sdk" error on Ubuntu 24.04 when
pkg-config is installed on host, now the host contamination has been fixed,
and the patch has been submitted to upstream:
https://github.com/rpm-software-management/rpm/pull/4127
* Add scdoc-native to DEPENDS to fix do_configure error for both native and
target:
Could not find SCDOC using the following names: scdoc
Note, both target and native need scdoc-native, it is used for generating the
manual, the man pages in *man/* are scdoc sources
* Add /etc/rpm to nativesdk-rpm to fix:
ERROR: nativesdk-rpm-1_6.0.1-r0 do_package: QA Issue: nativesdk-rpm:
Files/directories were installed but not shipped in any package:
/etc
/etc/rpm
* Add /etc/rpm to nativesdk-rpm to fix:
* Fix build with systemd, the rpm's sysuser creation doesn't work with
cross build, and we don't need rpm to create the users since we have
useradd.bbclass. The fix is:
cmd = cmd + " --define '__sysusers_path %{nil}'"
The error is:
/var/tmp/rpm-tmp.U4iaJX: line 114: tr: command not found
* Make rpmbuild can find the pkgconfig (.pc) files in /usr/share/pkgconfig:
cmd = cmd + " --define '_datadir ${datadir}'"
The error is:
- nothing provides pkgconfig(shared-mime-info) needed by libgdk-pixbuf-2.0-dev-2.44.5-r0.x86_6
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
meta/classes-global/package_rpm.bbclass | 4 ++
...olor-setting-for-mips64_n32-binaries.patch | 21 ++++----
...akeLists.txt-Fix-checking-for-CFLAGS.patch | 46 -----------------
...et-libdir-to-CMAKE_INSTALL_FULL_LIBD.patch | 50 -------------------
...satisfiable-dependency-when-building.patch | 17 ++++---
...lib-rpm-as-the-installation-path-for.patch | 23 +++------
...1-Do-not-read-config-files-from-HOME.patch | 17 ++++---
...-PATH-environment-variable-before-ru.patch | 15 +++---
...lling-execute-package-scriptlets-wit.patch | 11 ++--
...not-insert-payloadflags-into-.rpm-me.patch | 17 ++++---
....c-fix-file-conflicts-for-MIPS64-N32.patch | 17 ++++---
...kgverify_level-to-digest-as-RCPM-4.2.patch | 34 +++++++++++++
...nfigdeps.sh-Use-pkg-config-from-PATH.patch | 42 ++++++++++++++++
...ools-elfdeps.cc-Remove-format-module.patch | 37 ++++++++++++++
...prefixing-etc-from-RPM_ETCCONFIGDIR-.patch | 25 ++++++----
...avoid-using-GLOB_BRACE-if-undefined-.patch | 13 +++--
...ge-logging-level-around-scriptlets-t.patch | 13 ++---
.../rpm/{rpm_4.20.1.bb => rpm_6.0.1.bb} | 15 +++---
18 files changed, 229 insertions(+), 188 deletions(-)
delete mode 100644 meta/recipes-devtools/rpm/files/0001-CMakeLists.txt-Fix-checking-for-CFLAGS.patch
delete mode 100644 meta/recipes-devtools/rpm/files/0001-CMakeLists.txt-set-libdir-to-CMAKE_INSTALL_FULL_LIBD.patch
create mode 100644 meta/recipes-devtools/rpm/files/0001-macros.in-Set-_pkgverify_level-to-digest-as-RCPM-4.2.patch
create mode 100644 meta/recipes-devtools/rpm/files/0001-scripts-pkgconfigdeps.sh-Use-pkg-config-from-PATH.patch
create mode 100644 meta/recipes-devtools/rpm/files/0001-tools-elfdeps.cc-Remove-format-module.patch
rename meta/recipes-devtools/rpm/{rpm_4.20.1.bb => rpm_6.0.1.bb} (94%)
diff --git a/meta/classes-global/package_rpm.bbclass b/meta/classes-global/package_rpm.bbclass
index f4dd779a52..2c2e127abb 100644
--- a/meta/classes-global/package_rpm.bbclass
+++ b/meta/classes-global/package_rpm.bbclass
@@ -622,6 +622,7 @@ python do_package_rpm () {
cmd = cmd + " --define '_topdir " + workdir + "' --define '_rpmdir " + pkgwritedir + "'"
cmd = cmd + " --define '_lib ${BASELIB}'"
cmd = cmd + " --define '_libdir ${libdir}'"
+ cmd = cmd + " --define '_datadir ${datadir}'"
cmd = cmd + " --define '_builddir " + d.getVar('B') + "'"
cmd = cmd + " --define '_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm'"
cmd = cmd + " --define '_binaries_in_noarch_packages_terminate_build 0'"
@@ -636,6 +637,7 @@ python do_package_rpm () {
cmd = cmd + " --define '_unpackaged_files_terminate_build 0'"
cmd = cmd + " --define 'debug_package %{nil}'"
cmd = cmd + " --define '_tmppath " + workdir + "'"
+ cmd = cmd + " --define '__sysusers_path %{nil}'"
cmd = cmd + " --define '_use_weak_usergroup_deps 1'"
cmd = cmd + " --define '_passwd_path " + "/completely/bogus/path" + "'"
cmd = cmd + " --define '_group_path " + "/completely/bogus/path" + "'"
@@ -665,6 +667,8 @@ python do_package_rpm () {
python () {
if d.getVar('PACKAGES') != '':
deps = ' rpm-native:do_populate_sysroot virtual/fakeroot-native:do_populate_sysroot'
+ # The pkgconfig-native is required by rpm's pkgconfigdeps.sh
+ deps += ' pkgconfig-native:do_populate_sysroot'
d.appendVarFlag('do_package_write_rpm', 'depends', deps)
d.setVarFlag('do_package_write_rpm', 'fakeroot', '1')
diff --git a/meta/recipes-devtools/rpm/files/0001-Add-a-color-setting-for-mips64_n32-binaries.patch b/meta/recipes-devtools/rpm/files/0001-Add-a-color-setting-for-mips64_n32-binaries.patch
index 769d7b3409..1bba3c0306 100644
--- a/meta/recipes-devtools/rpm/files/0001-Add-a-color-setting-for-mips64_n32-binaries.patch
+++ b/meta/recipes-devtools/rpm/files/0001-Add-a-color-setting-for-mips64_n32-binaries.patch
@@ -5,16 +5,19 @@ Subject: [PATCH] Add a color setting for mips64_n32 binaries
Upstream-Status: Inappropriate [oe-core specific]
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+
+Rebased to 6.0.1
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- build/rpmfc.c | 4 ++++
+ build/rpmfc.cc | 4 ++++
rpmrc.in | 2 ++
2 files changed, 6 insertions(+)
-diff --git a/build/rpmfc.c b/build/rpmfc.c
-index 86dd36d14..df421a23f 100644
---- a/build/rpmfc.c
-+++ b/build/rpmfc.c
-@@ -716,6 +716,7 @@ static int rpmfcHelper(rpmfc fc, int *fnx, int nfn, const char *proto,
+diff --git a/build/rpmfc.cc b/build/rpmfc.cc
+index 833e56fa8..d50a3407f 100644
+--- a/build/rpmfc.cc
++++ b/build/rpmfc.cc
+@@ -690,6 +690,7 @@ static int rpmfcHelper(rpmfc fc, int *fnx, int nfn, const char *proto,
static const struct rpmfcTokens_s rpmfcTokens[] = {
{ "directory", RPMFC_INCLUDE },
@@ -22,7 +25,7 @@ index 86dd36d14..df421a23f 100644
{ "ELF 32-bit", RPMFC_ELF32|RPMFC_INCLUDE },
{ "ELF 64-bit", RPMFC_ELF64|RPMFC_INCLUDE },
-@@ -1258,6 +1259,9 @@ static uint32_t getElfColor(const char *fn)
+@@ -1191,6 +1192,9 @@ static uint32_t getElfColor(const char *fn)
color = 0;
break;
}
@@ -33,10 +36,10 @@ index 86dd36d14..df421a23f 100644
if (elf)
elf_end(elf);
diff --git a/rpmrc.in b/rpmrc.in
-index 8646a966b..7349fdfd3 100644
+index 8fd0d7ee1..4cc52ceb3 100644
--- a/rpmrc.in
+++ b/rpmrc.in
-@@ -142,6 +142,8 @@ archcolor: mipsr6el 1
+@@ -152,6 +152,8 @@ archcolor: mipsr6el 1
archcolor: mips64r6 2
archcolor: mips64r6el 2
diff --git a/meta/recipes-devtools/rpm/files/0001-CMakeLists.txt-Fix-checking-for-CFLAGS.patch b/meta/recipes-devtools/rpm/files/0001-CMakeLists.txt-Fix-checking-for-CFLAGS.patch
deleted file mode 100644
index 412e1c146d..0000000000
--- a/meta/recipes-devtools/rpm/files/0001-CMakeLists.txt-Fix-checking-for-CFLAGS.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From e14502834fe6a9c6c9a439401ac3d2c8fd979267 Mon Sep 17 00:00:00 2001
-From: Robert Yang <liezhi.yang@windriver.com>
-Date: Sun, 8 Jun 2025 00:36:38 -0700
-Subject: [PATCH] CMakeLists.txt: Improve checking for CFLAGS
-
-The previous log wasn't clear:
--- Performing Test found
--- Performing Test found - Success
--- Performing Test found
--- Performing Test found - Success
--- Performing Test found
--- Performing Test found - Failed
-
-Use a new var compiler-supports${flag} will make it more clear:
--- Performing Test compiler-supports-fno-strict-overflow
--- Performing Test compiler-supports-fno-strict-overflow - Success
--- Performing Test compiler-supports-fno-delete-null-pointer-checks
--- Performing Test compiler-supports-fno-delete-null-pointer-checks - Success
--- Performing Test compiler-supports-fhardened
--- Performing Test compiler-supports-fhardened - Failed
-
-Upstream-Status: Backport [https://github.com/rpm-software-management/rpm/commit/e14502834fe6a9c6c9a439401ac3d2c8fd979267]
-
-Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
----
- CMakeLists.txt | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 08e3e5274..f275c396b 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -416,11 +416,10 @@ endif()
-
- # try to ensure some compiler sanity and hardening options where supported
- foreach (flag -fno-strict-overflow -fno-delete-null-pointer-checks -fhardened)
-- check_c_compiler_flag(${flag} found)
-- if (found)
-+ check_c_compiler_flag(${flag} compiler-supports${flag})
-+ if (compiler-supports${flag})
- add_compile_options(${flag})
- endif()
-- unset(found)
- endforeach()
-
- # generated sources
diff --git a/meta/recipes-devtools/rpm/files/0001-CMakeLists.txt-set-libdir-to-CMAKE_INSTALL_FULL_LIBD.patch b/meta/recipes-devtools/rpm/files/0001-CMakeLists.txt-set-libdir-to-CMAKE_INSTALL_FULL_LIBD.patch
deleted file mode 100644
index 7db643871f..0000000000
--- a/meta/recipes-devtools/rpm/files/0001-CMakeLists.txt-set-libdir-to-CMAKE_INSTALL_FULL_LIBD.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From cb5355da9b47166253dbe5ab3215e433b55068d1 Mon Sep 17 00:00:00 2001
-From: Yi Zhao <yi.zhao@windriver.com>
-Date: Fri, 26 Jul 2024 17:18:30 +0800
-Subject: [PATCH] CMakeLists.txt: set libdir to ${CMAKE_INSTALL_FULL_LIBDIR} in
- macros
-
-There is a patch in oe-core[1] to avoid hardcoded paths in macros. It
-tries to use libdir to expand %_libdir in macros.in. However, in
-upstream commit[2], libdir for macros in CMakeLists.txt is set to
-${prefix}/=LIB=, which causes %_libdir to expand to ${prefix}/=LIB=
-instead of the correct path in the final macros.
-
-On target:
-$ rpm --showrc | grep _libdir
-[snip]
--13: _libdir ${prefix}/=LIB=
-[snip]
-
-This also causes %__pkgconfig_path in fileattrs/pkgconfig.attr to become
-an invalid regular expression when building rpm packages. This results a
-warning in log.do_package_write_rpm in all packages:
-
-Warning: Ignoring invalid regular expression ^((${prefix}/=LIB=|usr/share)/pkgconfig/.*.pc|usr/bin/pkg-config)$
-
-Set libdir to ${CMAKE_INSTALL_FULL_LIBDIR} instead of ${prefix}/=LIB= to
-make sure it is expanded to the correct path in macros.
-
-[1] https://git.openembedded.org/openembedded-core/tree/meta/recipes-devtools/rpm/files/0001-Do-not-hardcode-lib-rpm-as-the-installation-path-for.patch
-[2] https://github.com/rpm-software-management/rpm/commit/d2abb7a48760418aacd7f17c8b64e39c25ca50c9
-
-Upstream-Status: Inappropriate [oe specific]
-
-Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
----
- CMakeLists.txt | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 08dabffd3..1b7661139 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -96,7 +96,7 @@ function(makemacros)
- set(sysconfdir "${CMAKE_INSTALL_FULL_SYSCONFDIR}")
- set(sharedstatedir "${CMAKE_INSTALL_FULL_SHAREDSTATEDIR}")
- set(localstatedir "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}")
-- set(libdir "\${prefix}/=LIB=")
-+ set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
- set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
- set(oldincludedir "${CMAKE_INSTALL_FULL_OLDINCLUDEDIR}")
- set(infodir "\${prefix}/${CMAKE_INSTALL_INFODIR}")
diff --git a/meta/recipes-devtools/rpm/files/0001-Do-not-add-an-unsatisfiable-dependency-when-building.patch b/meta/recipes-devtools/rpm/files/0001-Do-not-add-an-unsatisfiable-dependency-when-building.patch
index 96a5e14999..ec35b938b0 100644
--- a/meta/recipes-devtools/rpm/files/0001-Do-not-add-an-unsatisfiable-dependency-when-building.patch
+++ b/meta/recipes-devtools/rpm/files/0001-Do-not-add-an-unsatisfiable-dependency-when-building.patch
@@ -9,16 +9,19 @@ hand produces rpms that way by design.
Upstream-Status: Inappropriate [oe-core specific]
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+
+Rebased to 6.0.1
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- build/pack.c | 4 ----
+ build/pack.cc | 4 ----
1 file changed, 4 deletions(-)
-diff --git a/build/pack.c b/build/pack.c
-index eb9c7b3f1..fb1f1bed8 100644
---- a/build/pack.c
-+++ b/build/pack.c
-@@ -712,10 +712,6 @@ static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int ch
- headerPutBin(pkg->header, RPMTAG_SOURCEPKGID, spec->sourcePkgId,16);
+diff --git a/build/pack.cc b/build/pack.cc
+index 49c9d0a58..b1cda6d75 100644
+--- a/build/pack.cc
++++ b/build/pack.cc
+@@ -805,10 +805,6 @@ static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int ch
+ headerPutBin(pkg->header, RPMTAG_SOURCESIGMD5, spec->sourcePkgId,16);
}
- if (cheating) {
diff --git a/meta/recipes-devtools/rpm/files/0001-Do-not-hardcode-lib-rpm-as-the-installation-path-for.patch b/meta/recipes-devtools/rpm/files/0001-Do-not-hardcode-lib-rpm-as-the-installation-path-for.patch
index 6a44f4f22d..e7eead1b76 100644
--- a/meta/recipes-devtools/rpm/files/0001-Do-not-hardcode-lib-rpm-as-the-installation-path-for.patch
+++ b/meta/recipes-devtools/rpm/files/0001-Do-not-hardcode-lib-rpm-as-the-installation-path-for.patch
@@ -6,10 +6,15 @@ Subject: [PATCH] Do not hardcode "lib/rpm" as the installation path for
Upstream-Status: Denied [https://github.com/rpm-software-management/rpm/pull/263]
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+
+Updated for rpm 6.0.1:
+Remove the changes for macros.in since it doesn't work for rpmbuild, rpmbuild
+is like cross build, will define the values in package_rpm.bbclass.
+
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
CMakeLists.txt | 2 +-
- macros.in | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
+ 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index de0b578a6..9a3aba071 100644
@@ -23,17 +28,3 @@ index de0b578a6..9a3aba071 100644
+set(RPM_CONFIGDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/rpm" CACHE PATH "rpm home")
set(RPM_MACROSDIR "${RPM_CONFIGDIR}/macros.d")
set(RPM_VENDOR "vendor" CACHE STRING "rpm vendor string")
-
-diff --git a/macros.in b/macros.in
-index 4d3e8afdc..66e31320f 100644
---- a/macros.in
-+++ b/macros.in
-@@ -964,7 +964,7 @@ Supplements: (%{name} = %{version}-%{release} and langpacks-%{1})\
- %_sharedstatedir %{_var}/lib
- %_localstatedir %{_prefix}/var
- %_lib lib
--%_libdir %{_exec_prefix}/%{_lib}
-+%_libdir @libdir@
- %_includedir %{_prefix}/include
- %_infodir %{_datadir}/info
- %_mandir %{_datadir}/man
diff --git a/meta/recipes-devtools/rpm/files/0001-Do-not-read-config-files-from-HOME.patch b/meta/recipes-devtools/rpm/files/0001-Do-not-read-config-files-from-HOME.patch
index bfc9a74b6c..3ac6cf796c 100644
--- a/meta/recipes-devtools/rpm/files/0001-Do-not-read-config-files-from-HOME.patch
+++ b/meta/recipes-devtools/rpm/files/0001-Do-not-read-config-files-from-HOME.patch
@@ -5,15 +5,18 @@ Subject: [PATCH] Do not read config files from $HOME
Upstream-Status: Inappropriate [oe-core specific]
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+
+Rebased to 6.0.1
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- lib/rpmrc.c | 6 ++----
+ lib/rpmrc.cc | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
-diff --git a/lib/rpmrc.c b/lib/rpmrc.c
-index 5d778b8b7..dc8d42aeb 100644
---- a/lib/rpmrc.c
-+++ b/lib/rpmrc.c
-@@ -485,8 +485,7 @@ static void setDefaults(void)
+diff --git a/lib/rpmrc.cc b/lib/rpmrc.cc
+index 2b3baeddc..cea6f4bc5 100644
+--- a/lib/rpmrc.cc
++++ b/lib/rpmrc.cc
+@@ -390,8 +390,7 @@ static void setDefaults(void)
if (!defrcfiles) {
defrcfiles = rstrscat(NULL, confdir, "/rpmrc", ":",
confdir, "/" RPM_VENDOR "/rpmrc", ":",
@@ -23,7 +26,7 @@ index 5d778b8b7..dc8d42aeb 100644
}
/* macrofiles may be pre-set from --macros */
-@@ -498,8 +497,7 @@ static void setDefaults(void)
+@@ -403,8 +402,7 @@ static void setDefaults(void)
confdir, "/" RPM_VENDOR "/macros", ":",
SYSCONFDIR "/rpm/macros.*", ":",
SYSCONFDIR "/rpm/macros", ":",
diff --git a/meta/recipes-devtools/rpm/files/0001-Do-not-reset-the-PATH-environment-variable-before-ru.patch b/meta/recipes-devtools/rpm/files/0001-Do-not-reset-the-PATH-environment-variable-before-ru.patch
index d3263896ef..bcc07c1e07 100644
--- a/meta/recipes-devtools/rpm/files/0001-Do-not-reset-the-PATH-environment-variable-before-ru.patch
+++ b/meta/recipes-devtools/rpm/files/0001-Do-not-reset-the-PATH-environment-variable-before-ru.patch
@@ -8,15 +8,18 @@ We add lots of native stuff into it and scriptlets rely on that.
Upstream-Status: Inappropriate [oe-core specific]
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+
+Rebased to 6.0.1
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- lib/rpmscript.c | 2 +-
+ lib/rpmscript.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
-diff --git a/lib/rpmscript.c b/lib/rpmscript.c
-index 060fd8124..4dc6466a8 100644
---- a/lib/rpmscript.c
-+++ b/lib/rpmscript.c
-@@ -251,7 +251,7 @@ static void doScriptExec(ARGV_const_t argv, ARGV_const_t prefixes,
+diff --git a/lib/rpmscript.cc b/lib/rpmscript.cc
+index b75a62085..2d7a4c889 100644
+--- a/lib/rpmscript.cc
++++ b/lib/rpmscript.cc
+@@ -260,7 +260,7 @@ static void doScriptExec(ARGV_const_t argv, ARGV_const_t prefixes,
if (ipath && ipath[5] != '%')
path = ipath;
diff --git a/meta/recipes-devtools/rpm/files/0001-When-cross-installing-execute-package-scriptlets-wit.patch b/meta/recipes-devtools/rpm/files/0001-When-cross-installing-execute-package-scriptlets-wit.patch
index b71156fe12..b7c68a90bc 100644
--- a/meta/recipes-devtools/rpm/files/0001-When-cross-installing-execute-package-scriptlets-wit.patch
+++ b/meta/recipes-devtools/rpm/files/0001-When-cross-installing-execute-package-scriptlets-wit.patch
@@ -26,15 +26,16 @@ Upstream-Status: Inappropriate [oe-core specific]
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
Rebased to 4.20.1
+Rebased to 6.0.1
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- lib/rpmscript.c | 9 +++++++--
+ lib/rpmscript.cc | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
-diff --git a/lib/rpmscript.c b/lib/rpmscript.c
-index eb14870b3..1785e8f30 100644
---- a/lib/rpmscript.c
-+++ b/lib/rpmscript.c
+diff --git a/lib/rpmscript.cc b/lib/rpmscript.cc
+index b75a62085..7d667b7f5 100644
+--- a/lib/rpmscript.cc
++++ b/lib/rpmscript.cc
@@ -456,8 +456,7 @@ exit:
Fclose(out); /* XXX dup'd STDOUT_FILENO */
diff --git a/meta/recipes-devtools/rpm/files/0001-build-pack.c-do-not-insert-payloadflags-into-.rpm-me.patch b/meta/recipes-devtools/rpm/files/0001-build-pack.c-do-not-insert-payloadflags-into-.rpm-me.patch
index 0c29e5543a..9de291b057 100644
--- a/meta/recipes-devtools/rpm/files/0001-build-pack.c-do-not-insert-payloadflags-into-.rpm-me.patch
+++ b/meta/recipes-devtools/rpm/files/0001-build-pack.c-do-not-insert-payloadflags-into-.rpm-me.patch
@@ -1,7 +1,7 @@
From e688eb54fd54d65181e94b854b3568d99cbf3a24 Mon Sep 17 00:00:00 2001
From: Alexander Kanavin <alex@linutronix.de>
Date: Tue, 31 Aug 2021 10:37:05 +0200
-Subject: [PATCH] build/pack.c: do not insert payloadflags into .rpm metadata
+Subject: [PATCH] build/pack.cc: do not insert payloadflags into .rpm metadata
The flags look like '19T56' where 19 is the compression level
(deterministic), and 56 is the amount of threads (varies from one
@@ -9,15 +9,18 @@ host to the next and breaks reproducibility for .rpm).
Upstream-Status: Inappropriate [oe-core specific]
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
+
+Rebased to 6.0.1
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- build/pack.c | 2 +-
+ build/pack.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
-diff --git a/build/pack.c b/build/pack.c
-index fb1f1bed8..45885a6ac 100644
---- a/build/pack.c
-+++ b/build/pack.c
-@@ -330,7 +330,7 @@ static char *getIOFlags(Package pkg)
+diff --git a/build/pack.cc b/build/pack.cc
+index b1cda6d75..1425d27ba 100644
+--- a/build/pack.cc
++++ b/build/pack.cc
+@@ -338,7 +338,7 @@ static char *getIOFlags(Package pkg)
headerPutString(pkg->header, RPMTAG_PAYLOADCOMPRESSOR, compr);
buf = xstrdup(rpmio_flags);
buf[s - rpmio_flags] = '\0';
diff --git a/meta/recipes-devtools/rpm/files/0001-lib-transaction.c-fix-file-conflicts-for-MIPS64-N32.patch b/meta/recipes-devtools/rpm/files/0001-lib-transaction.c-fix-file-conflicts-for-MIPS64-N32.patch
index 7d443ccc6c..b65a7ef81b 100644
--- a/meta/recipes-devtools/rpm/files/0001-lib-transaction.c-fix-file-conflicts-for-MIPS64-N32.patch
+++ b/meta/recipes-devtools/rpm/files/0001-lib-transaction.c-fix-file-conflicts-for-MIPS64-N32.patch
@@ -1,7 +1,7 @@
From ad530868e37f09e9236c085d25a834304750704b Mon Sep 17 00:00:00 2001
From: Changqing Li <changqing.li@windriver.com>
Date: Thu, 7 May 2020 17:40:58 +0800
-Subject: [PATCH] lib/transaction.c: fix file conflicts for MIPS64 N32
+Subject: [PATCH] lib/transaction.cc: fix file conflicts for MIPS64 N32
This patch is from:
https://github.com/rpm-software-management/rpm/issues/193
@@ -27,15 +27,18 @@ Fixed by performing a 'last-in-wins' resolution when "neither is preferred".
Upstream-Status: Submitted <https://github.com/rpm-software-management/rpm/issues/193>
Signed-off-by: Changqing Li <changqing.li@windriver.com>
+
+Rebased to 6.0.1
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- lib/transaction.c | 13 ++++++++++++-
+ lib/transaction.cc | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
-diff --git a/lib/transaction.c b/lib/transaction.c
-index 5e4414d2a..b1c55bd44 100644
---- a/lib/transaction.c
-+++ b/lib/transaction.c
-@@ -400,7 +400,18 @@ static int handleColorConflict(rpmts ts,
+diff --git a/lib/transaction.cc b/lib/transaction.cc
+index de7cdabb2..697268733 100644
+--- a/lib/transaction.cc
++++ b/lib/transaction.cc
+@@ -375,7 +375,18 @@ static int handleColorConflict(rpmts ts,
rpmfsSetAction(ofs, ofx, FA_CREATE);
rpmfsSetAction(fs, fx, FA_SKIPCOLOR);
rConflicts = 0;
diff --git a/meta/recipes-devtools/rpm/files/0001-macros.in-Set-_pkgverify_level-to-digest-as-RCPM-4.2.patch b/meta/recipes-devtools/rpm/files/0001-macros.in-Set-_pkgverify_level-to-digest-as-RCPM-4.2.patch
new file mode 100644
index 0000000000..682c57c1f0
--- /dev/null
+++ b/meta/recipes-devtools/rpm/files/0001-macros.in-Set-_pkgverify_level-to-digest-as-RCPM-4.2.patch
@@ -0,0 +1,34 @@
+From 1cb53934b83b794c319813106c9f12d75cce66d2 Mon Sep 17 00:00:00 2001
+From: Robert Yang <liezhi.yang@windriver.com>
+Date: Sun, 18 Jan 2026 19:24:42 -0800
+Subject: [PATCH] macros.in: Set _pkgverify_level to digest as RPM 4.20.1
+
+Fixed:
+$ bitbake core-image-minimal
+Package bash-5.3-r0.16.x86_64_v3.rpm is not signed
+GPG check FAILED
+
+Set _pkgverify_level to digest as RPM 4.20.1 can fix the problem.
+
+Upstream-Status: Inappropriate [oe-core specific]
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
+---
+ macros.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/macros.in b/macros.in
+index 38066f00c..7fe00ad09 100644
+--- a/macros.in
++++ b/macros.in
+@@ -680,7 +680,7 @@ Supplements: (%{name} = %{version}-%{release} and langpacks-%{1})\
+ # signature require valid signature(s)
+ # digest require valid digest(s)
+ # none traditional rpm behavior, nothing required
+-%_pkgverify_level all
++%_pkgverify_level digest
+
+ # Disabler flags for package verification (similar to vsflags)
+ # Set to 0x0 for full compatibility with v4 packages.
+--
+2.49.0
+
diff --git a/meta/recipes-devtools/rpm/files/0001-scripts-pkgconfigdeps.sh-Use-pkg-config-from-PATH.patch b/meta/recipes-devtools/rpm/files/0001-scripts-pkgconfigdeps.sh-Use-pkg-config-from-PATH.patch
new file mode 100644
index 0000000000..62dad7df06
--- /dev/null
+++ b/meta/recipes-devtools/rpm/files/0001-scripts-pkgconfigdeps.sh-Use-pkg-config-from-PATH.patch
@@ -0,0 +1,42 @@
+From d1739be5b733277d681fbfe4c3447ddfb6c2e45a Mon Sep 17 00:00:00 2001
+From: Robert Yang <liezhi.yang@windriver.com>
+Date: Sat, 28 Feb 2026 02:14:19 -0500
+Subject: [PATCH] scripts/pkgconfigdeps.sh: Use pkg-config from PATH
+
+pkgconfig: Used for running during rpmbuild
+pkgconfig_requires: Used as 'Requires:' in the spec file.
+
+This can reduce host contaminations, and make it friendly to cross compile.
+
+Upstream-Status: Submitted [https://github.com/rpm-software-management/rpm/pull/4127]
+
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
+---
+ scripts/pkgconfigdeps.sh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/scripts/pkgconfigdeps.sh b/scripts/pkgconfigdeps.sh
+index ef4581856..c7fce4145 100755
+--- a/scripts/pkgconfigdeps.sh
++++ b/scripts/pkgconfigdeps.sh
+@@ -1,6 +1,7 @@
+ #!/bin/bash
+
+-pkgconfig=/usr/bin/pkg-config
++pkgconfig=$(which pkg-config)
++pkgconfig_requires=/usr/bin/pkg-config
+ test -x $pkgconfig || {
+ cat > /dev/null
+ exit 0
+@@ -44,7 +45,7 @@ case $1 in
+ case "${filename}" in
+ *.pc)
+ i="`expr $i + 1`"
+- [ $i -eq 1 ] && echo "$pkgconfig"
++ [ $i -eq 1 ] && echo "$pkgconfig_requires"
+ DIR="`dirname ${filename}`"
+ export PKG_CONFIG_PATH="$DIR:$DIR/../../share/pkgconfig"
+ $pkgconfig --print-requires --print-requires-private "$filename" 2> /dev/null | while read n r v ; do
+--
+2.43.0
+
diff --git a/meta/recipes-devtools/rpm/files/0001-tools-elfdeps.cc-Remove-format-module.patch b/meta/recipes-devtools/rpm/files/0001-tools-elfdeps.cc-Remove-format-module.patch
new file mode 100644
index 0000000000..1863fcb7b8
--- /dev/null
+++ b/meta/recipes-devtools/rpm/files/0001-tools-elfdeps.cc-Remove-format-module.patch
@@ -0,0 +1,37 @@
+From 3536ef6bb74144cf9dce10200cd62c2ad9f7cae4 Mon Sep 17 00:00:00 2001
+From: Robert Yang <liezhi.yang@windriver.com>
+Date: Thu, 15 Jan 2026 19:36:17 -0800
+Subject: [PATCH] tools/elfdeps.cc: Remove format module
+
+There is no format until gcc 13.1, so remove the format module to make it work
+on hosts such as Ubuntu 22.04.
+
+Upstream-Status: Inappropriate [oe-core specific]
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
+---
+ tools/elfdeps.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/tools/elfdeps.cc b/tools/elfdeps.cc
+index 17884b24e..33ff8d740 100644
+--- a/tools/elfdeps.cc
++++ b/tools/elfdeps.cc
+@@ -1,6 +1,5 @@
+ #include "system.h"
+
+-#include <format>
+ #include <string>
+ #include <vector>
+
+@@ -105,7 +104,7 @@ static void addSoDep(std::vector<std::string> & deps,
+ if (ver.empty() && marker.empty()) {
+ addDep(deps, soname);
+ } else {
+- auto dep = std::format("{}({}){}", soname, ver, marker);
++ std::string dep = soname + "(" + ver + ")" + marker;
+ addDep(deps, dep);
+ }
+ }
+--
+2.49.0
+
diff --git a/meta/recipes-devtools/rpm/files/0002-Add-support-for-prefixing-etc-from-RPM_ETCCONFIGDIR-.patch b/meta/recipes-devtools/rpm/files/0002-Add-support-for-prefixing-etc-from-RPM_ETCCONFIGDIR-.patch
index 082fb343c2..758094f9e4 100644
--- a/meta/recipes-devtools/rpm/files/0002-Add-support-for-prefixing-etc-from-RPM_ETCCONFIGDIR-.patch
+++ b/meta/recipes-devtools/rpm/files/0002-Add-support-for-prefixing-etc-from-RPM_ETCCONFIGDIR-.patch
@@ -9,15 +9,18 @@ from target rootfs instead of its own native sysroot.
Upstream-Status: Inappropriate [oe-core specific]
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+
+Rebased to 6.0.1
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- lib/rpmrc.c | 18 +++++++++++++-----
+ lib/rpmrc.cc | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
-diff --git a/lib/rpmrc.c b/lib/rpmrc.c
-index dc8d42aeb..3f2996850 100644
---- a/lib/rpmrc.c
-+++ b/lib/rpmrc.c
-@@ -481,11 +481,14 @@ static void setDefaults(void)
+diff --git a/lib/rpmrc.cc b/lib/rpmrc.cc
+index cea6f4bc5..e6cf21e1b 100644
+--- a/lib/rpmrc.cc
++++ b/lib/rpmrc.cc
+@@ -386,11 +386,14 @@ static void setDefaults(void)
userrc = xstrdup(oldrc);
}
}
@@ -33,7 +36,7 @@ index dc8d42aeb..3f2996850 100644
}
/* macrofiles may be pre-set from --macros */
-@@ -495,9 +498,9 @@ static void setDefaults(void)
+@@ -400,9 +403,9 @@ static void setDefaults(void)
confdir, "/platform/%{_target}/macros", ":",
confdir, "/fileattrs/*.attr", ":",
confdir, "/" RPM_VENDOR "/macros", ":",
@@ -46,7 +49,7 @@ index dc8d42aeb..3f2996850 100644
}
free(usermacros);
-@@ -1142,7 +1145,11 @@ static void read_auxv(void)
+@@ -1048,7 +1051,11 @@ static void read_auxv(void)
*/
static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os)
{
@@ -55,11 +58,11 @@ index dc8d42aeb..3f2996850 100644
+ if (etcconfdir == NULL)
+ etcconfdir = "";
+
-+ const char * const platform_path = rstrscat(NULL, etcconfdir, SYSCONFDIR "/rpm/platform", NULL);
++ char * const platform_path = rstrscat(NULL, etcconfdir, SYSCONFDIR "/rpm/platform", NULL);
static struct utsname un;
char * chptr;
- canonEntry canon;
-@@ -1462,6 +1469,7 @@ static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os)
+ int rc;
+@@ -1378,6 +1385,7 @@ static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os)
if (arch) *arch = un.machine;
if (os) *os = un.sysname;
diff --git a/meta/recipes-devtools/rpm/files/0002-rpmio-rpmglob.c-avoid-using-GLOB_BRACE-if-undefined-.patch b/meta/recipes-devtools/rpm/files/0002-rpmio-rpmglob.c-avoid-using-GLOB_BRACE-if-undefined-.patch
index 00fe19108e..751ef7b096 100644
--- a/meta/recipes-devtools/rpm/files/0002-rpmio-rpmglob.c-avoid-using-GLOB_BRACE-if-undefined-.patch
+++ b/meta/recipes-devtools/rpm/files/0002-rpmio-rpmglob.c-avoid-using-GLOB_BRACE-if-undefined-.patch
@@ -1,7 +1,7 @@
From d8972ff7fa0a30e199144ba135223bf561874e01 Mon Sep 17 00:00:00 2001
From: Alexander Kanavin <alex@linutronix.de>
Date: Tue, 16 Jan 2024 09:59:26 +0100
-Subject: [PATCH] rpmio/rpmglob.c: avoid using GLOB_BRACE if undefined by C
+Subject: [PATCH] rpmio/rpmglob.cc: avoid using GLOB_BRACE if undefined by C
library
This addresses musl failures; if there is code out there relying on
@@ -11,14 +11,17 @@ This is unlikely to be trivially fixable upstream.
Upstream-Status: Inappropriate [reported at https://github.com/rpm-software-management/rpm/issues/2844]
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
+
+Rebased to 6.0.1
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- rpmio/rpmglob.c | 6 ++++++
+ rpmio/rpmglob.cc | 6 ++++++
1 file changed, 6 insertions(+)
-diff --git a/rpmio/rpmglob.c b/rpmio/rpmglob.c
+diff --git a/rpmio/rpmglob.cc b/rpmio/rpmglob.cc
index eb439cad8..1eef0b851 100644
---- a/rpmio/rpmglob.c
-+++ b/rpmio/rpmglob.c
+--- a/rpmio/rpmglob.cc
++++ b/rpmio/rpmglob.cc
@@ -33,6 +33,12 @@
#include "debug.h"
diff --git a/meta/recipes-devtools/rpm/files/0016-rpmscript.c-change-logging-level-around-scriptlets-t.patch b/meta/recipes-devtools/rpm/files/0016-rpmscript.c-change-logging-level-around-scriptlets-t.patch
index bac2d6331c..28fb5f001b 100644
--- a/meta/recipes-devtools/rpm/files/0016-rpmscript.c-change-logging-level-around-scriptlets-t.patch
+++ b/meta/recipes-devtools/rpm/files/0016-rpmscript.c-change-logging-level-around-scriptlets-t.patch
@@ -1,7 +1,7 @@
From 452b696ea3e1975ea30cf7a92678aa4b316e6300 Mon Sep 17 00:00:00 2001
From: Alexander Kanavin <alex.kanavin@gmail.com>
Date: Thu, 10 Jan 2019 18:14:18 +0100
-Subject: [PATCH] rpmscript.c: change logging level around scriptlets to INFO
+Subject: [PATCH] rpmscript.cc: change logging level around scriptlets to INFO
from DEBUG
That way we can debug scriptlet failures without writing lots of
@@ -11,15 +11,16 @@ Upstream-Status: Inappropriate [oe-core specific]
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
Rebased to 4.20.1
+Rebased to 6.0.1
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
- lib/rpmscript.c | 8 ++++----
+ lib/rpmscript.cc | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
-diff --git a/lib/rpmscript.c b/lib/rpmscript.c
-index e9f288ae0..f0c628708 100644
---- a/lib/rpmscript.c
-+++ b/lib/rpmscript.c
+diff --git a/lib/rpmscript.cc b/lib/rpmscript.cc
+index fe5fc9138..861fd8ca8 100644
+--- a/lib/rpmscript.cc
++++ b/lib/rpmscript.cc
@@ -299,7 +299,7 @@ static char * writeScript(const char *cmd, const char *script)
if (Ferror(fd))
goto exit;
diff --git a/meta/recipes-devtools/rpm/rpm_4.20.1.bb b/meta/recipes-devtools/rpm/rpm_6.0.1.bb
similarity index 94%
rename from meta/recipes-devtools/rpm/rpm_4.20.1.bb
rename to meta/recipes-devtools/rpm/rpm_6.0.1.bb
index ba967ec1fa..22fb7502d1 100644
--- a/meta/recipes-devtools/rpm/rpm_4.20.1.bb
+++ b/meta/recipes-devtools/rpm/rpm_6.0.1.bb
@@ -24,7 +24,7 @@ HOMEPAGE = "http://www.rpm.org"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://COPYING;md5=066ecde17828e5c8911ec9eae8be78f4"
-SRC_URI = "git://github.com/rpm-software-management/rpm;branch=rpm-4.20.x;protocol=https \
+SRC_URI = "git://github.com/rpm-software-management/rpm;branch=${BPN}-6.0.x;tag=${BP}-release;protocol=https \
file://0001-Do-not-add-an-unsatisfiable-dependency-when-building.patch \
file://0001-Do-not-read-config-files-from-HOME.patch \
file://0001-When-cross-installing-execute-package-scriptlets-wit.patch \
@@ -37,14 +37,15 @@ SRC_URI = "git://github.com/rpm-software-management/rpm;branch=rpm-4.20.x;protoc
file://0001-build-pack.c-do-not-insert-payloadflags-into-.rpm-me.patch \
file://0001-CMakeLists.txt-look-for-lua-with-pkg-config-rather-t.patch \
file://0002-rpmio-rpmglob.c-avoid-using-GLOB_BRACE-if-undefined-.patch \
- file://0001-CMakeLists.txt-set-libdir-to-CMAKE_INSTALL_FULL_LIBD.patch \
- file://0001-CMakeLists.txt-Fix-checking-for-CFLAGS.patch \
+ file://0001-tools-elfdeps.cc-Remove-format-module.patch \
+ file://0001-macros.in-Set-_pkgverify_level-to-digest-as-RCPM-4.2.patch \
+ file://0001-scripts-pkgconfigdeps.sh-Use-pkg-config-from-PATH.patch \
"
PE = "1"
-SRCREV = "c8dc5ea575a2e9c1488036d12f4b75f6a5a49120"
+SRCREV = "58a917a6c5e24e9e8a01976c17d2eee06249b9b6"
-DEPENDS = "lua libgcrypt file popt xz bzip2 elfutils python3 sqlite3 zstd"
+DEPENDS = "lua libgcrypt file popt xz bzip2 elfutils python3 sqlite3 zstd scdoc-native"
DEPENDS:append:class-native = " file-replacement-native bzip2-replacement-native"
EXTRA_OECMAKE:append = " -D__CURL:FILEPATH=curl"
@@ -151,7 +152,8 @@ do_install:append () {
FILES:${PN} += "${libdir}/rpm-plugins/*.so \
"
-FILES:${PN}:append:class-nativesdk = " ${SDKPATHNATIVE}/environment-setup.d/rpm.sh"
+FILES:${PN}:append:class-nativesdk = " ${SDKPATHNATIVE}/environment-setup.d/rpm.sh \
+ /etc/rpm"
FILES:${PN}-dev += "${libdir}/rpm-plugins/*.la \
"
@@ -178,6 +180,7 @@ FILES:${PN}-build = "\
${libdir}/rpm/mkinstalldirs \
${libdir}/rpm/macros.p* \
${libdir}/rpm/fileattrs/* \
+ ${libdir}/rpm/rpm-setup-autosign \
"
FILES:${PN}-sign = "\
--
2.49.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v8 9/9] libarchive: Make it work with rpm 6
2026-03-12 14:09 [PATCH v8 0/9] rpm: 4.20.1 -> 6.0.1 liezhi.yang
` (7 preceding siblings ...)
2026-03-12 14:09 ` [PATCH v8 8/9] libarchive: upgrade 3.8.5 -> 3.8.6 liezhi.yang
@ 2026-03-12 14:09 ` liezhi.yang
2026-03-12 15:52 ` [PATCH v8 0/9] rpm: 4.20.1 -> 6.0.1 Mathieu Dubois-Briand
9 siblings, 0 replies; 17+ messages in thread
From: liezhi.yang @ 2026-03-12 14:09 UTC (permalink / raw)
To: openembedded-core
Cc: alex.kanavin, mathieu.dubois-briand, mattware, esparlin,
peter.marko
From: Robert Yang <liezhi.yang@windriver.com>
The patch is from:
https://github.com/libarchive/libarchive/pull/2846
Fixed:
$ oe-selftest -r debuginfod.Debuginfod.test_debuginfod_native
cannot open archive from pipe /path/to/tmp-debuginfod/work/x86-64-v3-poky-linux/xz/5.8.2/localpkgfeed/x86_64_v3/bash-locale-vi-5.3-r0.x86_64_v3.rpm
libarchive error: cannot open archive from pipe: Unrecognized archive format
exceptions encountered during archive scan
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
...end_filter-Keep-iterating-even-if-na.patch | 48 +
...egister_bidder-Allow-ARCHIVE_STATE_H.patch | 45 +
...er-into-a-proper-format-supporting-b.patch | 1723 +++++++++++++++++
.../libarchive/libarchive_3.8.6.bb | 3 +
4 files changed, 1819 insertions(+)
create mode 100644 meta/recipes-extended/libarchive/libarchive/0001-archive_read_append_filter-Keep-iterating-even-if-na.patch
create mode 100644 meta/recipes-extended/libarchive/libarchive/0002-__archive_read_register_bidder-Allow-ARCHIVE_STATE_H.patch
create mode 100644 meta/recipes-extended/libarchive/libarchive/0003-Convert-RPM-reader-into-a-proper-format-supporting-b.patch
diff --git a/meta/recipes-extended/libarchive/libarchive/0001-archive_read_append_filter-Keep-iterating-even-if-na.patch b/meta/recipes-extended/libarchive/libarchive/0001-archive_read_append_filter-Keep-iterating-even-if-na.patch
new file mode 100644
index 0000000000..8e236cedc8
--- /dev/null
+++ b/meta/recipes-extended/libarchive/libarchive/0001-archive_read_append_filter-Keep-iterating-even-if-na.patch
@@ -0,0 +1,48 @@
+From 26401df2e74e6d72e86fab165445949c9dd3eba9 Mon Sep 17 00:00:00 2001
+From: Davide Beatrici <git@davidebeatrici.dev>
+Date: Sat, 21 Feb 2026 02:55:40 +0100
+Subject: [PATCH 1/3] archive_read_append_filter(): Keep iterating even if name
+ is null
+
+While working on the RPM format I noticed the zstd filter failed to append.
+
+Turns out there are two unknown filters that are registered with a null name:
+
+bidder candidate bzip2
+bidder candidate compress (.Z)
+bidder candidate gzip
+bidder candidate lzip
+bidder candidate lzma
+bidder candidate xz
+bidder candidate uu
+bidder candidate lrzip
+bidder candidate (null)
+bidder candidate (null)
+bidder candidate lz4
+bidder candidate zstd
+
+I'm not sure if anonymous filters are expected behavior, but I believe this change doesn't hurt.
+
+Upstream-Status: Submitted [https://github.com/libarchive/libarchive/pull/2846]
+
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
+---
+ libarchive/archive_read_append_filter.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libarchive/archive_read_append_filter.c b/libarchive/archive_read_append_filter.c
+index cd88df11..9475b704 100644
+--- a/libarchive/archive_read_append_filter.c
++++ b/libarchive/archive_read_append_filter.c
+@@ -117,7 +117,7 @@ archive_read_append_filter(struct archive *_a, int code)
+ bidder = a->bidders;
+ for (i = 1; i < number_bidders; i++, bidder++)
+ {
+- if (!bidder->name || !strcmp(bidder->name, str))
++ if (bidder->name && !strcmp(bidder->name, str))
+ break;
+ }
+ if (!bidder->name || strcmp(bidder->name, str))
+--
+2.49.0
+
diff --git a/meta/recipes-extended/libarchive/libarchive/0002-__archive_read_register_bidder-Allow-ARCHIVE_STATE_H.patch b/meta/recipes-extended/libarchive/libarchive/0002-__archive_read_register_bidder-Allow-ARCHIVE_STATE_H.patch
new file mode 100644
index 0000000000..3ddfedb27c
--- /dev/null
+++ b/meta/recipes-extended/libarchive/libarchive/0002-__archive_read_register_bidder-Allow-ARCHIVE_STATE_H.patch
@@ -0,0 +1,45 @@
+From 8eafdb93fd551bfed7184bc7519f5d455811cefb Mon Sep 17 00:00:00 2001
+From: Davide Beatrici <git@davidebeatrici.dev>
+Date: Sat, 21 Feb 2026 05:33:36 +0100
+Subject: [PATCH 2/3] __archive_read_register_bidder(): Allow
+ ARCHIVE_STATE_HEADER, check if already registered
+
+This allows formats to apply filters when they know what they need.
+
+In the case of RPM, that's after parsing the (uncompressed) header.
+
+Upstream-Status: Submitted [https://github.com/libarchive/libarchive/pull/2846]
+
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
+---
+ libarchive/archive_read.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c
+index c9b9d598..bc6305ae 100644
+--- a/libarchive/archive_read.c
++++ b/libarchive/archive_read.c
+@@ -1232,13 +1232,18 @@ __archive_read_register_bidder(struct archive_read *a,
+ int i, number_slots;
+
+ archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
+- ARCHIVE_STATE_NEW, "__archive_read_register_bidder");
++ ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER,
++ "__archive_read_register_bidder");
+
+ number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
+
+ for (i = 0; i < number_slots; i++) {
+- if (a->bidders[i].vtable != NULL)
++ if (a->bidders[i].vtable != NULL) {
++ if (a->bidders[i].vtable == vtable)
++ /* Already registered. */
++ return (ARCHIVE_OK);
+ continue;
++ }
+ memset(a->bidders + i, 0, sizeof(a->bidders[0]));
+ bidder = (a->bidders + i);
+ bidder->data = bidder_data;
+--
+2.49.0
+
diff --git a/meta/recipes-extended/libarchive/libarchive/0003-Convert-RPM-reader-into-a-proper-format-supporting-b.patch b/meta/recipes-extended/libarchive/libarchive/0003-Convert-RPM-reader-into-a-proper-format-supporting-b.patch
new file mode 100644
index 0000000000..b231042f93
--- /dev/null
+++ b/meta/recipes-extended/libarchive/libarchive/0003-Convert-RPM-reader-into-a-proper-format-supporting-b.patch
@@ -0,0 +1,1723 @@
+From b31625af1c540e26da4c387eb0a6a81f7cf9b5a9 Mon Sep 17 00:00:00 2001
+From: Davide Beatrici <git@davidebeatrici.dev>
+Date: Wed, 4 Mar 2026 22:58:41 +0100
+Subject: [PATCH 3/3] Convert RPM reader into a proper format, supporting both
+ stripped CPIO and SVR4
+
+Upstream-Status: Submitted [https://github.com/libarchive/libarchive/pull/2846]
+
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
+---
+ Makefile.am | 2 +-
+ contrib/android/Android.mk | 2 +-
+ libarchive/CMakeLists.txt | 2 +-
+ libarchive/archive.h | 5 +-
+ libarchive/archive_read_append_filter.c | 4 -
+ libarchive/archive_read_private.h | 2 +-
+ libarchive/archive_read_set_format.c | 3 +
+ libarchive/archive_read_support_filter_all.c | 2 -
+ .../archive_read_support_filter_by_code.c | 2 -
+ libarchive/archive_read_support_filter_rpm.c | 294 -----
+ libarchive/archive_read_support_format_all.c | 1 +
+ libarchive/archive_read_support_format_rpm.c | 1126 +++++++++++++++++
+ libarchive/test/test_archive_read_support.c | 2 +-
+ .../test_read_format_cpio_svr4_bzip2_rpm.c | 4 +-
+ .../test_read_format_cpio_svr4_gzip_rpm.c | 6 +-
+ libarchive/test/test_read_format_huge_rpm.c | 4 +-
+ 16 files changed, 1142 insertions(+), 319 deletions(-)
+ delete mode 100644 libarchive/archive_read_support_filter_rpm.c
+ create mode 100644 libarchive/archive_read_support_format_rpm.c
+
+diff --git a/Makefile.am b/Makefile.am
+index b6bf5482..ec4cf678 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -183,7 +183,6 @@ libarchive_la_SOURCES= \
+ libarchive/archive_read_support_filter_lzop.c \
+ libarchive/archive_read_support_filter_none.c \
+ libarchive/archive_read_support_filter_program.c \
+- libarchive/archive_read_support_filter_rpm.c \
+ libarchive/archive_read_support_filter_uu.c \
+ libarchive/archive_read_support_filter_xz.c \
+ libarchive/archive_read_support_filter_zstd.c \
+@@ -200,6 +199,7 @@ libarchive_la_SOURCES= \
+ libarchive/archive_read_support_format_rar.c \
+ libarchive/archive_read_support_format_rar5.c \
+ libarchive/archive_read_support_format_raw.c \
++ libarchive/archive_read_support_format_rpm.c \
+ libarchive/archive_read_support_format_tar.c \
+ libarchive/archive_read_support_format_warc.c \
+ libarchive/archive_read_support_format_xar.c \
+diff --git a/contrib/android/Android.mk b/contrib/android/Android.mk
+index 20e46a69..dc54c6b5 100644
+--- a/contrib/android/Android.mk
++++ b/contrib/android/Android.mk
+@@ -74,7 +74,6 @@ libarchive_src_files := libarchive/archive_acl.c \
+ libarchive/archive_read_support_filter_lzop.c \
+ libarchive/archive_read_support_filter_none.c \
+ libarchive/archive_read_support_filter_program.c \
+- libarchive/archive_read_support_filter_rpm.c \
+ libarchive/archive_read_support_filter_uu.c \
+ libarchive/archive_read_support_filter_xz.c \
+ libarchive/archive_read_support_filter_zstd.c \
+@@ -91,6 +90,7 @@ libarchive_src_files := libarchive/archive_acl.c \
+ libarchive/archive_read_support_format_rar.c \
+ libarchive/archive_read_support_format_rar5.c \
+ libarchive/archive_read_support_format_raw.c \
++ libarchive/archive_read_support_format_rpm.c \
+ libarchive/archive_read_support_format_tar.c \
+ libarchive/archive_read_support_format_warc.c \
+ libarchive/archive_read_support_format_xar.c \
+diff --git a/libarchive/CMakeLists.txt b/libarchive/CMakeLists.txt
+index 4fb91713..19134451 100644
+--- a/libarchive/CMakeLists.txt
++++ b/libarchive/CMakeLists.txt
+@@ -92,7 +92,6 @@ SET(libarchive_SOURCES
+ archive_read_support_filter_lzop.c
+ archive_read_support_filter_none.c
+ archive_read_support_filter_program.c
+- archive_read_support_filter_rpm.c
+ archive_read_support_filter_uu.c
+ archive_read_support_filter_xz.c
+ archive_read_support_filter_zstd.c
+@@ -109,6 +108,7 @@ SET(libarchive_SOURCES
+ archive_read_support_format_rar.c
+ archive_read_support_format_rar5.c
+ archive_read_support_format_raw.c
++ archive_read_support_format_rpm.c
+ archive_read_support_format_tar.c
+ archive_read_support_format_warc.c
+ archive_read_support_format_xar.c
+diff --git a/libarchive/archive.h b/libarchive/archive.h
+index de472a18..7d776699 100644
+--- a/libarchive/archive.h
++++ b/libarchive/archive.h
+@@ -312,7 +312,7 @@ typedef const char *archive_passphrase_callback(struct archive *,
+ #define ARCHIVE_FILTER_LZMA 5
+ #define ARCHIVE_FILTER_XZ 6
+ #define ARCHIVE_FILTER_UU 7
+-#define ARCHIVE_FILTER_RPM 8
++/*#define ARCHIVE_FILTER_RPM 8*/
+ #define ARCHIVE_FILTER_LZIP 9
+ #define ARCHIVE_FILTER_LRZIP 10
+ #define ARCHIVE_FILTER_LZOP 11
+@@ -383,6 +383,7 @@ typedef const char *archive_passphrase_callback(struct archive *,
+ #define ARCHIVE_FORMAT_7ZIP 0xE0000
+ #define ARCHIVE_FORMAT_WARC 0xF0000
+ #define ARCHIVE_FORMAT_RAR_V5 0x100000
++#define ARCHIVE_FORMAT_RPM 0x110000
+
+ /*
+ * Codes returned by archive_read_format_capabilities().
+@@ -476,7 +477,6 @@ __LA_DECL int archive_read_support_filter_program(struct archive *,
+ __LA_DECL int archive_read_support_filter_program_signature
+ (struct archive *, const char * /* cmd */,
+ const void * /* match */, size_t);
+-__LA_DECL int archive_read_support_filter_rpm(struct archive *);
+ __LA_DECL int archive_read_support_filter_uu(struct archive *);
+ __LA_DECL int archive_read_support_filter_xz(struct archive *);
+ __LA_DECL int archive_read_support_filter_zstd(struct archive *);
+@@ -497,6 +497,7 @@ __LA_DECL int archive_read_support_format_mtree(struct archive *);
+ __LA_DECL int archive_read_support_format_rar(struct archive *);
+ __LA_DECL int archive_read_support_format_rar5(struct archive *);
+ __LA_DECL int archive_read_support_format_raw(struct archive *);
++__LA_DECL int archive_read_support_format_rpm(struct archive *);
+ __LA_DECL int archive_read_support_format_tar(struct archive *);
+ __LA_DECL int archive_read_support_format_warc(struct archive *);
+ __LA_DECL int archive_read_support_format_xar(struct archive *);
+diff --git a/libarchive/archive_read_append_filter.c b/libarchive/archive_read_append_filter.c
+index 9475b704..23e6a79c 100644
+--- a/libarchive/archive_read_append_filter.c
++++ b/libarchive/archive_read_append_filter.c
+@@ -80,10 +80,6 @@ archive_read_append_filter(struct archive *_a, int code)
+ strcpy(str, "uu");
+ r1 = archive_read_support_filter_uu(_a);
+ break;
+- case ARCHIVE_FILTER_RPM:
+- strcpy(str, "rpm");
+- r1 = archive_read_support_filter_rpm(_a);
+- break;
+ case ARCHIVE_FILTER_LZ4:
+ strcpy(str, "lz4");
+ r1 = archive_read_support_filter_lz4(_a);
+diff --git a/libarchive/archive_read_private.h b/libarchive/archive_read_private.h
+index 0c374f48..7efcf51a 100644
+--- a/libarchive/archive_read_private.h
++++ b/libarchive/archive_read_private.h
+@@ -205,7 +205,7 @@ struct archive_read {
+ int (*cleanup)(struct archive_read *);
+ int (*format_capabilties)(struct archive_read *);
+ int (*has_encrypted_entries)(struct archive_read *);
+- } formats[16];
++ } formats[18];
+ struct archive_format_descriptor *format; /* Active format. */
+
+ /*
+diff --git a/libarchive/archive_read_set_format.c b/libarchive/archive_read_set_format.c
+index 552ab12d..6a176e3b 100644
+--- a/libarchive/archive_read_set_format.c
++++ b/libarchive/archive_read_set_format.c
+@@ -81,6 +81,9 @@ archive_read_set_format(struct archive *_a, int code)
+ case ARCHIVE_FORMAT_RAW:
+ str = "raw";
+ break;
++ case ARCHIVE_FORMAT_RPM:
++ str = "rpm";
++ break;
+ case ARCHIVE_FORMAT_TAR:
+ str = "tar";
+ break;
+diff --git a/libarchive/archive_read_support_filter_all.c b/libarchive/archive_read_support_filter_all.c
+index cb46d120..0f91e326 100644
+--- a/libarchive/archive_read_support_filter_all.c
++++ b/libarchive/archive_read_support_filter_all.c
+@@ -60,8 +60,6 @@ archive_read_support_filter_all(struct archive *a)
+ archive_read_support_filter_xz(a);
+ /* The decode code doesn't use an outside library. */
+ archive_read_support_filter_uu(a);
+- /* The decode code doesn't use an outside library. */
+- archive_read_support_filter_rpm(a);
+ /* The decode code always uses "lrzip -q -d" command-line. */
+ archive_read_support_filter_lrzip(a);
+ /* Lzop decompress falls back to "lzop -d" command-line. */
+diff --git a/libarchive/archive_read_support_filter_by_code.c b/libarchive/archive_read_support_filter_by_code.c
+index 4c8b6cb5..1c9a405b 100644
+--- a/libarchive/archive_read_support_filter_by_code.c
++++ b/libarchive/archive_read_support_filter_by_code.c
+@@ -49,8 +49,6 @@ archive_read_support_filter_by_code(struct archive *a, int filter_code)
+ return archive_read_support_filter_xz(a);
+ case ARCHIVE_FILTER_UU:
+ return archive_read_support_filter_uu(a);
+- case ARCHIVE_FILTER_RPM:
+- return archive_read_support_filter_rpm(a);
+ case ARCHIVE_FILTER_LZIP:
+ return archive_read_support_filter_lzip(a);
+ case ARCHIVE_FILTER_LRZIP:
+diff --git a/libarchive/archive_read_support_filter_rpm.c b/libarchive/archive_read_support_filter_rpm.c
+deleted file mode 100644
+index 25ace4a2..00000000
+--- a/libarchive/archive_read_support_filter_rpm.c
++++ /dev/null
+@@ -1,294 +0,0 @@
+-/*-
+- * Copyright (c) 2009 Michihiro NAKAJIMA
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#include "archive_platform.h"
+-
+-#ifdef HAVE_ERRNO_H
+-#include <errno.h>
+-#endif
+-#ifdef HAVE_STDLIB_H
+-#include <stdlib.h>
+-#endif
+-
+-#include "archive.h"
+-#include "archive_endian.h"
+-#include "archive_private.h"
+-#include "archive_read_private.h"
+-
+-struct rpm {
+- int64_t total_in;
+- uint64_t hpos;
+- uint64_t hlen;
+- unsigned char header[16];
+- enum {
+- ST_LEAD, /* Skipping 'Lead' section. */
+- ST_HEADER, /* Reading 'Header' section;
+- * first 16 bytes. */
+- ST_HEADER_DATA, /* Skipping 'Header' section. */
+- ST_PADDING, /* Skipping padding data after the
+- * 'Header' section. */
+- ST_ARCHIVE /* Reading 'Archive' section. */
+- } state;
+- int first_header;
+-};
+-#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
+-#define RPM_MIN_HEAD_SIZE 16 /* Minimum size of 'Head'. */
+-
+-static int rpm_bidder_bid(struct archive_read_filter_bidder *,
+- struct archive_read_filter *);
+-static int rpm_bidder_init(struct archive_read_filter *);
+-
+-static ssize_t rpm_filter_read(struct archive_read_filter *,
+- const void **);
+-static int rpm_filter_close(struct archive_read_filter *);
+-
+-static inline size_t rpm_limit_bytes(uint64_t, size_t);
+-
+-#if ARCHIVE_VERSION_NUMBER < 4000000
+-/* Deprecated; remove in libarchive 4.0 */
+-int
+-archive_read_support_compression_rpm(struct archive *a)
+-{
+- return archive_read_support_filter_rpm(a);
+-}
+-#endif
+-
+-static const struct archive_read_filter_bidder_vtable
+-rpm_bidder_vtable = {
+- .bid = rpm_bidder_bid,
+- .init = rpm_bidder_init,
+-};
+-
+-int
+-archive_read_support_filter_rpm(struct archive *_a)
+-{
+- struct archive_read *a = (struct archive_read *)_a;
+-
+- return __archive_read_register_bidder(a, NULL, "rpm",
+- &rpm_bidder_vtable);
+-}
+-
+-static int
+-rpm_bidder_bid(struct archive_read_filter_bidder *self,
+- struct archive_read_filter *filter)
+-{
+- const unsigned char *b;
+- ssize_t avail;
+- int bits_checked;
+-
+- (void)self; /* UNUSED */
+-
+- b = __archive_read_filter_ahead(filter, 8, &avail);
+- if (b == NULL)
+- return (0);
+-
+- bits_checked = 0;
+- /*
+- * Verify Header Magic Bytes : 0XED 0XAB 0XEE 0XDB
+- */
+- if (memcmp(b, "\xED\xAB\xEE\xDB", 4) != 0)
+- return (0);
+- bits_checked += 32;
+- /*
+- * Check major version.
+- */
+- if (b[4] != 3 && b[4] != 4)
+- return (0);
+- bits_checked += 8;
+- /*
+- * Check package type; binary or source.
+- */
+- if (b[6] != 0)
+- return (0);
+- bits_checked += 8;
+- if (b[7] != 0 && b[7] != 1)
+- return (0);
+- bits_checked += 8;
+-
+- return (bits_checked);
+-}
+-
+-static const struct archive_read_filter_vtable
+-rpm_reader_vtable = {
+- .read = rpm_filter_read,
+- .close = rpm_filter_close,
+-};
+-
+-static int
+-rpm_bidder_init(struct archive_read_filter *self)
+-{
+- struct rpm *rpm;
+-
+- self->code = ARCHIVE_FILTER_RPM;
+- self->name = "rpm";
+-
+- rpm = calloc(1, sizeof(*rpm));
+- if (rpm == NULL) {
+- archive_set_error(&self->archive->archive, ENOMEM,
+- "Can't allocate data for rpm");
+- return (ARCHIVE_FATAL);
+- }
+-
+- self->data = rpm;
+- rpm->state = ST_LEAD;
+- self->vtable = &rpm_reader_vtable;
+-
+- return (ARCHIVE_OK);
+-}
+-
+-static inline size_t
+-rpm_limit_bytes(uint64_t bytes, size_t max)
+-{
+- return (bytes > max ? max : (size_t)bytes);
+-}
+-
+-static ssize_t
+-rpm_filter_read(struct archive_read_filter *self, const void **buff)
+-{
+- struct rpm *rpm;
+- const unsigned char *b;
+- ssize_t avail_in, total, used;
+- size_t n;
+- uint64_t section;
+- uint64_t bytes;
+-
+- rpm = (struct rpm *)self->data;
+- *buff = NULL;
+- total = avail_in = 0;
+- b = NULL;
+- used = 0;
+- do {
+- if (b == NULL) {
+- b = __archive_read_filter_ahead(self->upstream, 1,
+- &avail_in);
+- if (b == NULL) {
+- if (avail_in < 0)
+- return (ARCHIVE_FATAL);
+- else
+- break;
+- }
+- }
+-
+- switch (rpm->state) {
+- case ST_LEAD:
+- if (rpm->total_in + avail_in < RPM_LEAD_SIZE)
+- used += avail_in;
+- else {
+- n = (size_t)(RPM_LEAD_SIZE - rpm->total_in);
+- used += n;
+- b += n;
+- rpm->state = ST_HEADER;
+- rpm->hpos = 0;
+- rpm->hlen = 0;
+- rpm->first_header = 1;
+- }
+- break;
+- case ST_HEADER:
+- n = rpm_limit_bytes(RPM_MIN_HEAD_SIZE - rpm->hpos,
+- avail_in - used);
+- memcpy(rpm->header+rpm->hpos, b, n);
+- b += n;
+- used += n;
+- rpm->hpos += n;
+-
+- if (rpm->hpos == RPM_MIN_HEAD_SIZE) {
+- if (rpm->header[0] != 0x8e ||
+- rpm->header[1] != 0xad ||
+- rpm->header[2] != 0xe8 ||
+- rpm->header[3] != 0x01) {
+- if (rpm->first_header) {
+- archive_set_error(
+- &self->archive->archive,
+- ARCHIVE_ERRNO_FILE_FORMAT,
+- "Unrecognized rpm header");
+- return (ARCHIVE_FATAL);
+- }
+- rpm->state = ST_ARCHIVE;
+- *buff = rpm->header;
+- total = RPM_MIN_HEAD_SIZE;
+- break;
+- }
+- /* Calculate 'Header' length. */
+- section = archive_be32dec(rpm->header+8);
+- bytes = archive_be32dec(rpm->header+12);
+- rpm->hlen = rpm->hpos + section * 16 + bytes;
+- rpm->state = ST_HEADER_DATA;
+- rpm->first_header = 0;
+- }
+- break;
+- case ST_HEADER_DATA:
+- n = rpm_limit_bytes(rpm->hlen - rpm->hpos,
+- avail_in - used);
+- b += n;
+- used += n;
+- rpm->hpos += n;
+- if (rpm->hpos == rpm->hlen)
+- rpm->state = ST_PADDING;
+- break;
+- case ST_PADDING:
+- while (used < avail_in) {
+- if (*b != 0) {
+- /* Read next header. */
+- rpm->state = ST_HEADER;
+- rpm->hpos = 0;
+- rpm->hlen = 0;
+- break;
+- }
+- b++;
+- used++;
+- }
+- break;
+- case ST_ARCHIVE:
+- *buff = b;
+- total = avail_in;
+- used = avail_in;
+- break;
+- }
+- if (used == avail_in) {
+- rpm->total_in += used;
+- __archive_read_filter_consume(self->upstream, used);
+- b = NULL;
+- used = 0;
+- }
+- } while (total == 0 && avail_in > 0);
+-
+- if (used > 0 && b != NULL) {
+- rpm->total_in += used;
+- __archive_read_filter_consume(self->upstream, used);
+- }
+- return (total);
+-}
+-
+-static int
+-rpm_filter_close(struct archive_read_filter *self)
+-{
+- struct rpm *rpm;
+-
+- rpm = (struct rpm *)self->data;
+- free(rpm);
+-
+- return (ARCHIVE_OK);
+-}
+-
+diff --git a/libarchive/archive_read_support_format_all.c b/libarchive/archive_read_support_format_all.c
+index 3b53c9ad..067f2745 100644
+--- a/libarchive/archive_read_support_format_all.c
++++ b/libarchive/archive_read_support_format_all.c
+@@ -58,6 +58,7 @@ archive_read_support_format_all(struct archive *a)
+ archive_read_support_format_empty(a);
+ archive_read_support_format_lha(a);
+ archive_read_support_format_mtree(a);
++ archive_read_support_format_rpm(a);
+ archive_read_support_format_tar(a);
+ archive_read_support_format_xar(a);
+ archive_read_support_format_warc(a);
+diff --git a/libarchive/archive_read_support_format_rpm.c b/libarchive/archive_read_support_format_rpm.c
+new file mode 100644
+index 00000000..fe0e5009
+--- /dev/null
++++ b/libarchive/archive_read_support_format_rpm.c
+@@ -0,0 +1,1126 @@
++/*-
++ * Copyright (c) 2026 Davide Beatrici
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include "archive_platform.h"
++
++#ifdef HAVE_ERRNO_H
++#include <errno.h>
++#endif
++
++#ifdef HAVE_STDLIB_H
++#include <stdlib.h>
++#endif
++#ifdef HAVE_STRING_H
++#include <string.h>
++#endif
++
++#include "archive.h"
++#include "archive_endian.h"
++#include "archive_entry.h"
++#include "archive_entry_locale.h"
++#include "archive_private.h"
++#include "archive_read_private.h"
++
++#define MAX_NFILES 100000
++#define STR_SIZE_LIMIT (1024 * 1024) /* 1 MiB */
++
++#define LEAD_MAGIC "\xed\xab\xee\xdb"
++#define HEADER_MAGIC "\x8e\xad\xe8\x01\x00\x00\x00\x00"
++
++#define CPIO_END_MARK "TRAILER!!!"
++#define CPIO_END_MARK_SIZE 10
++
++#define CPIO_HEADER_STR_SIZE 16
++#define CPIO_HEADER_SVR_SIZE 110
++#define CPIO_HEADER_SVR_PATH_OFF 94
++
++#define CPIO_MAGIC_SIZE 6
++#define CPIO_MAGIC_STR "07070X"
++#define CPIO_MAGIC_SVR4_CRC "070702"
++#define CPIO_MAGIC_SVR4_NOCRC "070701"
++
++#define TAG_FILESIZES 1028
++#define TAG_FILEMODES 1030
++#define TAG_FILERDEVS 1033
++#define TAG_FILEMTIMES 1034
++#define TAG_FILEUSERNAMES 1039
++#define TAG_FILEGROUPNAMES 1040
++#define TAG_FILEDEVICES 1095
++#define TAG_FILEINODES 1096
++
++#define TAG_DIRINDEXES 1116
++#define TAG_BASENAMES 1117
++#define TAG_DIRNAMES 1118
++
++#define TAG_PAYLOADCOMPRESSOR 1125
++
++#define TAG_LONGFILESIZES 5008
++
++enum rpm_cpio_format {
++ CPIO_UNKNOWN,
++ CPIO_STR,
++ CPIO_SVR4_CRC,
++ CPIO_SVR4_NOCRC
++};
++
++struct rpm_file_info {
++ char *pathname;
++ char *uname;
++ char *gname;
++ uint64_t size;
++ uint16_t mode;
++ int32_t dev;
++ int16_t rdev;
++ uint32_t mtime;
++ uint32_t ino;
++};
++
++struct rpm_inode_info {
++ uint32_t n_files;
++ struct rpm_file_info **files;
++ uint32_t n_processed;
++};
++
++struct rpm_inode_temp_entry {
++ uint64_t ino;
++ struct rpm_file_info **files;
++ uint32_t n_files;
++ size_t capacity;
++ struct rpm_inode_temp_entry *next;
++};
++
++struct rpm_lead {
++ unsigned char magic[4];
++ unsigned char major, minor;
++ short type;
++ short archnum;
++ char name[66];
++ short osnum;
++ short signature_type;
++ char reserved[16];
++};
++
++struct rpm_header {
++ unsigned char magic[8];
++ uint32_t n_entries;
++ uint32_t data_size;
++};
++
++struct rpm_entry {
++ uint32_t tag;
++ uint32_t type;
++ int32_t offset;
++ uint32_t count;
++};
++
++struct rpm {
++ enum {
++ ST_LEAD,
++ ST_HEADER,
++ ST_PADDING,
++ ST_ARCHIVE
++ } state;
++ uint8_t first_header;
++
++ char *compressor;
++
++ uint32_t n_files;
++ uint32_t n_inodes;
++ struct rpm_file_info *files;
++ struct rpm_inode_info *inodes;
++
++ struct inode_hash_entry {
++ uint64_t ino;
++ struct rpm_inode_info *info;
++ struct inode_hash_entry *next;
++ } **inode_hash;
++
++ size_t inode_hash_size;
++
++ ssize_t entry_bytes_remaining;
++ ssize_t entry_bytes_unconsumed;
++ ssize_t entry_offset;
++ ssize_t entry_padding;
++};
++
++static int archive_read_format_rpm_bid(struct archive_read *, int);
++static int archive_read_format_rpm_read_header(struct archive_read *,
++ struct archive_entry *);
++static int archive_read_format_rpm_read_data(struct archive_read *,
++ const void **, size_t *, int64_t *);
++static int archive_read_format_rpm_read_data_skip(struct archive_read *);
++static int archive_read_format_rpm_cleanup(struct archive_read *);
++
++static int rpm_add_entry(struct archive_read *, struct archive_entry *);
++static int rpm_parse_main_header(struct archive_read *,
++ const struct rpm_header *header);
++
++static struct rpm_inode_info *rpm_get_inode(struct archive_read *, uint32_t);
++static enum rpm_cpio_format rpm_get_cpio_format(struct archive_read *);
++static uint8_t rpm_is_eof(struct archive_read *);
++
++static uint16_t rpm_be16_at(const void *buf_start,
++ const void *buf_end, const size_t off);
++static uint32_t rpm_be32_at(const void *buf_start,
++ const void *buf_end, const size_t off);
++static uint64_t rpm_be64_at(const void *buf_start,
++ const void *buf_end, const size_t off);
++
++static inline size_t rpm_limit_bytes(size_t, size_t);
++static char *rpm_strndup(struct archive_read *, const char *, size_t);
++static char *rpm_strread(struct archive_read *, size_t);
++static void rpm_strcat(struct archive_string *, const void *, const void *);
++static const char *rpm_strlist_at(const char *, const void *,
++ uint64_t, uint64_t);
++
++static void rpm_free_inode_temp_hash(struct rpm_inode_temp_entry **, size_t);
++
++int
++archive_read_support_format_rpm(struct archive *_a)
++{
++ struct archive_read *a = (struct archive_read *)_a;
++ struct rpm *rpm;
++ int r;
++
++ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
++ ARCHIVE_STATE_NEW, "archive_read_support_format_rpm");
++
++ rpm = calloc(1, sizeof(*rpm));
++ if (!rpm) {
++ archive_set_error(&a->archive,
++ ENOMEM,
++ "Can't allocate rpm data");
++ return ARCHIVE_FATAL;
++ }
++
++ r = __archive_read_register_format(a,
++ rpm,
++ "rpm",
++ archive_read_format_rpm_bid,
++ NULL,
++ archive_read_format_rpm_read_header,
++ archive_read_format_rpm_read_data,
++ archive_read_format_rpm_read_data_skip,
++ NULL,
++ archive_read_format_rpm_cleanup,
++ NULL,
++ NULL);
++
++ if (r != ARCHIVE_OK)
++ free(rpm);
++
++ return ARCHIVE_OK;
++}
++
++static int
++archive_read_format_rpm_bid(struct archive_read *a, int best_bid)
++{
++ const unsigned char *p;
++
++ (void)best_bid;
++
++ if ((p = __archive_read_ahead(a, sizeof(LEAD_MAGIC) - 1, NULL)) == NULL)
++ return -1;
++
++ if (memcmp(p, LEAD_MAGIC, sizeof(LEAD_MAGIC) - 1) == 0)
++ return 48;
++ else
++ return ARCHIVE_WARN;
++}
++
++static int
++archive_read_format_rpm_read_header(struct archive_read *a,
++ struct archive_entry *entry)
++{
++ struct rpm *rpm = a->format->data;
++ const unsigned char *p;
++ int r;
++
++ a->archive.archive_format = ARCHIVE_FORMAT_RPM;
++
++ for (;;) {
++ switch (rpm->state) {
++ case ST_LEAD: {
++ const struct rpm_lead *lead = __archive_read_ahead(a, sizeof(*lead), NULL);
++ if (lead == NULL) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Truncated lead");
++ return ARCHIVE_FATAL;
++ }
++
++ if (memcmp(lead->magic, LEAD_MAGIC, sizeof(lead->magic)) != 0) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Unrecognized lead");
++ return ARCHIVE_FATAL;
++ }
++
++ __archive_read_consume(a, sizeof(*lead));
++
++ rpm->state = ST_HEADER;
++ rpm->first_header = 1;
++ break;
++ }
++ case ST_HEADER: {
++ struct rpm_header header;
++
++ p = __archive_read_ahead(a, sizeof(header), NULL);
++ if (p == NULL) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Truncated header");
++ return ARCHIVE_FATAL;
++ }
++
++ memcpy(&header, p, sizeof(header));
++
++ if (memcmp(header.magic, HEADER_MAGIC, sizeof(header.magic)) != 0) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Unrecognized header");
++ return ARCHIVE_FATAL;
++ }
++
++ header.n_entries = archive_be32dec(&header.n_entries);
++ header.data_size = archive_be32dec(&header.data_size);
++
++ __archive_read_consume(a, sizeof(header));
++
++ r = rpm_parse_main_header(a, &header);
++ if (r != ARCHIVE_OK)
++ return r;
++
++ rpm->state = ST_PADDING;
++ break;
++ }
++ case ST_PADDING: {
++ for (;;) {
++ p = __archive_read_ahead(a, 1, NULL);
++ if (p == NULL) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Truncated padding");
++ return ARCHIVE_FATAL;
++ }
++
++ if (*p != 0)
++ break;
++
++ __archive_read_consume(a, 1);
++ }
++
++ if (rpm->first_header) {
++ rpm->first_header = 0;
++ rpm->state = ST_HEADER;
++ } else {
++ enum rpm_cpio_format cpio_format;
++
++ if (!rpm->compressor) {
++ /* No compression. */
++ } else if (strcmp(rpm->compressor, "zstd") == 0) {
++ r = archive_read_append_filter(&a->archive, ARCHIVE_FILTER_ZSTD);
++ } else if (strcmp(rpm->compressor, "xz") == 0) {
++ archive_read_append_filter(&a->archive, ARCHIVE_FILTER_XZ);
++ } else if (strcmp(rpm->compressor, "gzip") == 0) {
++ archive_read_append_filter(&a->archive, ARCHIVE_FILTER_GZIP);
++ } else if (strcmp(rpm->compressor, "bzip2") == 0) {
++ archive_read_append_filter(&a->archive, ARCHIVE_FILTER_BZIP2);
++ } else if (strcmp(rpm->compressor, "lzma") == 0) {
++ archive_read_append_filter(&a->archive, ARCHIVE_FILTER_LZMA);
++ } else {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Unrecognized compressor: %s", rpm->compressor);
++ return ARCHIVE_FATAL;
++ }
++
++ if (r != ARCHIVE_OK) {
++ archive_set_error(&a->archive, r, "Cannot append %s filter",
++ rpm->compressor);
++ return r;
++ }
++
++ cpio_format = rpm_get_cpio_format(a);
++ switch (cpio_format) {
++ case CPIO_STR:
++ a->archive.archive_format_name = "RPM (stripped CPIO)";
++ break;
++ case CPIO_SVR4_CRC:
++ a->archive.archive_format_name = "RPM (SVR4 cpio with CRC)";
++ break;
++ case CPIO_SVR4_NOCRC:
++ a->archive.archive_format_name = "RPM (SVR4 cpio with no CRC)";
++ break;
++ case CPIO_UNKNOWN:
++ default:
++ return ARCHIVE_FATAL;
++ }
++
++ rpm->state = ST_ARCHIVE;
++ }
++ break;
++ }
++ case ST_ARCHIVE:
++ return rpm_add_entry(a, entry);
++ }
++ }
++}
++
++static int
++archive_read_format_rpm_read_data(struct archive_read *a,
++ const void **buff, size_t *size, int64_t *offset)
++{
++ struct rpm *rpm = a->format->data;
++ ssize_t bytes_read;
++
++ if (rpm->entry_bytes_unconsumed > 0) {
++ __archive_read_consume(a, rpm->entry_bytes_unconsumed);
++ rpm->entry_bytes_unconsumed = 0;
++ }
++
++ if (rpm->entry_bytes_remaining > 0) {
++ *buff = __archive_read_ahead(a, 1, &bytes_read);
++ if (bytes_read <= 0)
++ return ARCHIVE_FATAL;
++
++ if (bytes_read > rpm->entry_bytes_remaining)
++ bytes_read = (ssize_t)rpm->entry_bytes_remaining;
++
++ *size = bytes_read;
++ rpm->entry_bytes_unconsumed = bytes_read;
++ *offset = rpm->entry_offset;
++ rpm->entry_offset += bytes_read;
++ rpm->entry_bytes_remaining -= bytes_read;
++
++ return ARCHIVE_OK;
++ } else {
++ if (rpm->entry_padding !=
++ __archive_read_consume(a, rpm->entry_padding)) {
++ return ARCHIVE_FATAL;
++ }
++
++ rpm->entry_padding = 0;
++ *buff = NULL;
++ *size = 0;
++ *offset = rpm->entry_offset;
++
++ return ARCHIVE_EOF;
++ }
++}
++
++static int
++archive_read_format_rpm_read_data_skip(struct archive_read *a)
++{
++ struct rpm *rpm = a->format->data;
++ const ssize_t to_skip = rpm->entry_bytes_remaining + rpm->entry_padding
++ + rpm->entry_bytes_unconsumed;
++
++ if (to_skip != __archive_read_consume(a, to_skip))
++ return ARCHIVE_FATAL;
++
++ rpm->entry_bytes_remaining = 0;
++ rpm->entry_padding = 0;
++ rpm->entry_bytes_unconsumed = 0;
++
++ return ARCHIVE_OK;
++}
++
++static int
++archive_read_format_rpm_cleanup(struct archive_read *a)
++{
++ struct rpm *rpm = a->format->data;
++ size_t i;
++
++ free(rpm->compressor);
++
++ if (rpm->inode_hash) {
++ for (i = 0; i < rpm->inode_hash_size; ++i) {
++ free(rpm->inode_hash[i]);
++ }
++
++ free(rpm->inode_hash);
++ }
++
++ if (rpm->inodes != NULL) {
++ for (i = 0; i < rpm->n_inodes; i++) {
++ free(rpm->inodes[i].files);
++ }
++
++ free(rpm->inodes);
++ }
++
++ if (rpm->files != NULL) {
++ for (i = 0; i < rpm->n_files; i++) {
++ free(rpm->files[i].pathname);
++ free(rpm->files[i].uname);
++ free(rpm->files[i].gname);
++ }
++
++ free(rpm->files);
++ }
++
++ free(rpm);
++
++ a->format->data = NULL;
++
++ return ARCHIVE_OK;
++}
++
++static int
++rpm_add_entry(struct archive_read *a, struct archive_entry *entry)
++{
++ struct rpm *rpm = a->format->data;
++ struct rpm_file_info *file = NULL;
++ struct rpm_inode_info *inode;
++ uint64_t idx_ino;
++ const void *p;
++
++ const enum rpm_cpio_format cpio_format = rpm_get_cpio_format(a);
++
++ p = __archive_read_ahead(a, CPIO_HEADER_STR_SIZE, NULL);
++ if (!p) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Premature EOF");
++ return ARCHIVE_FATAL;
++ }
++
++ char hex_str[9] = {0};
++ memcpy(hex_str, p + CPIO_MAGIC_SIZE, sizeof(idx_ino));
++ idx_ino = strtoull(hex_str, NULL, 16);
++
++ switch (cpio_format) {
++ case CPIO_STR:
++ __archive_read_consume(a, CPIO_HEADER_STR_SIZE);
++
++ if (rpm_is_eof(a))
++ return ARCHIVE_EOF;
++
++ if (idx_ino >= rpm->n_files) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "File index %" PRIu64 " out of range (max %u)", idx_ino, rpm->n_files - 1);
++ return ARCHIVE_FATAL;
++ }
++
++ file = &rpm->files[idx_ino];
++ inode = rpm_get_inode(a, file->ino);
++ if (!inode)
++ return ARCHIVE_FATAL;
++
++ break;
++ case CPIO_SVR4_CRC:
++ case CPIO_SVR4_NOCRC: {
++ size_t i;
++ uint64_t size;
++ char *path;
++
++ p = __archive_read_ahead(a, CPIO_HEADER_SVR_SIZE, NULL);
++ if (!p) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Truncated SVR4 header");
++ return ARCHIVE_FATAL;
++ }
++
++ memcpy(hex_str, p + CPIO_HEADER_SVR_PATH_OFF, sizeof(size));
++
++ __archive_read_consume(a, CPIO_HEADER_SVR_SIZE);
++
++ if (rpm_is_eof(a))
++ return ARCHIVE_EOF;
++
++ inode = rpm_get_inode(a, idx_ino);
++ if (!inode)
++ return ARCHIVE_FATAL;
++
++ size = strtoull(hex_str, NULL, 16);
++
++ path = rpm_strread(a, size);
++ if (!path)
++ return ARCHIVE_FATAL;
++
++ for (i = 0; i < inode->n_files; ++i) {
++ if (strcmp(inode->files[i]->pathname, path) == 0) {
++ file = inode->files[i];
++ break;
++ }
++ }
++
++ free(path);
++
++ if (!file) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Path not found");
++ return ARCHIVE_FATAL;
++ }
++
++ /* Pad name to 2 more than a multiple of 4. */
++ size += (2 - size) & 3;
++ __archive_read_consume(a, size);
++
++ break;
++ }
++ default:
++ return ARCHIVE_FATAL;
++ }
++
++ archive_entry_set_pathname_utf8(entry, file->pathname);
++ archive_entry_set_uname_utf8(entry, file->uname);
++ archive_entry_set_gname_utf8(entry, file->gname);
++ archive_entry_set_dev(entry, file->dev);
++ archive_entry_set_ino(entry, file->ino);
++ archive_entry_set_mode(entry, file->mode);
++ archive_entry_set_rdev(entry, file->rdev);
++ archive_entry_set_mtime(entry, file->mtime, 0);
++ archive_entry_set_nlink(entry, inode->n_files);
++
++ /* Hardlink: only last entry carries payload */
++ if (++inode->n_processed == inode->n_files)
++ rpm->entry_bytes_remaining = file->size;
++ else
++ rpm->entry_bytes_remaining = 0;
++
++ /* Pad file contents to a multiple of 4. */
++ rpm->entry_padding = 3 & -rpm->entry_bytes_remaining;
++ rpm->entry_offset = 0;
++ rpm->entry_bytes_unconsumed = 0;
++
++ if (S_ISLNK(file->mode)) {
++ char *target = rpm_strread(a, file->size);
++ if (!target)
++ return ARCHIVE_FATAL;
++
++ __archive_read_consume(a, rpm->entry_bytes_remaining);
++ rpm->entry_bytes_remaining = 0;
++
++ archive_entry_set_symlink_utf8(entry, target);
++
++ free(target);
++ }
++
++ archive_entry_set_size(entry, rpm->entry_bytes_remaining);
++
++ return ARCHIVE_OK;
++}
++
++static int
++rpm_parse_main_header(struct archive_read *a, const struct rpm_header *header)
++{
++ struct rpm *rpm = a->format->data;
++
++ struct rpm_header_parse {
++ uint32_t n_files;
++
++ const char *basenames;
++ uint32_t n_basenames;
++
++ const char *dirnames;
++ uint32_t n_dirnames;
++
++ const char *usernames;
++ uint32_t n_usernames;
++
++ const char *groupnames;
++ uint32_t n_groupnames;
++
++ union {
++ const int64_t *filesizes64;
++ const int32_t *filesizes32;
++ };
++ uint8_t is_filesizes64;
++
++ const int32_t *dirindexes;
++ const int16_t *filemodes;
++ const int32_t *filedevices;
++ const int16_t *filerdevs;
++ const int32_t *filemtimes;
++ const int32_t *fileinodes;
++ } hp;
++
++ const struct rpm_entry *entries;
++ struct rpm_inode_temp_entry **temp_hash;
++ size_t hlen, temp_hash_size = 1;
++ uint64_t i, ino = 0;
++
++ memset(&hp, 0, sizeof(hp));
++
++ hlen = sizeof(struct rpm_entry)
++ * (size_t)header->n_entries
++ + (size_t)header->data_size;
++
++ entries = __archive_read_ahead(a, hlen, NULL);
++ if (entries == NULL)
++ return ARCHIVE_EOF;
++
++ if (rpm->first_header) {
++ __archive_read_consume(a, hlen);
++ return ARCHIVE_OK;
++ }
++
++ for (i = 0; i < header->n_entries; i++) {
++ uint32_t tag, cnt;
++ int32_t off;
++ const void *p;
++
++ tag = archive_be32dec(&entries[i].tag);
++ off = archive_be32dec(&entries[i].offset);
++ cnt = archive_be32dec(&entries[i].count);
++
++ if (off < 0 || (uint32_t)off >= header->data_size)
++ continue;
++
++ p = (const uint8_t *)&entries[header->n_entries] + off;
++
++ switch (tag) {
++ case TAG_PAYLOADCOMPRESSOR:
++ rpm->compressor = rpm_strndup(a, p ? p : "", 0);
++ break;
++ case TAG_BASENAMES:
++ hp.basenames = p;
++ hp.n_basenames = cnt;
++ break;
++ case TAG_DIRNAMES:
++ hp.dirnames = p;
++ hp.n_dirnames = cnt;
++ break;
++ case TAG_FILEUSERNAMES:
++ hp.usernames = p;
++ hp.n_usernames = cnt;
++ break;
++ case TAG_FILEGROUPNAMES:
++ hp.groupnames = p;
++ hp.n_groupnames = cnt;
++ break;
++ case TAG_LONGFILESIZES:
++ hp.filesizes64 = p;
++ hp.n_files = cnt;
++ hp.is_filesizes64 = 1;
++ break;
++ case TAG_FILESIZES:
++ /* This tag should never appear when Longfilesizes is present,
++ * but checking doesn't hurt. */
++ if (!hp.is_filesizes64) {
++ hp.filesizes32 = p;
++ hp.n_files = cnt;
++ }
++ break;
++ case TAG_DIRINDEXES:
++ hp.dirindexes = p;
++ break;
++ case TAG_FILEINODES:
++ hp.fileinodes = p;
++ break;
++ case TAG_FILEMODES:
++ hp.filemodes = p;
++ break;
++ case TAG_FILEDEVICES:
++ hp.filedevices = p;
++ break;
++ case TAG_FILERDEVS:
++ hp.filerdevs = p;
++ break;
++ case TAG_FILEMTIMES:
++ hp.filemtimes = p;
++ break;
++ }
++ }
++
++ if (hp.n_files >= MAX_NFILES) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "n_files out of range");
++ return ARCHIVE_FATAL;
++ }
++
++ rpm->files = calloc(hp.n_files, sizeof(*rpm->files));
++ if (rpm->files == NULL) {
++ archive_set_error(&a->archive,
++ ENOMEM,
++ "Can't allocate files data");
++ return ARCHIVE_FATAL;
++ }
++
++ rpm->n_files = hp.n_files;
++
++ while (temp_hash_size < hp.n_files * 2)
++ temp_hash_size <<= 1;
++
++ temp_hash = calloc(temp_hash_size, sizeof(*temp_hash));
++ if (!temp_hash) {
++ archive_set_error(&a->archive,
++ ENOMEM,
++ "Can't allocate temp hash");
++ return ARCHIVE_FATAL;
++ }
++
++ for (i = 0; i < hp.n_files; i++) {
++ const void *hbuf_end = (const uint8_t *)entries + hlen;
++ struct rpm_file_info *file = &rpm->files[i];
++ struct rpm_inode_temp_entry *group;
++ struct archive_string as;
++ const char *dname, *bname, *uname, *gname;
++ size_t bucket;
++
++ if (hp.dirindexes != NULL) {
++ const uint32_t diri = rpm_be32_at(hp.dirindexes, hbuf_end, i);
++
++ if (diri >= hp.n_dirnames) {
++ rpm_free_inode_temp_hash(temp_hash, temp_hash_size);
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "dirindex out of range");
++ return ARCHIVE_FATAL;
++ }
++
++ dname = rpm_strlist_at(hp.dirnames, hbuf_end, diri, hp.n_dirnames);
++ } else
++ dname = NULL;
++
++ bname = rpm_strlist_at(hp.basenames, hbuf_end, i, hp.n_basenames);
++ uname = rpm_strlist_at(hp.usernames, hbuf_end, i, hp.n_usernames);
++ gname = rpm_strlist_at(hp.groupnames, hbuf_end, i, hp.n_groupnames);
++
++ archive_string_init(&as);
++ archive_strappend_char(&as, '.');
++ rpm_strcat(&as, dname, hbuf_end);
++ rpm_strcat(&as, bname, hbuf_end);
++ file->pathname = strdup(as.s);
++ archive_string_free(&as);
++
++ file->uname = rpm_strndup(a, uname ? uname : "", 0);
++ file->gname = rpm_strndup(a, gname ? gname : "", 0);
++
++ if (hp.is_filesizes64)
++ file->size = rpm_be64_at(hp.filesizes64, hbuf_end, i);
++ else
++ file->size = rpm_be32_at(hp.filesizes32, hbuf_end, i);
++ file->mode = rpm_be16_at(hp.filemodes, hbuf_end, i);
++ file->dev = rpm_be32_at(hp.filedevices, hbuf_end, i);
++ file->rdev = rpm_be16_at(hp.filerdevs, hbuf_end, i);
++ file->mtime = rpm_be32_at(hp.filemtimes, hbuf_end, i);
++ file->ino = rpm_be32_at(hp.fileinodes, hbuf_end, i);
++
++ bucket = file->ino & (temp_hash_size - 1);
++ group = temp_hash[bucket];
++
++ while (group) {
++ if (group->ino == file->ino)
++ break;
++
++ group = group->next;
++ }
++
++ if (!group) {
++ group = calloc(1, sizeof(*group));
++ if (!group) {
++ rpm_free_inode_temp_hash(temp_hash, temp_hash_size);
++ archive_set_error(&a->archive,
++ ENOMEM,
++ "Can't allocate inode group");
++ return ARCHIVE_FATAL;
++ }
++
++ group->ino = file->ino;
++ group->files = NULL;
++ group->n_files = 0;
++ group->capacity = 0;
++
++ group->next = temp_hash[bucket];
++ temp_hash[bucket] = group;
++ }
++
++ if (group->n_files >= group->capacity) {
++ group->capacity = group->capacity ? group->capacity * 2 : 8;
++ void *prev_ptr = group->files;
++
++ group->files = realloc(group->files, group->capacity * sizeof(*group->files));
++ if (!group->files) {
++ free(prev_ptr);
++ rpm_free_inode_temp_hash(temp_hash, temp_hash_size);
++ archive_set_error(&a->archive,
++ ENOMEM,
++ "Can't grow inode file list");
++ return ARCHIVE_FATAL;
++ }
++ }
++
++ group->files[group->n_files++] = file;
++ }
++
++ rpm->n_inodes = 0;
++ for (i = 0; i < temp_hash_size; i++) {
++ for (struct rpm_inode_temp_entry *e = temp_hash[i]; e; e = e->next)
++ rpm->n_inodes++;
++ }
++
++ rpm->inodes = calloc(rpm->n_inodes, sizeof(*rpm->inodes));
++ if (!rpm->inodes) {
++ rpm_free_inode_temp_hash(temp_hash, temp_hash_size);
++ archive_set_error(&a->archive,
++ ENOMEM,
++ "Can't allocate inodes array");
++ return ARCHIVE_FATAL;
++ }
++
++ for (i = 0; i < temp_hash_size; i++) {
++ struct rpm_inode_temp_entry *e = temp_hash[i];
++ while (e) {
++ struct rpm_inode_info *info = &rpm->inodes[ino++];
++ info->n_files = e->n_files;
++ info->files = e->files;
++ info->n_processed = 0;
++
++ struct rpm_inode_temp_entry *next = e->next;
++ free(e);
++ e = next;
++ }
++ }
++
++ free(temp_hash);
++
++ rpm->inode_hash_size = 1;
++ while (rpm->inode_hash_size < rpm->n_inodes * 2)
++ rpm->inode_hash_size <<= 1;
++
++ rpm->inode_hash = calloc(rpm->inode_hash_size, sizeof(*rpm->inode_hash));
++ if (!rpm->inode_hash) {
++ archive_set_error(&a->archive,
++ ENOMEM,
++ "Can't allocate inode hash");
++ return ARCHIVE_FATAL;
++ }
++
++ for (i = 0; i < rpm->n_inodes; i++) {
++ uint64_t raw = rpm->inodes[i].files[0]->ino;
++ size_t bucket = raw & (rpm->inode_hash_size - 1);
++
++ struct inode_hash_entry *e = malloc(sizeof(*e));
++ if (!e) {
++ archive_set_error(&a->archive,
++ ENOMEM,
++ "Can't allocate inode hash entry");
++ return ARCHIVE_FATAL;
++ }
++
++ e->ino = raw;
++ e->info = &rpm->inodes[i];
++ e->next = rpm->inode_hash[bucket];
++ rpm->inode_hash[bucket] = e;
++ }
++
++ __archive_read_consume(a, hlen);
++
++ return ARCHIVE_OK;
++}
++
++static struct rpm_inode_info *
++rpm_get_inode(struct archive_read *a, const uint32_t ino)
++{
++ const struct rpm *rpm = a->format->data;
++ struct inode_hash_entry *e;
++ size_t bucket;
++
++ if (!rpm->inode_hash)
++ return NULL;
++
++ bucket = ino & (rpm->inode_hash_size - 1);
++
++ for (e = rpm->inode_hash[bucket]; e; e = e->next)
++ if (e->ino == ino)
++ return e->info;
++
++ return NULL;
++}
++
++static enum rpm_cpio_format
++rpm_get_cpio_format(struct archive_read *a)
++{
++ const char *magic = __archive_read_ahead(a, CPIO_MAGIC_SIZE, NULL);
++ if (!magic) {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Premature EOF");
++ return ARCHIVE_FATAL;
++ }
++
++ if (memcmp(magic, CPIO_MAGIC_STR, CPIO_MAGIC_SIZE) == 0)
++ return CPIO_STR;
++ else if (memcmp(magic, CPIO_MAGIC_SVR4_CRC, CPIO_MAGIC_SIZE) == 0)
++ return CPIO_SVR4_CRC;
++ else if (memcmp(magic, CPIO_MAGIC_SVR4_NOCRC, CPIO_MAGIC_SIZE) == 0)
++ return CPIO_SVR4_NOCRC;
++ else {
++ archive_set_error(&a->archive,
++ ARCHIVE_ERRNO_FILE_FORMAT,
++ "Unrecognized magic");
++ return CPIO_UNKNOWN;
++ }
++}
++
++static uint8_t
++rpm_is_eof(struct archive_read *a)
++{
++ const void *p = __archive_read_ahead(a, CPIO_END_MARK_SIZE, NULL);
++ if (!p)
++ return 1;
++
++ return memcmp(p, CPIO_END_MARK, CPIO_END_MARK_SIZE) == 0;
++}
++
++static uint16_t
++rpm_be16_at(const void *buf_start, const void *buf_end, size_t off)
++{
++ off *= sizeof(uint16_t);
++
++ if (!buf_start || (buf_end <= buf_start) ||
++ (size_t)(buf_end - buf_start) < (off + sizeof(uint16_t)))
++ return 0;
++
++ return archive_be16dec(buf_start + off);
++}
++
++static uint32_t
++rpm_be32_at(const void *buf_start, const void *buf_end, size_t off)
++{
++ off *= sizeof(uint32_t);
++
++ if (!buf_start || (buf_end <= buf_start) ||
++ (size_t)(buf_end - buf_start) < (off + sizeof(uint32_t)))
++ return 0;
++
++ return archive_be32dec(buf_start + off);
++}
++
++static uint64_t
++rpm_be64_at(const void *buf_start, const void *buf_end, size_t off)
++{
++ off *= sizeof(uint64_t);
++
++ if (!buf_start || (buf_end <= buf_start) ||
++ (size_t)(buf_end - buf_start) < (off + sizeof(uint64_t)))
++ return 0;
++
++ return archive_be64dec(buf_start + off);
++}
++
++static inline size_t
++rpm_limit_bytes(const size_t bytes, const size_t max)
++{
++ return (bytes > max ? max : bytes);
++}
++
++static char *
++rpm_strndup(struct archive_read *a, const char *s, size_t len)
++{
++ if (s == NULL)
++ return NULL;
++
++ if (len == 0)
++ len = strnlen(s, STR_SIZE_LIMIT);
++
++ if (len > STR_SIZE_LIMIT) {
++ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
++ "String too long (malformed?)");
++ return NULL;
++ }
++
++ return strndup(s, len);
++}
++
++static char *
++rpm_strread(struct archive_read *a, size_t len) {
++ const void *p;
++
++ if (len > STR_SIZE_LIMIT) {
++ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
++ "String too long");
++ return NULL;
++ }
++
++ p = __archive_read_ahead(a, len, NULL);
++ if (!p) {
++ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
++ "Truncated string");
++ return NULL;
++ }
++
++ return rpm_strndup(a, p, len);
++}
++
++static void
++rpm_strcat(struct archive_string *a, const void *s, const void *buf_end)
++{
++ if (!s || s >= buf_end)
++ return;
++
++ archive_strncat(a, s, rpm_limit_bytes(buf_end - s, STR_SIZE_LIMIT));
++}
++
++static const char *
++rpm_strlist_at(const char *p, const void *end, uint64_t i, uint64_t n)
++{
++ uint64_t k;
++
++ if (p == NULL || i >= n || (const char *)end < p)
++ return NULL;
++
++ for (k = 0; k < n; k++) {
++ const uint64_t max_len = rpm_limit_bytes((const char *)end - p,
++ STR_SIZE_LIMIT);
++ const uint64_t len = strnlen(p, max_len);
++ if (len == max_len)
++ /* Unterminated or absurdly long string. */
++ return NULL;
++
++ if (k == i)
++ return p;
++
++ p += len + 1;
++
++ if (p >= (const char *)end)
++ return NULL;
++ }
++
++ return NULL;
++}
++
++static void
++rpm_free_inode_temp_hash(struct rpm_inode_temp_entry **hash, const size_t hash_size)
++{
++ for (size_t i = 0; i < hash_size; i++) {
++ struct rpm_inode_temp_entry *e = hash[i];
++ while (e) {
++ struct rpm_inode_temp_entry *next = e->next;
++ free(e->files);
++ free(e);
++ e = next;
++ }
++ }
++
++ free(hash);
++}
+diff --git a/libarchive/test/test_archive_read_support.c b/libarchive/test/test_archive_read_support.c
+index b0c92802..bc256a17 100644
+--- a/libarchive/test/test_archive_read_support.c
++++ b/libarchive/test/test_archive_read_support.c
+@@ -91,6 +91,7 @@ DEFINE_TEST(test_archive_read_support)
+ test_filter_or_format(archive_read_support_format_iso9660);
+ test_filter_or_format(archive_read_support_format_lha);
+ test_filter_or_format(archive_read_support_format_mtree);
++ test_filter_or_format(archive_read_support_format_rpm);
+ test_filter_or_format(archive_read_support_format_tar);
+ test_filter_or_format(archive_read_support_format_xar);
+ test_filter_or_format(archive_read_support_format_zip);
+@@ -140,7 +141,6 @@ DEFINE_TEST(test_archive_read_support)
+ test_filter_or_format(archive_read_support_filter_lzip);
+ test_filter_or_format(archive_read_support_filter_lzma);
+ test_filter_or_format(archive_read_support_filter_none);
+- test_filter_or_format(archive_read_support_filter_rpm);
+ test_filter_or_format(archive_read_support_filter_uu);
+ test_filter_or_format(archive_read_support_filter_xz);
+ }
+diff --git a/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c b/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c
+index cff64d72..c775e6f4 100644
+--- a/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c
++++ b/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c
+@@ -97,8 +97,6 @@ DEFINE_TEST(test_read_format_cpio_svr4_bzip2_rpm)
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, r);
+- assertEqualIntA(a, ARCHIVE_OK,
+- archive_read_support_filter_rpm(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
+@@ -121,7 +119,7 @@ DEFINE_TEST(test_read_format_cpio_svr4_bzip2_rpm)
+ /* Verify that the format detection worked. */
+ assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_BZIP2);
+ assertEqualString(archive_filter_name(a, 0), "bzip2");
+- assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);
++ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_RPM);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+diff --git a/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c b/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c
+index 345760c1..913dc793 100644
+--- a/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c
++++ b/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c
+@@ -97,8 +97,6 @@ DEFINE_TEST(test_read_format_cpio_svr4_gzip_rpm)
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, r);
+- assertEqualIntA(a, ARCHIVE_OK,
+- archive_read_support_filter_rpm(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
+@@ -121,8 +119,8 @@ DEFINE_TEST(test_read_format_cpio_svr4_gzip_rpm)
+ /* Verify that the format detection worked. */
+ assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_GZIP);
+ assertEqualString(archive_filter_name(a, 0), "gzip");
+- assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);
+-
++ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_RPM);
++
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ }
+diff --git a/libarchive/test/test_read_format_huge_rpm.c b/libarchive/test/test_read_format_huge_rpm.c
+index 729c1e18..b56dfbed 100644
+--- a/libarchive/test/test_read_format_huge_rpm.c
++++ b/libarchive/test/test_read_format_huge_rpm.c
+@@ -40,9 +40,7 @@ DEFINE_TEST(test_read_format_huge_rpm)
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify that the format detection worked. */
+- assertEqualInt(ARCHIVE_FILTER_RPM, archive_filter_code(a, 0));
+- assertEqualString("rpm", archive_filter_name(a, 0));
+- assertEqualInt(ARCHIVE_FORMAT_EMPTY, archive_format(a));
++ assertEqualInt(ARCHIVE_FORMAT_RPM, archive_format(a));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+--
+2.49.0
+
diff --git a/meta/recipes-extended/libarchive/libarchive_3.8.6.bb b/meta/recipes-extended/libarchive/libarchive_3.8.6.bb
index d579cdb65a..4e1f6b08b5 100644
--- a/meta/recipes-extended/libarchive/libarchive_3.8.6.bb
+++ b/meta/recipes-extended/libarchive/libarchive_3.8.6.bb
@@ -31,6 +31,9 @@ EXTRA_OECONF += "--enable-largefile --without-iconv"
SRC_URI = "https://libarchive.org/downloads/libarchive-${PV}.tar.gz \
file://run-ptest \
+ file://0001-archive_read_append_filter-Keep-iterating-even-if-na.patch \
+ file://0002-__archive_read_register_bidder-Allow-ARCHIVE_STATE_H.patch \
+ file://0003-Convert-RPM-reader-into-a-proper-format-supporting-b.patch \
"
UPSTREAM_CHECK_URI = "https://www.libarchive.org/"
--
2.49.0
^ permalink raw reply related [flat|nested] 17+ messages in thread