--- configure.ac.orig	2022-09-02 12:39:48.138302773 +0000
+++ configure.ac	2022-09-02 12:39:50.554298710 +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	2022-09-02 12:39:48.130302787 +0000
+++ lib/header.c	2022-09-02 12:39:50.558298704 +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"
@@ -18,6 +19,12 @@
 
 #include "debug.h"
 
+/**
+ * Reasonableness check on count values.
+ * Most types have further restrictions, these are just the outer perimeter.
+ */
+#define hdrchkCount(_dl, _count) ((_count) < 1 || (_count) > (_dl))
+
 /** \ingroup header
  */
 const unsigned char rpm_header_magic[8] = {
@@ -206,6 +213,8 @@ int headerVerifyInfo(int il, int dl, con
 
 	if (hdrchkType(info->type))
 	    return i;
+	if (hdrchkCount(dl, info->count))
+	    return i;
 	if (hdrchkAlign(info->type, info->offset))
 	    return i;
 	if (hdrchkRange(dl, info->offset))
@@ -317,11 +326,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) {
-	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;
 	}
@@ -332,7 +342,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;
 }
 
 /**
@@ -789,8 +803,8 @@ int headerDel(Header h, rpmTagVal tag)
 Header headerImport(void * blob, unsigned int bsize, headerImportFlags flags)
 {
     const int32_t * ei = (int32_t *) blob;
-    int32_t il = ntohl(ei[0]);		/* index length */
-    int32_t dl = ntohl(ei[1]);		/* data length */
+    int32_t il = ntohl((uint32_t)ei[0]);		/* index length */
+    int32_t dl = ntohl((uint32_t)ei[1]);		/* data length */
     unsigned int pvlen = sizeof(il) + sizeof(dl) +
 		    (il * sizeof(struct entryInfo_s)) + dl;;
     Header h = NULL;
@@ -802,7 +816,7 @@ Header headerImport(void * blob, unsigne
     int fast = (flags & HEADERIMPORT_FAST);
 
     /* Sanity checks on header intro. */
-    if (bsize && bsize != pvlen)
+    if (bsize && (bsize < 8 || bsize != pvlen))
 	goto errxit;
     if (hdrchkTags(il) || hdrchkData(dl) || pvlen >= headerMaxbytes)
 	goto errxit;
@@ -815,7 +829,7 @@ Header headerImport(void * blob, unsigne
     dataEnd = dataStart + dl;
 
     entry = h->index;
-    if (!(htonl(pe->tag) < RPMTAG_HEADERI18NTABLE)) {
+    if (il < 1 || !(htonl(pe->tag) < RPMTAG_HEADERI18NTABLE)) {
 	h->flags |= HEADERFLAG_LEGACY;
 	entry->info.type = REGION_TAG_TYPE;
 	entry->info.tag = RPMTAG_HEADERIMAGE;
--- lib/package.c.orig	2014-02-05 13:04:02.000000000 +0000
+++ lib/package.c	2022-09-02 12:46:39.889608287 +0000
@@ -25,79 +25,72 @@ static unsigned int nkeyids = 0;
 static unsigned int nextkeyid  = 0;
 static unsigned int * keyids;
 
+static struct taglate_s {
+    rpmTagVal stag;
+    rpmTagVal xtag;
+    rpm_count_t count;
+    int quirk;
+} const xlateTags[] = {
+    { RPMSIGTAG_SIZE, RPMTAG_SIGSIZE, 1, 0 },
+    { RPMSIGTAG_PGP, RPMTAG_SIGPGP, 0, 0 },
+    { RPMSIGTAG_MD5, RPMTAG_SIGMD5, 16, 0 },
+    { RPMSIGTAG_GPG, RPMTAG_SIGGPG, 0, 0 },
+    /* { RPMSIGTAG_PGP5, RPMTAG_SIGPGP5, 0, 0 }, */ /* long obsolete, dont use */
+    { RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1, 1 },
+    { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1, 0 },
+    { RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0, 0 },
+    { RPMSIGTAG_RSA, RPMTAG_RSAHEADER, 0, 0 },
+    { RPMSIGTAG_LONGSIZE, RPMTAG_LONGSIGSIZE, 1, 0 },
+    { RPMSIGTAG_LONGARCHIVESIZE, RPMTAG_LONGARCHIVESIZE, 1, 0 },
+    { 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)
+static 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_DSA:
-	case RPMSIGTAG_RSA:
-	default:
-	    if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE))
+    for (xl = xlateTags; xl->stag; xl++) {
+	/* There mustn't be one in the main header */
+	if (headerIsEntry(h, xl->xtag)) {
+	    /* Some tags may exist in either header, but never both */
+	    if (xl->quirk && !headerIsEntry(sigh, xl->stag))
 		continue;
-	    break;
+	    goto exit;
 	}
-	if (td.data == NULL) continue;	/* XXX can't happen */
-	if (!headerIsEntry(h, td.tag)) {
-	    if (hdrchkType(td.type))
-		continue;
-	    if (td.count < 0 || hdrchkData(td.count))
-		continue;
-	    switch(td.type) {
-	    case RPM_NULL_TYPE:
-		continue;
+    }
+
+    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;
 }
 
 /**
@@ -280,8 +273,8 @@ static rpmRC headerVerify(rpmKeyring key
 {
     char *buf = NULL;
     int32_t * ei = (int32_t *) uh;
-    int32_t il = ntohl(ei[0]);
-    int32_t dl = ntohl(ei[1]);
+    int32_t il = ntohl((uint32_t)ei[0]);
+    int32_t dl = ntohl((uint32_t)ei[1]);
     entryInfo pe = (entryInfo) &ei[2];
     int32_t pvlen = sizeof(il) + sizeof(dl) + (il * sizeof(*pe)) + dl;
     unsigned char * dataStart = (unsigned char *) (pe + il);
@@ -292,7 +285,7 @@ static rpmRC headerVerify(rpmKeyring key
     rpmRC rc = RPMRC_FAIL;	/* assume failure */
 
     /* Is the blob the right size? */
-    if (uc > 0 && pvlen != uc) {
+    if (uc > 0 && (uc < 8 || pvlen != uc)) {
 	rasprintf(&buf, _("blob size(%d): BAD, 8 + 16 * il(%d) + dl(%d)\n"),
 		(int)uc, (int)il, (int)dl);
 	goto exit;
@@ -302,7 +295,7 @@ static rpmRC headerVerify(rpmKeyring key
     memset(&info, 0, sizeof(info));
 
     /* Check (and convert) the 1st tag element. */
-    if (headerVerifyInfo(1, dl, pe, &entry.info, 0) != -1) {
+    if (il > 0 && headerVerifyInfo(1, dl, pe, &entry.info, 0) != -1) {
 	rasprintf(&buf, _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
 		0, entry.info.tag, entry.info.type,
 		entry.info.offset, entry.info.count);
@@ -431,12 +424,12 @@ static rpmRC rpmpkgReadHeader(rpmKeyring
 	rasprintf(&buf, _("hdr magic: BAD\n"));
 	goto exit;
     }
-    il = ntohl(block[2]);
+    il = ntohl((uint32_t)block[2]);
     if (hdrchkTags(il)) {
 	rasprintf(&buf, _("hdr tags: BAD, no. of tags(%d) out of range\n"), il);
 	goto exit;
     }
-    dl = ntohl(block[3]);
+    dl = ntohl((uint32_t)block[3]);
     if (hdrchkData(dl)) {
 	rasprintf(&buf,
 		  _("hdr data: BAD, no. of bytes(%d) out of range\n"), dl);
@@ -695,10 +688,15 @@ exit:
 	    headerConvert(h, HEADERCONV_COMPRESSFILELIST);
 	
 	/* Append (and remap) signature tags to the metadata. */
-	headerMergeLegacySigs(h, sigh);
+	if (headerMergeLegacySigs(h, sigh, &msg)) {
+	    rpmlog(RPMLOG_ERR, "%s: %s\n", fn, msg);
+	    free(msg);
+	    rc = RPMRC_FAIL;
+	}
 
 	/* Bump reference count for return. */
-	*hdrp = headerLink(h);
+	if (rc != RPMRC_FAIL)
+	    *hdrp = headerLink(h);
     }
     rpmtdFreeData(&sigtd);
     rpmDigestFinal(ctx, NULL, NULL, 0);
--- lib/signature.c.orig	2022-09-02 12:39:59.930282929 +0000
+++ lib/signature.c	2022-09-02 12:43:18.081949466 +0000
@@ -95,13 +95,13 @@ rpmRC rpmReadSignature(FD_t fd, Header *
 	rasprintf(&buf, _("sigh magic: BAD\n"));
 	goto exit;
     }
-    il = ntohl(block[2]);
+    il = ntohl((uint32_t)block[2]);
     if (il < 0 || il > 32) {
 	rasprintf(&buf, 
 		  _("sigh tags: BAD, no. of tags(%d) out of range\n"), il);
 	goto exit;
     }
-    dl = ntohl(block[3]);
+    dl = ntohl((uint32_t)block[3]);
     if (dl < 0 || dl > 8192) {
 	rasprintf(&buf, 
 		  _("sigh data: BAD, no. of  bytes(%d) out of range\n"), dl);
@@ -125,7 +125,7 @@ rpmRC rpmReadSignature(FD_t fd, Header *
     }
     
     /* Check (and convert) the 1st tag element. */
-    xx = headerVerifyInfo(1, dl, pe, &entry.info, 0);
+    xx = il > 0 ? headerVerifyInfo(1, dl, pe, &entry.info, 0) : -1;
     if (xx != -1) {
 	rasprintf(&buf, _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"),
 		  0, entry.info.tag, entry.info.type,
