diff options
-rw-r--r-- | lib/header.c | 135 | ||||
-rw-r--r-- | lib/header_internal.h | 3 |
2 files changed, 48 insertions, 90 deletions
diff --git a/lib/header.c b/lib/header.c index 8844466b3..8b0fef791 100644 --- a/lib/header.c +++ b/lib/header.c @@ -848,93 +848,46 @@ int headerDel(Header h, rpmTagVal tag) return 0; } -Header headerImport(void * blob, unsigned int bsize, headerImportFlags flags) +rpmRC hdrblobImport(hdrblob blob, int fast, Header *hdrp, char **emsg) { - 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; - - if (flags & HEADERIMPORT_COPY && bsize) - ei = blob = memcpy(xmalloc(bsize), ei, bsize); - h = headerCreate(blob, il); - - pe = (entryInfo) &ei[2]; - dataStart = (unsigned char *) (pe + il); - dataEnd = dataStart + dl; + h = headerCreate(blob->ei, blob->il); entry = h->index; - if (!(htonl(pe->tag) < RPMTAG_HEADERI18NTABLE)) { + if (!(htonl(blob->pe->tag) < RPMTAG_HEADERI18NTABLE)) { + /* An original v3 header, create a legacy region entry for it */ 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) + entry->info.offset = ((unsigned char *)blob->pe - blob->dataStart); /* negative offset */ + + entry->data = blob->pe; + entry->length = blob->pvlen - sizeof(blob->il) - sizeof(blob->dl); + rdlen = regionSwab(entry+1, blob->il, 0, blob->pe, + blob->dataStart, blob->dataEnd, + entry->info.offset, fast); + if (rdlen != blob->dl) goto errxit; entry->rdlen = rdlen; h->indexUsed++; } else { - int32_t rdl; + /* Either a v4 header or an "upgraded" v3 header with a legacy region */ 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); + ei2h(blob->pe, &entry->info); + ril = (entry->info.offset != 0) ? blob->ril : blob->il; + + entry->info.offset = -(ril * sizeof(*blob->pe)); /* negative offset */ + entry->data = blob->pe; + entry->length = blob->pvlen - sizeof(blob->il) - sizeof(blob->dl); + rdlen = regionSwab(entry+1, ril-1, 0, blob->pe+1, + blob->dataStart, blob->dataEnd, + entry->info.offset, fast); if (rdlen < 0) goto errxit; entry->rdlen = rdlen; @@ -945,8 +898,8 @@ Header headerImport(void * blob, unsigned int bsize, headerImportFlags flags) int rid = entry->info.offset+1; /* Load dribble entries from region. */ - rdlen = regionSwab(newEntry, ne, rdlen, pe+ril, - dataStart, dataEnd, rid, fast); + rdlen = regionSwab(newEntry, ne, rdlen, blob->pe+ril, + blob->dataStart, blob->dataEnd, rid, fast); if (rdlen < 0) goto errxit; @@ -973,7 +926,7 @@ Header headerImport(void * blob, unsigned int bsize, headerImportFlags flags) rdlen += REGION_TAG_COUNT; - if (rdlen != dl) + if (rdlen != blob->dl) goto errxit; } @@ -981,17 +934,18 @@ Header headerImport(void * blob, unsigned int bsize, headerImportFlags flags) h->sorted = HEADERSORT_NONE; headerSort(h); h->flags |= HEADERFLAG_ALLOCATED; + if (hdrp) + *hdrp = h; - return h; + return RPMRC_OK; errxit: if (h) { - if (flags & HEADERIMPORT_COPY) - free(h->blob); free(h->index); free(h); + rasprintf(emsg, _("hdr load: BAD")); } - return NULL; + return RPMRC_FAIL; } Header headerReload(Header h, rpmTagVal tag) @@ -1982,7 +1936,7 @@ rpmRC hdrblobInit(const void *uh, size_t uc, blob->dataEnd = blob->dataStart + blob->dl; /* Is the blob the right size? */ - if (blob->uc > 0 && blob->pvlen != blob->uc) { + if (blob->pvlen >= headerMaxbytes || blob->pvlen != blob->uc) { rasprintf(emsg, _("blob size(%zd): BAD, 8 + 16 * il(%d) + dl(%d)"), blob->uc, blob->il, blob->dl); goto exit; @@ -2001,18 +1955,23 @@ exit: return rc; } -rpmRC hdrblobImport(hdrblob blob, headerImportFlags flags, - Header *hdrp, char **emsg) +Header headerImport(void * blob, unsigned int bsize, headerImportFlags flags) { - Header h = headerImport(blob->ei, blob->uc, flags); + Header h = NULL; + struct hdrblob_s hblob; + char *buf = NULL; + void * b = blob; - if (h == NULL) { - free(blob->ei); - rasprintf(emsg, _("hdr load: BAD")); - } else { - *hdrp = h; - } - blob->ei = NULL; + if (flags & HEADERIMPORT_COPY && bsize) + b = memcpy(xmalloc(bsize), b, bsize); - return (h != NULL) ? RPMRC_OK : RPMRC_FAIL; + /* Sanity checks on header intro. */ + if (hdrblobInit(b, bsize, 0, 0, &hblob, &buf) == RPMRC_OK) + hdrblobImport(&hblob, (flags & HEADERIMPORT_FAST), &h, &buf); + + if (h == NULL && b != blob) + free(b); + free(buf); + + return h; } diff --git a/lib/header_internal.h b/lib/header_internal.h index 76d1bd528..ec83c05be 100644 --- a/lib/header_internal.h +++ b/lib/header_internal.h @@ -57,8 +57,7 @@ RPM_GNUC_INTERNAL rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrblob blob, char **emsg); RPM_GNUC_INTERNAL -rpmRC hdrblobImport(hdrblob blob, headerImportFlags flags, - Header *hdrp, char **emsg); +rpmRC hdrblobImport(hdrblob blob, int fast, Header *hdrp, char **emsg); /** \ingroup header * Set header instance (rpmdb record number) |