- Logging output (including callback activities) is conceptually always
a "write"-event, but independent of log context manipulation so it
needs a mutex of its own to serialize log events. Previously we
write-locked only for records that need saving, so messages above
warning level could get interleaved.
- Grab the bits we need from context to local variables and free
the lock before callback and output, either of which could involve
writing to files (and in case of callback, who knows what) so
it could take long and prevent something silly like rpmIsDebug() from
proceeding. Also this way callback can call some rpmlog-related
functions without much worries of getting stuck or other trouble.
- Checking whether we need to log requires a (read) lock on entry,
but most of the time that's all. Hide that locking behind calling
rpmlogSetMask() and move ctx acquire into dolog()
- Means we're now taking two different logs when actually logging,
but since that's the rarer condition it hardly matters.
- A string pointer returned rpmlogMessage() is in fact guaranteed to
be valid until rpmlogClose(), because its malloced separately
from the owning record. So while the address of the owning record
can change via realloc(), the contained message stays put.
- Track non-global macro definitions in a helper variable, this
eliminates the need for costly macro table walking at end of each
expansion cycle as we only bother doing it if non-global macros
were defined during a given expansion cycle.
- Commit 547a004b7e introduced a regression
on stacked io Fclose() return code, details at
http://lists.rpm.org/pipermail/rpm-maint/2014-August/003731.html
- The original code seems fishy in other ways (missed errors), this
hopefully fixes both cases by only attempting to close actually
open fdno's and only considering actual closes for error codes.
- Our libraries are in reality so interdependent that its not even
possible to use them independently of others, so having them
all follow sort of independent versioning information just doesn't
make any sense and is a PITA everytime I need to touch the data.
- This causes librpmsign soname bump with no good reason so its
probably "evil" and all ... so sue me, its not as if anybody
is actually using this library outside rpm itself.
- Commit 1bdcd05008 to fix RhBug:1045723
broke some funky java macros in Fedora which include line continuation
in the argument (comments 6-7 in the bug). That it ever worked seems
far more like luck than by design but since this seems to fix it...
- Test for terminating ')' existence before copying, otherwise we'll
end up walking over the edge of the world.
- Return address from doDefine() on error will likely differ after
this, whether that actually affects anything remains to be seen...
- Within rpm itself, this allocation from 12 years ago doesn't come anywhere
close to stack limits on Linux at least, but since we're a library
we should be considerate to API users stack needs as well. Allocate
the buffer from heap instead, its not performance critical either
since this will always be limited by physical IO and digest calculation
speed rather than a single malloc.
- Both doDefine() and doUndefine() assumed the macro string would
always fit into MACROBUFSIZ, which of course is true for any
normal use but we cant make such assumptions.
- In the case of %define/%global there are various other overrun-issues
that need further changes to fix.
- In the current macro implementation the check is simply far too
expensive to leave on always. Its useful though, so enable it
when tracing macro expansion, in which case you're probably
troubleshooting some macro-issues...
- Reword the message to something hopefully little more understandable,
change from error to a warning (only matters for output)
- Check unused macros at end of every scope, but unlike with parametrized
macros, dont actually delete
- Only whine once per unused macro due to the above to avoid spurious
output due to above
- This catches the common error in specs where %define is used in a scope
unintentionally, eg "%{!?foo: %define foo 1}" where the just defined
macro should actually fall out of scope upon the closing }, but
only gets erased if any parametrized macro is "called" and causes
insane behavior such as described in RhBug:552944. So at least we'll
warn on these situations.
- In practise doesn't change anything visible as the "macro not used"
message is disabled, but tracking a flag bit is saner than
strlen() + strchr() + bunch of other stuff which isn't even correct:
prior to this %## would've triggered "unused" errors which is plain
wrong, and complaining about unused %1 %2 ... isn't really right
either.
- Revert back to pre commit c22d5b1299
state wrt macro substitution. The commit does have fixes we want
but it also breaks valid cases which is not okay. We really need
a far more thorough macro test suite before these kind of changes,
and also need to do the changes in more controlled pieces.
- Commit c22d5b1299 changed the parsing
to require a valid name in %{name} macro, but this outlaws existing
uses such as %{foo_%{bar}_something}. Relaxing the %{name} form
to use as-is substitution as well allows these to work again.
- Makes the testcase from commit f082b5baa4
succeed. While the old behavior is non-sensical and most likely entirely
unintentional, we're changing a very long-standing behavior here (tested
back to rpm 4.4.x and almost certainly much much older than that) so
its entirely possible people are actually relying on the old
behavior. Lets see what breaks...
- Should've really been in commit 20cfa7d2b4
but at the time NSS didn't even support SHA-224 so it was untestable.
Now that it does, and somebody actually bothered to test...
Fixes RhBug:1066494.
- Allow loading custom macro files from eg specs. This is quite different
from %include which inlines arbitrary content into a spec, but which
cannot be used for including macro files as their syntax is entirely
different. Both have their uses.
- rpm5.org also supports %load within macro files, we dont as I find the
imperative %load very alien in what's otherwise an entirely declarative
file "format"
- This simplifies things a bit as we dont need to worry about the
id storage and the starting location of the next string in advance.
- Also make it clearer the string is copied into the current chunk,
to which pool->offs only points to. Make pool->offs const to
enforce the strings are never written through it.
- Assign newly alloc'ed chunks to pool->chunks, pool->offs just
contains pointers into the chunks. This doesn't change actual
behavior at all, just (IMO) clarifies the code a bit.
- As pointed out by Michael Schroeder in
http://lists.rpm.org/pipermail/rpm-maint/2013-September/003605.html,
the dummy entries used for optimizing rpmstrPoolStrlen() are
problematic in number of ways:
- Walking the id's in a pool is unreliable, and rehashing can cause
bogus empty strings to be added to a pool where they otherwise
do not exist
- rpmstrPoolNumStr() is not accurate when more than one chunk is in use
- Unfortunately this means giving up the rpmstrPoolStrlen() optimization,
for now at least.
- There are any number of places where this could be fixed, but
to keep the behavior similar to eg /bin/sh scriptlet without a body,
just turn a non-existent script into an empty string.
Also use the byte count of the MPI as block size instead of using
MP_WORDS_TO_BITS, as the latter depends on the internal word size
used in the beecryt library.
Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
Use the _bin variants instead of converting the MPIs to hex.
Also check the exit status of the beecrypt functions.
Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
Simplifies the code a lot. Also check that that there's room for the
mpi len before calling pgpMpiLen().
Signed-off-by: Panu Matilainen <pmatilai@redhat.com>
- Using the already calculated macro arg + arglen for copying the
buffer instead of buggy local variant helps... This is as old as
the embedded lua interpreter in rpm, close to a decade.
- Besides fixing the segfault, this actually makes it behave like
other built-ins, evaluating to empty string when an empty arguments
or no arguments are passed.
- Previously various built-in macros without an actual argument,
eg %{basename:} would evaluate to "}" which makes no sense
whatsoever. With this, they evaluate to an empty string similarly
to when no argument is passed, eg %{basename}. Arguably these
should emit an error/warning instead but for now...
- This reverts commit 43a34e1554,
contrary to what the comment said the is NOT how other built-ins
behave, they evaluate to an empty string without an argument.
Better fix needed...
- %{lua:...} is used for invoking the embedded Lua interpreter, in
which case the script must be passed as the macro argument. If
no argument is passed, let it fall through to normal macro expansion.
This might not be the most sensible behavior possible but at least
its in line with what currently happens with other similar built-in
macros.
- Add the actual locking into macro context acquire + release. We're
using a mutex instead of rwlock because currently any macro can
involve defines and undefines and we dont know it beforehand. So
we just use a bigger hammer...
- The macro engine internals shouldn't need recursive mutexes but
unfortunately Lua macro bindings, which are limited to the
lock-on-entry interfaces can and do get called recursively
from macros so currently there's not much choice but to use
recursive mutex for the macro contexts. What makes it even uglier
is that there's no portable static initializer for recursive mutex
so we need to add yet another pthread-construct to safely dynamically
initialize the mutexes :(
- Of course this doesn't make bunch of threads simultaneously messing
with macros behave sane: if one thread tries to load new macros
and the other one frees them, they shouldn't crash but the
results are unlikely to be what the caller intended. The purpose
here is just to allow the occasional rpmExpand() and such to
complete without crashing and burning when multiple threads are
doing stuff like trying to read packages from disk.
- rpmLoadMacros() is a dumb name for what it does: it copies macros
from one context to another. The only actual use within rpm is
to copy back the cli macros to global context, but make the
internal helper more flexible by allowing copying to any context.
- rpmLoadMacros() is mostly just a dumb wrapper around copyMacros()
to grab locks and guard against copying global context to itself.
Adjust rpmInitMacros() to use copyMacros() as it already has a
lock on the global table, it just needs a lock on the cli contexts
as well.
- rpmInitMacros() already grabs the (theoretical) lock on entry
so we shouldn't try to grab it again, use the new lockless
loadMacroFile() version for the purpose.
- rpmLoadMacroFile() is now just a simple lock-wrapper around
loadMacroFile()