int headerVerifyInfo(int il, int dl, const void * pev, void * iv, int negate) { entryInfo pe = (entryInfo) pev; entryInfo info = iv; int i; for (i = 0; i < il; i++) { info->tag = ntohl(pe[i].tag); info->type = ntohl(pe[i].type); info->offset = ntohl(pe[i].offset); if (negate) info->offset = -info->offset; info->count = ntohl(pe[i].count); if (hdrchkType(info->type)) return i; if (hdrchkAlign(info->type, info->offset)) return i; if (hdrchkRange(dl, info->offset)) return i; if (hdrchkData(info->count)) return i; } return -1; }
/** \ingroup header * Read (and load) header from file handle. * @param fd file handle * @param magicp read (and verify) 8 bytes of (magic, 0)? * @return header (or NULL on error) */ Header headerRead(FD_t fd, enum hMagic magicp) { int32_t block[4]; int32_t reserved; int32_t * ei = NULL; int32_t il; int32_t dl; int32_t magic; Header h = NULL; size_t len; int i; memset(block, 0, sizeof(block)); i = 2; if (magicp == HEADER_MAGIC_YES) i += 2; /* FIX: cast? */ if (timedRead(fd, (char *)block, i*sizeof(*block)) != (i * sizeof(*block))) goto exit; i = 0; if (magicp == HEADER_MAGIC_YES) { magic = block[i++]; if (memcmp(&magic, rpm_header_magic, sizeof(magic))) goto exit; reserved = block[i++]; } il = ntohl(block[i]); i++; dl = ntohl(block[i]); i++; len = sizeof(il) + sizeof(dl) + (il * sizeof(struct entryInfo_s)) + dl; /* Sanity checks on header intro. */ if (hdrchkTags(il) || hdrchkData(dl) || len > headerMaxbytes) goto exit; ei = xmalloc(len); ei[0] = htonl(il); ei[1] = htonl(dl); len -= sizeof(il) + sizeof(dl); /* FIX: cast? */ if (timedRead(fd, (char *)&ei[2], len) != len) goto exit; h = headerLoad(ei); exit: if (h == NULL && ei != NULL) { free(ei); } return h; }
Header headerRead(FD_t fd, int magicp) { int32_t block[4]; int32_t * ei = NULL; int32_t il; int32_t dl; Header h = NULL; unsigned int len, blen; if (magicp == HEADER_MAGIC_YES) { int32_t magic; if (Freadall(fd, block, 4*sizeof(*block)) != 4*sizeof(*block)) goto exit; magic = block[0]; if (memcmp(&magic, rpm_header_magic, sizeof(magic))) goto exit; il = ntohl(block[2]); dl = ntohl(block[3]); } else { if (Freadall(fd, block, 2*sizeof(*block)) != 2*sizeof(*block)) goto exit; il = ntohl(block[0]); dl = ntohl(block[1]); } blen = (il * sizeof(struct entryInfo_s)) + dl; len = sizeof(il) + sizeof(dl) + blen; /* Sanity checks on header intro. */ if (hdrchkTags(il) || hdrchkData(dl) || len > headerMaxbytes) goto exit; ei = xmalloc(len); ei[0] = htonl(il); ei[1] = htonl(dl); if (Freadall(fd, (char *)&ei[2], blen) != blen) goto exit; h = headerImport(ei, len, 0); exit: if (h == NULL && ei != NULL) { free(ei); } return h; }
Header headerCopyLoad(const void * uh) { int32_t * ei = (int32_t *) uh; int32_t il = ntohl(ei[0]); /* index length */ int32_t dl = ntohl(ei[1]); /* data length */ size_t pvlen = sizeof(il) + sizeof(dl) + (il * sizeof(struct entryInfo_s)) + dl; void * nuh = NULL; Header h = NULL; /* Sanity checks on header intro. */ if (!(hdrchkTags(il) || hdrchkData(dl)) && pvlen < headerMaxbytes) { nuh = memcpy(xmalloc(pvlen), uh, pvlen); if ((h = headerLoad(nuh)) == NULL) nuh = _free(nuh); } return h; }
static int intAddEntry(Header h, rpmtd td) { indexEntry entry; rpm_data_t data; int length; /* Count must always be >= 1 for headerAddEntry. */ if (td->count <= 0) return 0; if (hdrchkType(td->type)) return 0; if (hdrchkData(td->count)) return 0; length = 0; data = grabData(td->type, td->data, td->count, &length); if (data == NULL || length <= 0) return 0; /* Allocate more index space if necessary */ if (h->indexUsed == h->indexAlloced) { h->indexAlloced += INDEX_MALLOC_SIZE; h->index = xrealloc(h->index, h->indexAlloced * sizeof(*h->index)); } /* Fill in the index */ entry = h->index + h->indexUsed; entry->info.tag = td->tag; entry->info.type = td->type; entry->info.count = td->count; entry->info.offset = 0; entry->data = data; entry->length = length; if (h->indexUsed > 0 && td->tag < h->index[h->indexUsed-1].info.tag) h->flags &= ~HEADERFLAG_SORTED; h->indexUsed++; return 1; }
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 */ unsigned int pvlen = sizeof(il) + sizeof(dl) + (il * sizeof(struct entryInfo_s)) + dl;; Header h = NULL; entryInfo pe; unsigned char * dataStart; unsigned char * dataEnd; indexEntry entry; int rdlen; int fast = (flags & HEADERIMPORT_FAST); /* Sanity checks on header intro. */ if (bsize && bsize != pvlen) goto errxit; if (hdrchkTags(il) || hdrchkData(dl) || pvlen >= headerMaxbytes) goto errxit; h = headerCreate(blob, (flags & HEADERIMPORT_COPY) ? pvlen : 0, il); ei = h->blob; /* In case we had to copy */ pe = (entryInfo) &ei[2]; dataStart = (unsigned char *) (pe + il); dataEnd = dataStart + dl; entry = h->index; if (!(htonl(pe->tag) < RPMTAG_HEADERI18NTABLE)) { h->flags |= HEADERFLAG_LEGACY; entry->info.type = REGION_TAG_TYPE; entry->info.tag = RPMTAG_HEADERIMAGE; entry->info.count = REGION_TAG_COUNT; entry->info.offset = ((unsigned char *)pe - dataStart); /* negative offset */ entry->data = pe; entry->length = pvlen - sizeof(il) - sizeof(dl); rdlen = regionSwab(entry+1, il, 0, pe, dataStart, dataEnd, entry->info.offset, fast); if (rdlen != dl) goto errxit; entry->rdlen = rdlen; h->indexUsed++; } else { int32_t rdl; int32_t ril; h->flags &= ~HEADERFLAG_LEGACY; entry->info.type = htonl(pe->type); entry->info.count = htonl(pe->count); entry->info.tag = htonl(pe->tag); if (!ENTRY_IS_REGION(entry)) goto errxit; if (entry->info.type != REGION_TAG_TYPE) goto errxit; if (entry->info.count != REGION_TAG_COUNT) goto errxit; { int off = ntohl(pe->offset); if (off) { size_t nb = REGION_TAG_COUNT; int32_t stei[nb]; if (hdrchkRange(dl, (off + nb))) goto errxit; /* XXX Hmm, why the copy? */ memcpy(&stei, dataStart + off, nb); rdl = -ntohl(stei[2]); /* negative offset */ ril = rdl/sizeof(*pe); if (hdrchkTags(ril) || hdrchkData(rdl)) goto errxit; } else { ril = il; rdl = (ril * sizeof(struct entryInfo_s)); entry->info.tag = RPMTAG_HEADERIMAGE; } } entry->info.offset = -rdl; /* negative offset */ entry->data = pe; entry->length = pvlen - sizeof(il) - sizeof(dl); rdlen = regionSwab(entry+1, ril-1, 0, pe+1, dataStart, dataEnd, entry->info.offset, fast); if (rdlen < 0) goto errxit; entry->rdlen = rdlen; if (ril < h->indexUsed) { indexEntry newEntry = entry + ril; int ne = (h->indexUsed - ril); int rid = entry->info.offset+1; /* Load dribble entries from region. */ rdlen = regionSwab(newEntry, ne, rdlen, pe+ril, dataStart, dataEnd, rid, fast); if (rdlen < 0) goto errxit; { indexEntry firstEntry = newEntry; int save = h->indexUsed; int j; /* Dribble entries replace duplicate region entries. */ h->indexUsed -= ne; for (j = 0; j < ne; j++, newEntry++) { (void) headerDel(h, newEntry->info.tag); if (newEntry->info.tag == RPMTAG_BASENAMES) (void) headerDel(h, RPMTAG_OLDFILENAMES); } /* If any duplicate entries were replaced, move new entries down. */ if (h->indexUsed < (save - ne)) { memmove(h->index + h->indexUsed, firstEntry, (ne * sizeof(*entry))); } h->indexUsed += ne; } } rdlen += REGION_TAG_COUNT; if (rdlen != dl) goto errxit; } /* Force sorting, dribble lookups can cause early sort on partial header */ h->sorted = HEADERSORT_NONE; headerSort(h); h->flags |= HEADERFLAG_ALLOCATED; return h; errxit: if (h) { if (flags & HEADERIMPORT_COPY) free(h->blob); free(h->index); free(h); } return NULL; }
void * headerExport(Header h, unsigned int *bsize) { int32_t * ei = NULL; entryInfo pe; char * dataStart; char * te; unsigned len, diff; int32_t il = 0; int32_t dl = 0; indexEntry entry; int i; int drlen, ndribbles; if (h == NULL) return NULL; /* Sort entries by (offset,tag). */ headerUnsort(h); /* Compute (il,dl) for all tags, including those deleted in region. */ drlen = ndribbles = 0; for (i = 0, entry = h->index; i < h->indexUsed; i++, entry++) { if (ENTRY_IS_REGION(entry)) { int32_t rdl = -entry->info.offset; /* negative offset */ int32_t ril = rdl/sizeof(*pe); int rid = entry->info.offset; il += ril; dl += entry->rdlen + entry->info.count; /* XXX Legacy regions do not include the region tag and data. */ if (i == 0 && (h->flags & HEADERFLAG_LEGACY)) il += 1; /* Skip rest of entries in region, but account for dribbles. */ for (; i < h->indexUsed && entry->info.offset <= rid+1; i++, entry++) { if (entry->info.offset <= rid) continue; /* Alignment */ diff = alignDiff(entry->info.type, dl); if (diff) { drlen += diff; dl += diff; } ndribbles++; il++; drlen += entry->length; dl += entry->length; } i--; entry--; continue; } /* Ignore deleted drips. */ if (entry->data == NULL || entry->length <= 0) continue; /* Alignment */ dl += alignDiff(entry->info.type, dl); il++; dl += entry->length; } /* Sanity checks on header intro. */ if (hdrchkTags(il) || hdrchkData(dl)) goto errxit; len = sizeof(il) + sizeof(dl) + (il * sizeof(*pe)) + dl; ei = xmalloc(len); ei[0] = htonl(il); ei[1] = htonl(dl); pe = (entryInfo) &ei[2]; dataStart = te = (char *) (pe + il); for (i = 0, entry = h->index; i < h->indexUsed; i++, entry++) { const char * src; unsigned char *t; int count; int rdlen; unsigned int diff; if (entry->data == NULL || entry->length <= 0) continue; t = (unsigned char*)te; pe->tag = htonl(entry->info.tag); pe->type = htonl(entry->info.type); pe->count = htonl(entry->info.count); if (ENTRY_IS_REGION(entry)) { int32_t rdl = -entry->info.offset; /* negative offset */ int32_t ril = rdl/sizeof(*pe) + ndribbles; int rid = entry->info.offset; src = (char *)entry->data; rdlen = entry->rdlen; /* XXX Legacy regions do not include the region tag and data. */ if (i == 0 && (h->flags & HEADERFLAG_LEGACY)) { int32_t stei[4]; memcpy(pe+1, src, rdl); memcpy(te, src + rdl, rdlen); te += rdlen; pe->offset = htonl(te - dataStart); stei[0] = pe->tag; stei[1] = pe->type; stei[2] = htonl(-rdl-entry->info.count); stei[3] = pe->count; memcpy(te, stei, entry->info.count); te += entry->info.count; ril++; rdlen += entry->info.count; count = regionSwab(NULL, ril, 0, pe, t, NULL, 0, 0); if (count != rdlen) goto errxit; } else { memcpy(pe+1, src + sizeof(*pe), ((ril-1) * sizeof(*pe))); memcpy(te, src + (ril * sizeof(*pe)), rdlen+entry->info.count+drlen); te += rdlen; { entryInfo se = (entryInfo)src; int off = ntohl(se->offset); pe->offset = (off) ? htonl(te - dataStart) : htonl(off); } te += entry->info.count + drlen; count = regionSwab(NULL, ril, 0, pe, t, NULL, 0, 0); if (count != (rdlen + entry->info.count + drlen)) goto errxit; } /* Skip rest of entries in region. */ while (i < h->indexUsed && entry->info.offset <= rid+1) { i++; entry++; } i--; entry--; pe += ril; continue; } /* Ignore deleted drips. */ if (entry->data == NULL || entry->length <= 0) continue; /* Alignment */ diff = alignDiff(entry->info.type, (te - dataStart)); if (diff) { memset(te, 0, diff); te += diff; } pe->offset = htonl(te - dataStart); /* copy data w/ endian conversions */ switch (entry->info.type) { case RPM_INT64_TYPE: count = entry->info.count; src = entry->data; while (count--) { *((uint64_t *)te) = htonll(*((uint64_t *)src)); te += sizeof(uint64_t); src += sizeof(uint64_t); } break; case RPM_INT32_TYPE: count = entry->info.count; src = entry->data; while (count--) { *((int32_t *)te) = htonl(*((int32_t *)src)); te += sizeof(int32_t); src += sizeof(int32_t); } break; case RPM_INT16_TYPE: count = entry->info.count; src = entry->data; while (count--) { *((int16_t *)te) = htons(*((int16_t *)src)); te += sizeof(int16_t); src += sizeof(int16_t); } break; default: memcpy(te, entry->data, entry->length); te += entry->length; break; } pe++; } /* Insure that there are no memcpy underruns/overruns. */ if (((char *)pe) != dataStart) goto errxit; if ((((char *)ei)+len) != te) goto errxit; if (bsize) *bsize = len; headerSort(h); return (void *) ei; errxit: free(ei); return NULL; }
/** \ingroup header * Swap int32_t and int16_t arrays within header region. * * If a header region tag is in the set to be swabbed, as the data for a * a header region is located after all other tag data. * * @param entry header entry * @param il no. of entries * @param dl start no. bytes of data * @param pe header physical entry pointer (swapped) * @param dataStart header data start * @param dataEnd header data end * @param regionid region offset * @param fast use offsets for data sizes if possible * @return no. bytes of data in region, -1 on error */ static int regionSwab(indexEntry entry, int il, int dl, entryInfo pe, unsigned char * dataStart, const unsigned char * dataEnd, int regionid, int fast) { if ((entry != NULL && regionid >= 0) || (entry == NULL && regionid != 0)) return -1; for (; il > 0; il--, pe++) { struct indexEntry_s ie; ie.info.tag = ntohl(pe->tag); ie.info.type = ntohl(pe->type); ie.info.count = ntohl(pe->count); ie.info.offset = ntohl(pe->offset); if (hdrchkType(ie.info.type)) return -1; if (hdrchkData(ie.info.count)) return -1; if (hdrchkData(ie.info.offset)) return -1; if (hdrchkAlign(ie.info.type, ie.info.offset)) return -1; ie.data = dataStart + ie.info.offset; if (dataEnd && (unsigned char *)ie.data >= dataEnd) return -1; if (fast && il > 1) { ie.length = ntohl(pe[1].offset) - ie.info.offset; } else { ie.length = dataLength(ie.info.type, ie.data, ie.info.count, 1, dataEnd); } if (ie.length < 0 || hdrchkData(ie.length)) return -1; ie.rdlen = 0; if (entry) { ie.info.offset = regionid; *entry = ie; /* structure assignment */ entry++; } /* Alignment */ dl += alignDiff(ie.info.type, dl); /* Perform endian conversions */ switch (ntohl(pe->type)) { case RPM_INT64_TYPE: { uint64_t * it = ie.data; for (; ie.info.count > 0; ie.info.count--, it += 1) { if (dataEnd && ((unsigned char *)it) >= dataEnd) return -1; *it = htonll(*it); } } break; case RPM_INT32_TYPE: { int32_t * it = ie.data; for (; ie.info.count > 0; ie.info.count--, it += 1) { if (dataEnd && ((unsigned char *)it) >= dataEnd) return -1; *it = htonl(*it); } } break; case RPM_INT16_TYPE: { int16_t * it = ie.data; for (; ie.info.count > 0; ie.info.count--, it += 1) { if (dataEnd && ((unsigned char *)it) >= dataEnd) return -1; *it = htons(*it); } } break; } dl += ie.length; } return dl; }
Header headerLoad(void * uh) { int32_t * ei = (int32_t *) uh; int32_t il = ntohl(ei[0]); /* index length */ int32_t dl = ntohl(ei[1]); /* data length */ size_t pvlen = sizeof(il) + sizeof(dl) + (il * sizeof(struct entryInfo_s)) + dl; void * pv = uh; Header h = NULL; entryInfo pe; unsigned char * dataStart; unsigned char * dataEnd; indexEntry entry; int rdlen; /* Sanity checks on header intro. */ if (hdrchkTags(il) || hdrchkData(dl)) goto errxit; ei = (int32_t *) pv; pe = (entryInfo) &ei[2]; dataStart = (unsigned char *) (pe + il); dataEnd = dataStart + dl; h = xcalloc(1, sizeof(*h)); h->blob = uh; h->indexAlloced = il + 1; h->indexUsed = il; h->instance = 0; h->index = xcalloc(h->indexAlloced, sizeof(*h->index)); h->flags |= HEADERFLAG_SORTED; h->nrefs = 0; h = headerLink(h); entry = h->index; if (!(htonl(pe->tag) < HEADER_I18NTABLE)) { h->flags |= HEADERFLAG_LEGACY; entry->info.type = REGION_TAG_TYPE; entry->info.tag = HEADER_IMAGE; entry->info.count = REGION_TAG_COUNT; entry->info.offset = ((unsigned char *)pe - dataStart); /* negative offset */ entry->data = pe; entry->length = pvlen - sizeof(il) - sizeof(dl); rdlen = regionSwab(entry+1, il, 0, pe, dataStart, dataEnd, entry->info.offset); if (rdlen != dl) goto errxit; entry->rdlen = rdlen; h->indexUsed++; } else { int32_t rdl; int32_t ril; h->flags &= ~HEADERFLAG_LEGACY; entry->info.type = htonl(pe->type); entry->info.count = htonl(pe->count); if (hdrchkType(entry->info.type)) goto errxit; if (hdrchkTags(entry->info.count)) goto errxit; { int off = ntohl(pe->offset); if (hdrchkData(off)) goto errxit; if (off) { size_t nb = REGION_TAG_COUNT; int32_t stei[nb]; /* XXX Hmm, why the copy? */ memcpy(&stei, dataStart + off, nb); rdl = -ntohl(stei[2]); /* negative offset */ ril = rdl/sizeof(*pe); if (hdrchkTags(ril) || hdrchkData(rdl)) goto errxit; entry->info.tag = htonl(pe->tag); } else { ril = il; rdl = (ril * sizeof(struct entryInfo_s)); entry->info.tag = HEADER_IMAGE; } } entry->info.offset = -rdl; /* negative offset */ entry->data = pe; entry->length = pvlen - sizeof(il) - sizeof(dl); rdlen = regionSwab(entry+1, ril-1, 0, pe+1, dataStart, dataEnd, entry->info.offset); if (rdlen < 0) goto errxit; entry->rdlen = rdlen; if (ril < h->indexUsed) { indexEntry newEntry = entry + ril; int ne = (h->indexUsed - ril); int rid = entry->info.offset+1; int rc; /* Load dribble entries from region. */ rc = regionSwab(newEntry, ne, 0, pe+ril, dataStart, dataEnd, rid); if (rc < 0) goto errxit; rdlen += rc; { indexEntry firstEntry = newEntry; int save = h->indexUsed; int j; /* Dribble entries replace duplicate region entries. */ h->indexUsed -= ne; for (j = 0; j < ne; j++, newEntry++) { (void) headerDel(h, newEntry->info.tag); if (newEntry->info.tag == RPMTAG_BASENAMES) (void) headerDel(h, RPMTAG_OLDFILENAMES); } /* If any duplicate entries were replaced, move new entries down. */ if (h->indexUsed < (save - ne)) { memmove(h->index + h->indexUsed, firstEntry, (ne * sizeof(*entry))); } h->indexUsed += ne; } } } h->flags &= ~HEADERFLAG_SORTED; headerSort(h); h->flags |= HEADERFLAG_ALLOCATED; return h; errxit: if (h) { h->index = _free(h->index); h = _free(h); } return h; }
/** \ingroup header * Swap int32_t and int16_t arrays within header region. * * If a header region tag is in the set to be swabbed, as the data for a * a header region is located after all other tag data. * * @param entry header entry * @param il no. of entries * @param dl start no. bytes of data * @param pe header physical entry pointer (swapped) * @param dataStart header data start * @param dataEnd header data end * @param regionid region offset * @return no. bytes of data in region, -1 on error */ static int regionSwab(indexEntry entry, int il, int dl, entryInfo pe, unsigned char * dataStart, const unsigned char * dataEnd, int regionid) { for (; il > 0; il--, pe++) { struct indexEntry_s ie; rpmTagType type; ie.info.tag = ntohl(pe->tag); ie.info.type = ntohl(pe->type); ie.info.count = ntohl(pe->count); ie.info.offset = ntohl(pe->offset); if (hdrchkType(ie.info.type)) return -1; if (hdrchkData(ie.info.count)) return -1; if (hdrchkData(ie.info.offset)) return -1; if (hdrchkAlign(ie.info.type, ie.info.offset)) return -1; ie.data = dataStart + ie.info.offset; if (dataEnd && (unsigned char *)ie.data >= dataEnd) return -1; ie.length = dataLength(ie.info.type, ie.data, ie.info.count, 1, dataEnd); if (ie.length < 0 || hdrchkData(ie.length)) return -1; ie.rdlen = 0; if (entry) { ie.info.offset = regionid; *entry = ie; /* structure assignment */ entry++; } /* Alignment */ type = ie.info.type; if (typeSizes[type] > 1) { unsigned diff = typeSizes[type] - (dl % typeSizes[type]); if (diff != typeSizes[type]) { dl += diff; } } /* Perform endian conversions */ switch (ntohl(pe->type)) { case RPM_INT64_TYPE: { uint64_t * it = ie.data; for (; ie.info.count > 0; ie.info.count--, it += 1) { if (dataEnd && ((unsigned char *)it) >= dataEnd) return -1; *it = htonll(*it); } } break; case RPM_INT32_TYPE: { int32_t * it = ie.data; for (; ie.info.count > 0; ie.info.count--, it += 1) { if (dataEnd && ((unsigned char *)it) >= dataEnd) return -1; *it = htonl(*it); } } break; case RPM_INT16_TYPE: { int16_t * it = ie.data; for (; ie.info.count > 0; ie.info.count--, it += 1) { if (dataEnd && ((unsigned char *)it) >= dataEnd) return -1; *it = htons(*it); } } break; } dl += ie.length; } return dl; }
static rpmRC rpmpkgReadHeader(rpmKeyring keyring, rpmVSFlags vsflags, FD_t fd, Header *hdrp, char ** msg) { char *buf = NULL; int32_t block[4]; int32_t il; int32_t dl; int32_t * ei = NULL; size_t uc; size_t nb; Header h = NULL; rpmRC rc = RPMRC_FAIL; /* assume failure */ int xx; if (hdrp) *hdrp = NULL; if (msg) *msg = NULL; memset(block, 0, sizeof(block)); if ((xx = timedRead(fd, (char *)block, sizeof(block))) != sizeof(block)) { rasprintf(&buf, _("hdr size(%d): BAD, read returned %d\n"), (int)sizeof(block), xx); goto exit; } if (memcmp(block, rpm_header_magic, sizeof(rpm_header_magic))) { rasprintf(&buf, _("hdr magic: BAD\n")); goto exit; } il = ntohl(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]); if (hdrchkData(dl)) { rasprintf(&buf, _("hdr data: BAD, no. of bytes(%d) out of range\n"), dl); goto exit; } nb = (il * sizeof(struct entryInfo_s)) + dl; uc = sizeof(il) + sizeof(dl) + nb; ei = xmalloc(uc); ei[0] = block[2]; ei[1] = block[3]; if ((xx = timedRead(fd, (char *)&ei[2], nb)) != nb) { rasprintf(&buf, _("hdr blob(%zd): BAD, read returned %d\n"), nb, xx); goto exit; } /* Sanity check header tags */ rc = headerVerify(keyring, vsflags, ei, uc, msg); if (rc != RPMRC_OK) goto exit; /* OK, blob looks sane, load the header. */ h = headerLoad(ei); if (h == NULL) { rasprintf(&buf, _("hdr load: BAD\n")); rc = RPMRC_FAIL; goto exit; } ei = NULL; /* XXX will be freed with header */ exit: if (hdrp && h && rc == RPMRC_OK) *hdrp = headerLink(h); ei = _free(ei); h = headerFree(h); if (msg != NULL && *msg == NULL && buf != NULL) { *msg = buf; } else { free(buf); } return rc; }
void headerMergeLegacySigs(Header h, const Header sigh) { HeaderIterator hi; 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)) continue; break; } 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; 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; break; case RPM_STRING_TYPE: case RPM_BIN_TYPE: if (td.count >= 16*1024) continue; break; case RPM_STRING_ARRAY_TYPE: case RPM_I18NSTRING_TYPE: continue; break; } (void) headerPut(h, &td, HEADERPUT_DEFAULT); } } hi = headerFreeIterator(hi); }