[Rpm-maint] [PATCH 3/3] Add RPMTAG_IDENTITY calculation as tag extension
Panu Matilainen
pmatilai at redhat.com
Wed Sep 19 09:37:52 UTC 2018
On 8/23/18 12:01 AM, Vladimir D. Seleznev wrote:
> RPMTAG_IDENTITY is calculating as digest of part of package header that
> marked for identity calculation in rpmtag.h. They are supposed to not
> contain irrelevant to package build tag entries.
>
> Mathematically RPMTAG_IDENTITY value is a result of function of two
> variable: a package header and an rpm utility, thus this value can
> differ for same package and different version of rpm.
>
> Signed-off-by: Vladimir D. Seleznev <vseleznv at altlinux.org>
> ---
> lib/tagexts.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 72 insertions(+)
>
> diff --git a/lib/tagexts.c b/lib/tagexts.c
> index 61e9b702b..1467bfcd3 100644
> --- a/lib/tagexts.c
> +++ b/lib/tagexts.c
> @@ -954,6 +954,77 @@ static int filenlinksTag(Header h, rpmtd td, headerGetFlags hgflags)
>
> #include "identitymatch.C"
>
> +static int identityTag(Header h, rpmtd td, headerGetFlags hgflags)
> +{
> + int rc = 1;
> + DIGEST_CTX ctx;
> + char * identity = NULL;
> +
> + struct rpmtd_s ttd;
> + Header ih;
> + HeaderIterator hi;
> +
> + /* Return immediatly if there is no identity marker in rpmtag.h */
> + if (!identityMatch(0)) {
> + rc = 0;
> + goto exit;
> + }
> +
> + /* rpm v3 packages dont have an immutable region */
> + if (!headerGet(h, RPMTAG_HEADERIMMUTABLE, &ttd, HEADERGET_DEFAULT)) {
> + rc = 0;
> + goto exit;
> + }
> +
> + ih = headerImport(ttd.data, ttd.count, HEADERIMPORT_FAST);
> + if ((hi = headerInitIterator(ih)) == NULL) {
> + rc = 0;
> + goto exit;
> + }
> +
> + if ((ctx = rpmDigestInit(PGPHASHALGO_SHA256, RPMDIGEST_NONE)) == NULL) {
> + rc = 0;
That's no less than four cases setting rc to failure before jumping out.
I'd suggest expecting failure to begin with, and only setting it to
success one at the end. Which is a common idiom all over the codebase.
> + goto exit;
> + }
> +
> + while (headerNext(hi, &ttd) && rc) {
> + if (rpmtdCount(&ttd) > 0) {
There should be no need for this, tags with zero count don't exist in
headers AFAIK.
> + if (identityMatch(ttd.tag)) {
> + int i;
> + rpmtdInit(&ttd);
No need for rpmtdInit() here either, headerNext() takes care of that.
> + while ((i = rpmtdNext(&ttd)) >= 0) {
> + rpmDigestUpdate(ctx, &ttd.tag, sizeof(ttd.tag));
> + rpmDigestUpdate(ctx, &i, sizeof(i));
> + if (ttd.type == RPM_STRING_ARRAY_TYPE) {
> + for (int j = 0; j < ttd.count; j++)
> + rpmDigestUpdate(ctx, ((char **) ttd.data)[j], strlen(((char **) ttd.data)[j]));
> + continue;
> + }
> + rpmDigestUpdate(ctx, ttd.data, ttd.size);
I tend to agree with Jeff on this one - everything can be converted to
strings after which all datatypes can be handled identically, and more
simply.
> + }
> + }
> + }
> + rpmtdFreeData(&ttd);
> + }
> +
> + if (!rc)
> + goto exit;
> +
> + rpmDigestFinal(ctx, (void **) &identity, NULL, 1);
> + headerFree(ih);
> +
> + td->data = xstrdup(identity);
> + td->type = RPM_STRING_TYPE;
> + td->count = 1;
> + td->flags = RPMTD_ALLOCED;
> +
> +exit:
> + headerFreeIterator(hi);
> + _free(identity);
Why strdup() of already malloced data? Just pass address of td->data
directly to rpmDigestFinal() and avoid this unnecessary dance.
- Panu -
> +
> + return rc;
> +}
> +
> static const struct headerTagFunc_s rpmHeaderTagExtensions[] = {
> { RPMTAG_GROUP, groupTag },
> { RPMTAG_DESCRIPTION, descriptionTag },
> @@ -992,6 +1063,7 @@ static const struct headerTagFunc_s rpmHeaderTagExtensions[] = {
> { RPMTAG_OBSOLETENEVRS, obsoletenevrsTag },
> { RPMTAG_CONFLICTNEVRS, conflictnevrsTag },
> { RPMTAG_FILENLINKS, filenlinksTag },
> + { RPMTAG_IDENTITY, identityTag },
> { 0, NULL }
> };
>
>
More information about the Rpm-maint
mailing list