Commit Graph

1885 Commits

Author SHA1 Message Date
Panu Matilainen 493f4f7f32 Eliminate pthread_once from global config dir initialization
C++ guarantees static initializers run in a thread-safe manner,
move the confdir initialization to a constructor of a tiny object
and voila we don't need the pthread once dance.
2024-09-24 10:08:38 +02:00
Panu Matilainen 31de9dc548 Eliminate an unnecessary round of locking from every rpmlog() call
On entry to rpmlog() we compare the log mask to see if it's something
we need to act on at all. Since we've been using rpmlogSetMask() for
this, each and every RPMLOG_DEBUG etc call that is not normally logged
stops on its way to take at least one read mutex to do nothing at all.
Which is nuts.

rpmlogSetMask() technically does need the mutex lock because it both reads
and writes, and something could come in between. But for the rpmlog() entry
we only need to read, and reading an int is atomic. Add an internal
helper that lets us get the silly mask without locking.
2024-09-24 10:08:38 +02:00
Panu Matilainen e54abc75ac Take advantage of C++ native mutex facilities for rpmlog
See previous commits for rationale. Of particular note here is that
we now always take a write lock where we previously dynamically selected
between read/write, because the STL primitives don't seem to support
that in any easy way.
2024-09-24 10:08:38 +02:00
Panu Matilainen 7e489edc45 Take advantage of C++ native mutex facilities for keyring and keys
Replace manual pthread_* calls with the STL counterparts. Since there
was nothing to wrap these calls to begin with, this makes for a
particularly nice cleanup.
2024-09-24 10:08:38 +02:00
Panu Matilainen a162cf10df Take advantage of C++ native mutex facilities for string pool
Shared and exclusive locks are of different types in STL so we can't
easily return one or the other from poolLock() as per the write
argument. Just convert all poolLock() calls sites to name their
lock type locally.
2024-09-24 10:08:38 +02:00
Panu Matilainen 7f69da1909 Take advantage of C++ native mutex facilities for macro locking
C++ guarantees initialization of static objects takes place before
threads can run, so we don't need all the locksInitialized fubar.
The native objects also release themselves which fixes a theoretical
leak we had: we never destroyed the lock or lockattr so they remained
reachable until program exit.

We could continue to acquire and release the lock in the corresponding
functions but that's not RAII and would be inconsistent with what we
do elsewhere in rpm, just convert to the local lock variable style.
2024-09-24 10:08:38 +02:00
Panu Matilainen 532e6b9065 Filter Lua deprecation warnings based on the originating rpm version
Issuing deprecation warnings on packages built long time ago is
just antisocial behavior when the user is powerless to do anything
about it.

When running scripts, pass the builder rpm version to Lua through the
registry, and filter out the warnings when the package was built with
an rpm version where these functions were not yet deprecated.
Usage through rpmlua and macros always gets warnings: those are things
that can technically be fixed by the user.
2024-09-23 19:09:45 +02:00
Panu Matilainen ce269ed5ed Issue deprecation warnings for rpm.redirect2null() too, oops
Commit 46bd0ed2a9 did document
rpm.redirect2null() as deprecated but failed to add an actual warning
on it. Meaning no existing user will notice it being deprecated,
unless they were also using some of the other deprecated items too.

Turn check_deprecated() into an actual function for better control,
we'll have use for that later on.
2024-09-03 09:37:09 +03:00
Panu Matilainen b066411c46 Fix rpm.execute() return code handling
The status returned from waitpid() is not your exit code, it's encoded
and needs processing the W*() macros, like we do in the new rpm.spawn()
function.

These two should really be refactored to use common code, but leaving
that to later because one is in C and the other one in C++...
2024-08-27 14:09:31 +02:00
Panu Matilainen 6444f71286 Add rpm.spawn() Lua API
Turns out real-world usage needs more control than rpm.execute()
delivers. This could be crammed into rpm.execute() but it'd be forward
incompatible in a somewhat non-obvious way, we might just as well
add a separate function for it.

Supports redirecting stdin, stdout and stderr to a given path, support
for file descriptors, other actions and spawn attributes can be added
later.

Fixes: #3192
2024-08-27 14:09:31 +02:00
Panu Matilainen 05fbeb97a9 Fix crash on Lua file trigger exiting with return'ed data (#3029)
Reset the Lua stack on return from rpmluaRunScript() to discard any
unhandled returned data from the scriptlet. This may happen if there's
eg "return 0" from a non-macro scriptlet.

We could check for a numeric return value here and treat it as an exit
code, but then what to do with other kinds of returned data?
Our documentation states errors in Lua scriptlets should be signaled with
Lua error() function, it seems better to stick with that and avoid
introducing ambiguities and incompatibilities.

Update the existing file trigger tests to cover this case.

Fixes: #3029
2024-08-07 13:57:09 +02:00
FeRD (Frank Dana) 930b146bc0 Build: Add include dirs to exported lib targets
Each library target's exported `INTERFACE_INCLUDE_DIRECTORIES` list,
as written into the `rpm-targets.cmake` export file, is controlled by
the `PUBLIC` arguments supplied to `target_include_directories()` for
the library target.

* Directories scoped with the `$<BUILD_INTERFACE>` generator expression
  will be included in the export file written to the build dir by
  `export(TARGETS...)`
* Directories scoped with `$<INSTALL_INTERFACE>` will be included in
  the `rpm-targets.cmake` file installed into the
  `${CMAKE_INSTALL_LIBDIR}/cmake/rpm/` configuration directory.

Providing `PUBLIC` include directory paths for both the build and
install contexts is important, because without them the exported
CMake configuration is useless to library consumers.

(If the build is installed into `/usr/` or `/usr/local` it won't
matter, because the include directories required are the default
`/usr/include` or `/usr/local/include/` paths. But an install
targeted elsewhere with a `CMAKE_INSTALL_PREFIX` path needs an
`INTERFACE_INCLUDE_DIRECTORIES` property of
`${CMAKE_INSTALL_INCLUDEDIR}` to correctly locate its installed
includes.)
2024-08-01 10:23:38 +03:00
Neal H. Walfield 8befef3434 When using rpm-sequoia, use pgpPubkeyMerge.
As of v1.7.0, `rpm-sequoia` implements `pgpPubkeyMerge`.  Bump the
minimum supported version of `rpm-sequoia` to v1.7.0, and replace the
`pgpPubkeyMerge` stub with `rpm-sequoia`'s implementation of
`pgpPubkeyMerge`.
2024-07-30 10:32:59 +03:00
Florian Festi ef87d25034 Reset recursion depth for error message
$ rpm --define 'aaa %[%aaa]' --eval '%aaa'

let to a core dump due to a stack overflow. This was cause by the
generation of the error message failing due to being too deep in the
recursion of the macro expansion - creating more error messages.

Resetting the depth counter allows rendering the error message. As we are
failing and breaking off the parse run this is fine to do.

Thanks to Miro Hrončok for reporting

Resolves: #3197
2024-07-23 14:24:56 +02:00
Panu Matilainen c00d8a0ed3 Replace typedef's with using = for new internal C++ constructs
typedef's prevent const correctness and have various other issues,
"using" is the native modern version. When in Rome...
2024-06-26 11:07:59 +03:00
Florian Festi 4c1f71ec9e Add error messages for url helper calls
Rpm allows URLs as cli parameters. The files are then automatically
downloaded with %_urlhelper which defaults to curl(1). So far failures
have been ignored right away and error messages are generated later when
the file was not found on disk.

Issue a meaningful error message when the help program is failing or missing
completely. This allows not to ship curl with rpm while still giving the
user a chance to find out what is going on. This is not quite ideal as
the operation continues and creates a second error message later on, but
as good as it gets without redesigning the whole code.

Related: rhbz#2216754
Resolves: #2683
2024-06-14 13:43:37 +03:00
Panu Matilainen 558793e2b9 Convert rpmhook table and args to STL containers
Somehow this never got updated to rpmhash, so it was carrying a whole
hash implementation on its own. Lotsa fubar goes away.
Natively allocate rpmhook args too, and use a vector
2024-06-14 09:29:15 +03:00
Panu Matilainen 8ad361d804 Replace digest bundle static sized array with STL map
Removes the arbitrary limit of ids we support. Not that rpm needs more,
but arbitrary is arbitrary. Technically it's more efficient because
we don't need to brute-force search and there are never inactive digests
to skip when updating, but given the small number of elements it's
unlikely to make any real-world difference.

Also remove the unused nbytes member, I don't recall why I added it
but it hasn't been grown any uses in 10+ years so might as well drop.
2024-06-14 09:29:01 +03:00
Michael Schroeder 0c52a522e9 Support pubkey merging in the keyring code
The new rpmPubkeyMerge function will merge the certificate
material of two pubkeys describing the same key.

This is currently only implemented in the "legcay" backend.
2024-06-14 08:54:44 +03:00
Michael Schroeder 66502215ca Add a method to lookup a key from the keyring
Use this method in rpmtsImportPubkey() to check if we already
have that key. This is the place where we will implement key
merging in the next commits.
2024-06-14 08:54:44 +03:00
Michael Schroeder 2018cd4d71 Add rpmKeyringModify to change the keys of a keyring
This allows us to replace or delete keys from the keyring.
2024-06-14 08:54:44 +03:00
Michael Schroeder 30f9190db1 Split subkey initialization into its own function
No functual changes.
2024-06-14 08:54:44 +03:00
Michael Schroeder b871b68706 Always clear the RPMEXPAND_KEEP_QUOTED flag if we do not return the resulting flags
If the resulting flags cannot be returned, the caller has no way to
strip the quote characters. So we must assume that we are not to
return quotes in this case.

Fixes issue #3145
2024-06-05 14:46:01 +03:00
Panu Matilainen 18f7e53951 Remove C++ guards from internal headers
While these were necessary to get things going, they are only
counterproductive now: we want to be able to freely use C++ features
inside rpm.
2024-05-06 12:08:29 +03:00
Panu Matilainen 1f66db3459 Untangle the per-name stack from the macro entry struct
Use an STL stack to store the macro entries sharing the name to separate
the data from its containing structure, this lets the macro entries be
proper C++ objects that manage their own business only and thus can be
also directly stored containers, doing away with manual allocation.

And now that these entries no longer need any special care, we can
delete all the copy-control fubar from the main macro context: it's all
standard library storage now and don't need our handholding.
2024-04-30 09:06:24 +03:00
Panu Matilainen a39bb9359e Convert macro table to STL containers + native strings
Use an STL map for the macro entry table, this matches exactly the behavior
we manually did with the C array.

The variable length array at end of macro entry structs is not really
C++, use native strings for the storage. It's slower, but not tragically
so. For now, keep name, opts and body as const char pointers though to
the c_str() items to avoid having to change everything at once.

Popping macros is a bit clunky and repetitive, we'll clean it up later.
findEntry() returns a pointer to the macro entry itself instead of
pointer to pointer, which simplifies things a bit further.

This is a wee bit slower than the "raw C" counterpart, but by no means
tragically so and moving to native structures opens up other opportunities
in turn, both optimization and feature wise. Further work will be easier
now that the highly optimized but also tangled up data structure is
(mostly) untangled.
2024-04-30 09:06:24 +03:00
Panu Matilainen e571df4b9c Add copy control and in particular, destructor to the macro context
The macro contexts being static structs, they get their destructor
automatically called at program end. Which counter-intuitively *causes*
a leak if macros are stored in an STL container and rpmFreeMacros()
isn't called, because then the container clears itself and the macros
are left dangling, whereas without the destructor they are still
reachable. freeMacros() obviously wants to be a member function but
trying to keep things in the struct land for now.

Doesn't really change anything as of now, but this is needed for moving
the macro storage to C++ container.
2024-04-30 09:06:24 +03:00
Panu Matilainen f23483f629 Replace temporary argv array in Lua posix.exec() with a vector 2024-04-25 13:25:02 +03:00
Panu Matilainen bac494c35c Replace a couple of local IO buffers with a vector 2024-04-25 13:25:02 +03:00
Panu Matilainen 99e26b9df5 Replace homegrown mallocing getcwd() with filesystem::current_path() 2024-04-25 13:25:02 +03:00
Panu Matilainen 5f7be71090 Use strings as keyid and STL map for keyring storage
C++ strings can hold \0's so we can use it for convenient storage of
keyids, passing them to C requires special attention anyhow. And then
we can easily replace all array bookkeeping and lookup fubar with
STL map. We could just as easily use unordered_map, but map matches
what it did before so...
2024-04-25 13:25:02 +03:00
Panu Matilainen e2722fd423 Take advantage of rvasprintf() in rpmlog()
rpmlog() predates rvasprintf() by something like two decades, but no
reason not to use it now. One malloc() down, yay.
2024-04-25 13:25:02 +03:00
Panu Matilainen 695b5c2521 Fix multiply defined local macros escaping scope
freeArgs() only popped any local macros once, so if a local macro was
pushed multiple times, whether through %define or multiple identical
options getting passed, we leaked any remaining macros to the outside
scope.

Simply pop the local macros in a loop to fix. Have the internal
popMacro() return the previous pointer (if any) to simplify the job.
We even had an expected-fail test for this, now passing, but add a
more straightforward reproducer too.

This bug was circa 26 years old. Some might call it vintage at this point.

Fixes: #3056
2024-04-24 11:06:35 +02:00
Panu Matilainen e6d6b49f2f Unbreak zstd compression from 7462ad4dbe
A stupid newbie C++ error, array allocation would've been "new uint8_t[nb]"
and requiring delete[] as well. Use a vector instead, then we don't
need to manually free or track the size.

We really need to test the optional io types too, eww.
2024-04-24 09:14:51 +03:00
Panu Matilainen 317dadbdbe Natively allocate expression most parser structs 2024-04-23 09:36:51 +03:00
Panu Matilainen 7e558e3de6 Natively allocate keyring and pubkey structs
Use vector for pubkey packet storage as well to bring down the number
of mallocs.
2024-04-23 09:36:51 +03:00
Panu Matilainen eb561c88bc Use c++ string for rpmExpand() helper buffer 2024-04-23 09:36:51 +03:00
Panu Matilainen 59984c66c5 Use a c++ string for macro expansion buffer
Natively allocate the struct so we can use a string in there.
2024-04-23 09:36:51 +03:00
Panu Matilainen 1721962889 Use C++ constructs for rpmlog internal storage
Change the log record message to a string and then the records can be
stored in a vector without requiring custom destructors and all that.
2024-04-23 09:36:51 +03:00
Panu Matilainen 344e837f1a Replace internal Lua printing stack with a C++ stack 2024-04-23 09:36:51 +03:00
Panu Matilainen 9af6b4f39f Replace internal Lua print buffer with a C++ string 2024-04-23 09:36:51 +03:00
Panu Matilainen ad80c1761e Natively allocate internal rpmlua structs
Eliminate raw calloc/malloc uses, just new/delete for the parts that
end up on C side but our first vector uses too for some temp arrays.
2024-04-23 09:36:51 +03:00
Panu Matilainen 7462ad4dbe Natively allocate rpmio structs
Rename some internal structs to common style, the dust is thick in this
part of the cellar. In particular "lzfile" as a struct name clashes with
our local variables, don't do that.
2024-04-23 09:36:51 +03:00
Panu Matilainen 0d1071b99a Minimally convert digest code to native c++ allocation
Some background + rationale that will apply to a lot more commits going
forward and not going to keep repeating it all, so using this as a cover
letter of sorts:

Converting rpm to something resembling C++ is going to be a multi-year
operation, and what is being done here is just the first step of many.

Moving to native C++ allocation seems like an important first step as it
allows using non-trivial C++ data types (such as strings) in said constructs
(with malloc/free, destructors do not run). Also, it brings down the
number of raw C allocations with their ugly casts. It's worth nothing
that we'll never be free of raw mallocs entirely as some of the allocations
we return are expected to be free()'d from C, such as the output
parameter of rpmDigestFinal(). So we just want to get to the state where
ALL C-style allocations are for data going across the API border as
quickly as possible, the mixed state of things is ugly and fragile.

In many places rpm is relying on calloc() or memset() to zero-initialize
structs, but this cannot be used on C++ structs with "non-trivial" data
types such as strings, STL containers and the like. The {}
initialization is the nearest C++ counterpart for that. It'd be safer
to place the initialization(s) in the struct members directly but we're
shooting for minimal changes at this point, that'll come later.

Finally, we are using "naked new" because many of our pointers are going
across the API border to C where smart pointers simply cannot be used,
not without extra tricks anyhow. We don't want to worry about that just
now. We'll be using "naked new" for internal pointers too initially, again
just to keep changes minimal.
2024-04-23 09:36:51 +03:00
Michael Schroeder 4e9458ecca Add the "Primary Binding" pgp signature type
This type is needed to verify the primary binding signature
embedded in subkey binding signatures.
2024-04-22 15:21:39 +03:00
Michael Schroeder 200c91ff72 Relax openssl version requirement
And also delete the no longer needed include statements.
2024-04-18 12:50:24 +03:00
Panu Matilainen 8c7d8d9412 Remove the WITH_CXX option, this is a one-way street 2024-04-09 11:00:00 +03:00
Panu Matilainen 62840a3cdf Add casts that C++ requires but C doesn't across librpmio
In other words, a whole lot of "yes, really".
2024-04-09 11:00:00 +03:00
Panu Matilainen 656c8e75f5 Fixup missed constification in Lua readline callback
Should've been in commit 38b2602142
2024-04-09 08:16:18 +03:00
Panu Matilainen f8a72afbdb Fix pointer bogosity in rpmlog callback
rpmlogCallbackData is already a pointer type, we don't want a pointer
to a pointer for this. Kinda surprising it actually worked, but then
it's just a void pointer so...
2024-04-09 08:16:18 +03:00