IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an
email to Administrator. User accounts are meant only to access repo
and report issues and/or generate pull requests.
This is a purpose-specific Git hosting for
BaseALT
projects. Thank you for your understanding!
Только зарегистрированные пользователи имеют доступ к сервису!
Для получения аккаунта, обратитесь к администратору.
PreReqs differ from regular requirements, they need special treatment.
Also do not add RPMSENSE_FIND_REQUIRES unnecessarily.
Fixes: 4.0.4-alt122~2 ("addReqProv: implement dep flags merge")
lld linked binaries differ by structure from GNU ld, so eu-lint will
always complaint about. Allow to skip those checks by passing
%set_verify_elf_method lint=(skip|no)
Signed-off-by: Konstantin A. Lepikhov <lakostis@altlinux.ru>
- Dropped $RPM_STRICT_INTERDEPS support
(introduced in 4.0.4-alt110).
- Made name, version, release, and disttag check stricter
(by vseleznv@ and me).
- Changed the generator of package self-provides
and the generator of strict intersubpackage dependencies
to use [E:]V-R[:D] format instead of [E:]V-R
(by vseleznv@ and me).
- addReqProv: implemented dep flags merge:
when a stronger requirement is added while a weaker one already exists
with incompatible flags, try to merge these flags to produce a new
stronger requirement. For example,
"PreReq: %name = %version" + "Requires: %name = %version-%release"
now results to "PreReq: %name = %version-%release".
When a stronger requirement is added while a weaker one already exists
with incompatible flags, try to merge these flags to produce a new
stronger requirement.
For example,
"PreReq: %name = %version" + "Requires: %name = %version-%release"
now results to "PreReq: %name = %version-%release", and
"PreReq: %name = %EVR" + "Requires: %name = %EVRD"
now results to "PreReq: %name = %EVRD".
Backport rpmCharCheck() from rpm-4.13.0.1-release, replace rasprintf()
and risalnum() with asprintf() and isalnum() respectively, check
VERSION and RELEASE tags against whitelisted characters. The whitelist
only contains all alphanumeric symbols as well as "._+" symbols.
[ldv:
Rewritten, all code from rpm is terrible.
Extended to NAME and DISTTAG.]
This enhances ProvidedSymbols() in two ways:
* fixes st_shndx check for the case when it is not $7 in
"readelf --wide --dyn-syms" output as it happens on some architectures
like ppc64le;
* filters out special symbols (__bss_start, _edata, _end, _fini, _init)
after stripping of versioning.
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
- Add _allow_deps_with_beginning_dot macro to allow dependencies
beginning with a dot character (such as ones generated by replaceDeps
function) in spec file (vseleznv@).
After commit f4d876f93 rpm-build may generate dependencies beginning
with a dot character, but spec parser refuses such dependencies.
rpmrebuild fails to rebuild packages with such dependencies because it
builds packages with rpmbuild from generated spec files.
Most of the binaries on mipsel do not contain the stack section,
so this check is not relevant for that architecture. Morover,
it fails, since it can't find the stack section, which is
(rightfully) not present.
eu-elflint does not understand mipsel binaries currently,
so here we disable that check, too.
The code in question uses an improvised "strntoul" function (hidden
behind the GET_NUM_FIELD macro) which returns "int".
int cpioHeaderRead(FSM_t fsm, struct stat * st)
...
GET_NUM_FIELD(hdr.filesize, st->st_size);
When a file size undergoes an "int bottleneck", it cannot be safely
converted back to an unsigned 64-bit integer. By the C rules, if the
size is in the range 2G..4G-1, int becomes negative (or this may be
undefined behaviour already, I'm not a language lawyer), and conversion
to unsigned 64-bit is performed as if by adding 2^64 to the negative
value.
So you get a huge 64-bit file size. Funnily enough, if you truncate it
to 32 bits, it's back to normal! That's why things worked with 32-bit
size_t.
static int expandRegular(/*@special@*/ FSM_t fsm)
...
size_t left = st->st_size;
- Implemented limited support for large files: a 2GB+ file can now be packaged,
but the total size of uncompressed cpio payload is capped at 4 GB.
- Automatically downgrade LZMA compression levels 7-9 -> 6 on small payloads.
- Implemented limited support for large files: a 2GB+ file can now be packaged,
but the total size of uncompressed cpio payload is capped at 4 GB.
- Automatically downgrade LZMA compression levels 7-9 -> 6 on small payloads.
This is probably the last change of such kind. There are many other
instances left, and fixing them all is hopeless. On the other hand,
the way mod 2^32 arithmetic works, although technically not always
well defined, is to our advantage. I suggest that only user-visible
discrepancies further be fixed.
The following comparison to st_size looks particularly bad.
The code turns out to be unused!
lib/signature.c:
> verifySizeSignature(const char * datafile, int_32 size, /*@out@*/ char * result)
> [...]
> if (size != st.st_size) {
> sprintf(result, "Header+Archive size mismatch.\n"
Some of the preceding code is probably undefined or unspecified behavior,
but there's no easy way to fix it other than rewriting, which I'm not
going to do. Surprisingly enough, the code just happens to work, due to
a series of mutual cancellations mod 2^32. As they say in Russian,
the war will write off all. Likewise, mod 2^32 arithmetic can write off
a multitude of sins (James 5:20).
> static inline rpmRC checkSize(FD_t fd, int siglen, int pad, int datalen)
[...]
> int delta;
[...]
> delta = (sizeof(struct rpmlead) + siglen + pad + datalen) - st.st_size;
Here, the expression in parentheses yields a different numeric value
depending on whether datalen is signed or unsigned. However, when delta
is finally truncated to 32 bits, the result turns out to be the same.
> switch (delta) {
> case -32: /* XXX rpm-4.0 packages */
> case 32: /* XXX Legacy headers have a HEADER_IMAGE tag added. */
> case 0:
The diff context is just big enough to see what happens.
RPMTAG_FILESIZES are interpreted as signed integers, and st_size which
has type off_t is also signed. So the 32-bit file size form the header
gets sign-extended, after which the equality to st_size does not hold.
This completes support for building packages with 2G+ files, more or
less (packaging 4G+ files is still a distant goal). I am able to build
a valid package with a 3G sparse file on both i586 and x86-64. On i586,
though, such a package cannot be installed with rpm-4.0:
error: unpacking of archive failed on file /usr/bin/6;5a70a676:
cpio: write failed - File too large
I believe there is no obvious way to identify and mark such packages,
since rpmlib(LargeFiles) dependency is meant only for 4G+ files, which
require 07070X cpio entries.
Therefore, limited support for handling such packages shall be provided
for rpm-4.0 in branch p8 (there are issues other than simply enabling
AC_SYS_LARGEFILE).
This turns out to be a bit easier than I thought yesterday. When mmap
fails in lib/fsm.c, it falls back to file descriptor IO. So by simply
enabling AC_SYS_LARGEFILE, I'm already able to package a 3G file, which
can be written like this:
perl -e 'seek STDOUT,3<<30,0 and print 1 or die' >out
The nearest goal is to be able to package files up to 4G, on both 32-bit
64-bit architectures, provided that cpio payload size also does not
exceed 4G. More specifically, the limit is 2^32-2, while 2^32-1 remains
special (this is not my own invention, I adopt it from rpm.org).
If the limit is exceeded, rpmbuild should fail gracefully instead of
writing malformed packages with truncated integer tags.
(Supporting 4G+ files is a distant goal - neither rpm-4.0 nor apt-rpm
can handle them yet. Besides, it's not clear if producing such big
packages is even a good idea, unless one wishes to package p0rn.)
This is the reason why files >= 2G could not be added to cpio, even on
64-bit architectures. Fwrite was called with a buffer >= 2G, but the
return value was truncated to int (this narrowing conversion is probably
undefined behavior already; what happens next, though, is that after
casting to size_t it assumes a very big numeric value of >= 2^64-2^32).
So rpmbuild was failing with an unrelated errno, "cpio: write failed -
Bad file descriptor".
There are other reasons why this still won't work on 32-bit architectures.
For one, rpmbuild mmaps a file before feeding it to cpio, and 32-bit
architectures have a very limited ability, if any, to mmap 2G+ files.