--- ./configure.ac.orig	2021-04-21 14:19:29.689566856 +0000
+++ ./configure.ac	2021-04-21 14:19:36.741553877 +0000
@@ -37,7 +37,7 @@ fi
 AS=${AS-as}
 AC_SUBST(AS)
 if test "$GCC" = yes; then
-    cflags_to_try="-fno-strict-aliasing -fstack-protector -Wempty-body"
+    cflags_to_try="-fno-strict-aliasing -fstack-protector -fno-strict-overflow -fno-delete-null-pointer-checks -Wempty-body"
     AC_MSG_CHECKING([supported compiler flags])
     old_cflags=$CFLAGS
     echo
--- ./lib/header.c.orig	2021-04-21 14:19:29.693566848 +0000
+++ ./lib/header.c	2021-04-21 14:19:36.741553877 +0000
@@ -11,6 +11,7 @@
 #include "system.h"
 #include <netdb.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <rpm/rpmtypes.h>
 #include <rpm/rpmstring.h>
 #include "lib/header_internal.h"
@@ -135,6 +136,12 @@ static const size_t headerMaxbytes = (25
 #define hdrchkTag(_tag) ((_tag) < HEADER_I18NTABLE)
 
 /**
+ * Reasonableness check on count values.
+ * Most types have further restrictions, these are just the outer perimeter.
+ */
+#define hdrchkCount(_dl, _count) ((_count) < 1 || (_count) > (_dl))
+
+/**
  * Sanity check on type values.
  */
 #define hdrchkType(_type) ((_type) < RPM_MIN_TYPE || (_type) > RPM_MAX_TYPE)
@@ -288,6 +295,8 @@ static rpmRC hdrblobVerifyInfo(hdrblob b
 	    goto err;
 	if (hdrchkType(info.type))
 	    goto err;
+	if (hdrchkCount(blob->dl, info.count))
+	    goto err;
 	if (hdrchkAlign(info.type, info.offset))
 	    goto err;
 	if (hdrchkRange(blob->dl, info.offset))
@@ -301,6 +310,15 @@ static rpmRC hdrblobVerifyInfo(hdrblob b
 	end = info.offset + len;
 	if (hdrchkRange(blob->dl, end) || len <= 0)
 	    goto err;
+	if (blob->regionTag) {
+	    /*
+	     * Verify that the data does not overlap the region trailer.  The
+	     * region trailer is skipped by this loop, so the other checks
+	     * don’t catch this case.
+	     */
+	    if (end > blob->rdl - REGION_TAG_COUNT && info.offset < blob->rdl)
+		goto err;
+	}
     }
     return 0; /* Everything ok */
 
@@ -408,13 +426,12 @@ unsigned headerSizeof(Header h, int magi
 static inline int strtaglen(const char *str, rpm_count_t c, const char *end)
 {
     const char *start = str;
-    const char *s;
+    const char *s = NULL;
+    int len = -1; /* assume failure */
 
     if (end) {
-	if (str >= end)
-	    return -1;
-	while ((s = memchr(start, '\0', end-start))) {
-	    if (--c == 0 || s > end)
+	while (end > start && (s = memchr(start, '\0', end-start))) {
+	    if (--c == 0)
 		break;
 	    start = s + 1;
 	}
@@ -425,7 +442,11 @@ static inline int strtaglen(const char *
 	    start = s + 1;
 	}
     }
-    return (c > 0) ? -1 : (s - str + 1);
+
+    if (s != NULL && c == 0)
+	len = s - str + 1;
+
+    return len;
 }
 
 /**
@@ -1894,6 +1915,25 @@ hdrblob hdrblobFree(hdrblob blob)
     return NULL;
 }
 
+static rpmRC hdrblobVerifyLengths(rpmTagVal regionTag, uint32_t il, uint32_t dl,
+				  char **emsg) {
+    uint32_t il_max = HEADER_TAGS_MAX;
+    uint32_t dl_max = HEADER_DATA_MAX;
+    if (regionTag == RPMTAG_HEADERSIGNATURES) {
+	il_max = 32;
+	dl_max = 64 * 1024 * 1024;
+    }
+    if (hdrchkRange(il_max, il)) {
+	rasprintf(emsg, _("hdr tags: BAD, no. of tags(%" PRIu32 ") out of range"), il);
+	return RPMRC_FAIL;
+    }
+    if (hdrchkRange(dl_max, dl)) {
+	rasprintf(emsg, _("hdr data: BAD, no. of bytes(%" PRIu32 ") out of range"), dl);
+	return RPMRC_FAIL;
+    }
+    return RPMRC_OK;
+}
+
 rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrblob blob, char **emsg)
 {
     int32_t block[4];
@@ -1906,13 +1946,6 @@ rpmRC hdrblobRead(FD_t fd, int magic, in
     size_t nb;
     rpmRC rc = RPMRC_FAIL;		/* assume failure */
     int xx;
-    int32_t il_max = HEADER_TAGS_MAX;
-    int32_t dl_max = HEADER_DATA_MAX;
-
-    if (regionTag == RPMTAG_HEADERSIGNATURES) {
-	il_max = 32;
-	dl_max = 64 * 1024 * 1024;
-    }
 
     memset(block, 0, sizeof(block));
     if ((xx = Freadall(fd, bs, blen)) != blen) {
@@ -1925,15 +1958,9 @@ rpmRC hdrblobRead(FD_t fd, int magic, in
 	goto exit;
     }
     il = ntohl(block[2]);
-    if (hdrchkRange(il_max, il)) {
-	rasprintf(emsg, _("hdr tags: BAD, no. of tags(%d) out of range"), il);
-	goto exit;
-    }
     dl = ntohl(block[3]);
-    if (hdrchkRange(dl_max, dl)) {
-	rasprintf(emsg, _("hdr data: BAD, no. of bytes(%d) out of range"), dl);
+    if (hdrblobVerifyLengths(regionTag, il, dl, emsg))
 	goto exit;
-    }
 
     nb = (il * sizeof(struct entryInfo_s)) + dl;
     uc = sizeof(il) + sizeof(dl) + nb;
@@ -1977,11 +2004,18 @@ rpmRC hdrblobInit(const void *uh, size_t
 		struct hdrblob_s *blob, char **emsg)
 {
     rpmRC rc = RPMRC_FAIL;
-
     memset(blob, 0, sizeof(*blob));
+    if (uc && uc < 8) {
+	rasprintf(emsg, _("hdr length: BAD"));
+	goto exit;
+    }
+
     blob->ei = (int32_t *) uh; /* discards const */
-    blob->il = ntohl(blob->ei[0]);
-    blob->dl = ntohl(blob->ei[1]);
+    blob->il = ntohl((uint32_t)(blob->ei[0]));
+    blob->dl = ntohl((uint32_t)(blob->ei[1]));
+    if (hdrblobVerifyLengths(regionTag, blob->il, blob->dl, emsg) != RPMRC_OK)
+	goto exit;
+
     blob->pe = (entryInfo) &(blob->ei[2]);
     blob->pvlen = sizeof(blob->il) + sizeof(blob->dl) +
 		  (blob->il * sizeof(*blob->pe)) + blob->dl;
--- ./lib/headerutil.c.orig	2020-03-02 15:45:22.126481230 +0000
+++ ./lib/headerutil.c	2021-04-21 14:19:36.741553877 +0000
@@ -332,8 +332,10 @@ static void providePackageNVR(Header h)
     rpmds hds, nvrds;
 
     /* Generate provides for this package name-version-release. */
-    if (!(name && pEVR))
+    if (!(name && pEVR)) {
+	free(pEVR);
 	return;
+    }
 
     /*
      * Rpm prior to 3.0.3 does not have versioned provides.
--- ./lib/package.c.orig	2020-04-28 12:50:11.817399053 +0000
+++ ./lib/package.c	2021-04-21 14:39:20.883355526 +0000
@@ -31,76 +31,72 @@ struct pkgdata_s {
     rpmRC rc;
 };
 
+struct taglate_s {
+    rpmTagVal stag;
+    rpmTagVal xtag;
+    rpm_count_t count;
+} const xlateTags[] = {
+    { RPMSIGTAG_SIZE, RPMTAG_SIGSIZE, 1 },
+    { RPMSIGTAG_PGP, RPMTAG_SIGPGP, 0 },
+    { RPMSIGTAG_MD5, RPMTAG_SIGMD5, 16 },
+    { RPMSIGTAG_GPG, RPMTAG_SIGGPG, 0 },
+    /* { RPMSIGTAG_PGP5, RPMTAG_SIGPGP5, 0 }, */ /* long obsolete, dont use */
+    { RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1 },
+    /* { RPMSIGTAG_FILESIGNATURES, RPMTAG_FILESIGNATURES, 0 }, */
+    /* { RPMSIGTAG_FILESIGNATURELENGTH, RPMTAG_FILESIGNATURELENGTH, 1 }, */
+    { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1 },
+    { RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 1 },
+    { RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0 },
+    { RPMSIGTAG_RSA, RPMTAG_RSAHEADER, 0 },
+    { RPMSIGTAG_LONGSIZE, RPMTAG_LONGSIGSIZE, 1 },
+    { RPMSIGTAG_LONGARCHIVESIZE, RPMTAG_LONGARCHIVESIZE, 1 },
+    { 0 }
+};
+
 /** \ingroup header
  * Translate and merge legacy signature tags into header.
  * @param h		header (dest)
  * @param sigh		signature header (src)
  */
 static
-void headerMergeLegacySigs(Header h, Header sigh)
+rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg)
 {
-    HeaderIterator hi;
+    const struct taglate_s *xl;
     struct rpmtd_s td;
 
-    hi = headerInitIterator(sigh);
-    for (; headerNext(hi, &td); rpmtdFreeData(&td))
-    {
-	switch (td.tag) {
-	/* XXX Translate legacy signature tag values. */
-	case RPMSIGTAG_SIZE:
-	    td.tag = RPMTAG_SIGSIZE;
-	    break;
-	case RPMSIGTAG_PGP:
-	    td.tag = RPMTAG_SIGPGP;
-	    break;
-	case RPMSIGTAG_MD5:
-	    td.tag = RPMTAG_SIGMD5;
-	    break;
-	case RPMSIGTAG_GPG:
-	    td.tag = RPMTAG_SIGGPG;
-	    break;
-	case RPMSIGTAG_PGP5:
-	    td.tag = RPMTAG_SIGPGP5;
-	    break;
-	case RPMSIGTAG_PAYLOADSIZE:
-	    td.tag = RPMTAG_ARCHIVESIZE;
-	    break;
-	case RPMSIGTAG_SHA1:
-	case RPMSIGTAG_SHA256:
-	case RPMSIGTAG_DSA:
-	case RPMSIGTAG_RSA:
-	default:
-	    if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE))
-		continue;
-	    break;
-	}
-	if (!headerIsEntry(h, td.tag)) {
-	    switch (td.type) {
-	    case RPM_NULL_TYPE:
-		continue;
+    for (xl = xlateTags; xl->stag; xl++) {
+	/* There mustn't be one in the main header */
+	if (headerIsEntry(h, xl->xtag))
+	    goto exit;
+    }
+
+    rpmtdReset(&td);
+    for (xl = xlateTags; xl->stag; xl++) {
+	if (headerGet(sigh, xl->stag, &td, HEADERGET_RAW|HEADERGET_MINMEM)) {
+	    /* Translate legacy tags */
+	    if (xl->stag != xl->xtag)
+		td.tag = xl->xtag;
+	    /* Ensure type and tag size match expectations */
+	    if (td.type != rpmTagGetTagType(td.tag))
 		break;
-	    case RPM_CHAR_TYPE:
-	    case RPM_INT8_TYPE:
-	    case RPM_INT16_TYPE:
-	    case RPM_INT32_TYPE:
-	    case RPM_INT64_TYPE:
-		if (td.count != 1)
-		    continue;
+	    if (td.count < 1 || td.count > 16*1024*1024)
 		break;
-	    case RPM_STRING_TYPE:
-	    case RPM_BIN_TYPE:
-		if (td.count >= 16*1024)
-		    continue;
+	    if (xl->count && td.count != xl->count)
 		break;
-	    case RPM_STRING_ARRAY_TYPE:
-	    case RPM_I18NSTRING_TYPE:
-		continue;
+	    if (!headerPut(h, &td, HEADERPUT_DEFAULT))
 		break;
-	    }
-	    (void) headerPut(h, &td, HEADERPUT_DEFAULT);
+	    rpmtdFreeData(&td);
 	}
     }
-    headerFreeIterator(hi);
+    rpmtdFreeData(&td);
+
+exit:
+    if (xl->stag) {
+	rasprintf(msg, "invalid signature tag %s (%d)",
+			rpmTagGetName(xl->xtag), xl->xtag);
+    }
+
+    return xl->stag;
 }
 
 /**
@@ -363,7 +359,8 @@ rpmRC rpmReadPackageFile(rpmts ts, FD_t
 		goto exit;
 
 	    /* Append (and remap) signature tags to the metadata. */
-	    headerMergeLegacySigs(h, sigh);
+	    if (headerMergeLegacySigs(h, sigh, &msg))
+		goto exit;
 	    applyRetrofits(h);
 
 	    /* Bump reference count for return. */
--- ./rpmio/rpmio.c.orig	2020-04-28 12:50:11.934400460 +0000
+++ ./rpmio/rpmio.c	2021-04-21 14:19:36.741553877 +0000
@@ -772,6 +772,7 @@ static LZFILE *lzopen_internal(const cha
 		 * should've processed
 		 * */
 		while (isdigit(*++mode));
+		--mode;
 	    }
 #ifdef HAVE_LZMA_MT
 	    else
