} state;
int first_header;
};
-#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
+#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
+#define RPM_MIN_HEAD_SIZE 16 /* Minimum size of 'Head'. */
static int rpm_bidder_bid(struct archive_read_filter_bidder *,
struct archive_read_filter *);
const void **);
static int rpm_filter_close(struct archive_read_filter *);
+static inline size_t rpm_limit_bytes(uint64_t, size_t);
+
#if ARCHIVE_VERSION_NUMBER < 4000000
/* Deprecated; remove in libarchive 4.0 */
int
return (ARCHIVE_OK);
}
+static inline size_t
+rpm_limit_bytes(uint64_t bytes, size_t max)
+{
+ return (bytes > max ? max : (size_t)bytes);
+}
+
static ssize_t
rpm_filter_read(struct archive_read_filter *self, const void **buff)
{
struct rpm *rpm;
const unsigned char *b;
- ssize_t avail_in, total;
- uint64_t used, n;
+ ssize_t avail_in, total, used;
+ size_t n;
uint64_t section;
uint64_t bytes;
}
break;
case ST_HEADER:
- n = 16 - rpm->hpos;
- if (n > avail_in - used)
- n = avail_in - used;
+ n = rpm_limit_bytes(RPM_MIN_HEAD_SIZE - rpm->hpos,
+ avail_in - used);
memcpy(rpm->header+rpm->hpos, b, n);
b += n;
used += n;
rpm->hpos += n;
- if (rpm->hpos == 16) {
+ if (rpm->hpos == RPM_MIN_HEAD_SIZE) {
if (rpm->header[0] != 0x8e ||
rpm->header[1] != 0xad ||
rpm->header[2] != 0xe8 ||
}
rpm->state = ST_ARCHIVE;
*buff = rpm->header;
- total = rpm->hpos;
+ total = RPM_MIN_HEAD_SIZE;
break;
}
/* Calculate 'Header' length. */
section = archive_be32dec(rpm->header+8);
bytes = archive_be32dec(rpm->header+12);
- rpm->hlen = 16 + section * 16 + bytes;
+ rpm->hlen = rpm->hpos + section * 16 + bytes;
rpm->state = ST_HEADER_DATA;
rpm->first_header = 0;
}
break;
case ST_HEADER_DATA:
- n = rpm->hlen - rpm->hpos;
- if (n > avail_in - used)
- n = avail_in - used;
+ n = rpm_limit_bytes(rpm->hlen - rpm->hpos,
+ avail_in - used);
b += n;
used += n;
rpm->hpos += n;
rpm->state = ST_PADDING;
break;
case ST_PADDING:
- while (used < (size_t)avail_in) {
+ while (used < avail_in) {
if (*b != 0) {
/* Read next header. */
rpm->state = ST_HEADER;
used = avail_in;
break;
}
- if (used == (size_t)avail_in) {
+ if (used == avail_in) {
rpm->total_in += used;
__archive_read_filter_consume(self->upstream, used);
b = NULL;