QPACK_ERR_DB, /* cannot decode Delta Base prefix field */
QPACK_ERR_TRUNCATED, /* truncated stream */
QPACK_ERR_HUFFMAN, /* huffman decoding error */
+ QPACK_ERR_TOO_LARGE, /* decoded request/response is too large */
};
struct qpack_dec {
};
int qpack_decode_fs(const unsigned char *buf, uint64_t len, struct buffer *tmp,
- struct http_hdr *list);
+ struct http_hdr *list, int list_size);
int qpack_decode_enc(struct buffer *buf, void *ctx);
int qpack_decode_dec(struct buffer *buf, void *ctx);
/* TODO support buffer wrapping */
BUG_ON(b_head(buf) + len >= b_wrap(buf));
- if (qpack_decode_fs((const unsigned char *)b_head(buf), len, tmp, list) < 0)
+ if (qpack_decode_fs((const unsigned char *)b_head(buf), len, tmp,
+ list, sizeof(list) / sizeof(list[0])) < 0) {
return -1;
+ }
qc_get_buf(qcs, &htx_buf);
BUG_ON(!b_size(&htx_buf));
status = sl->info.res.status;
}
else if (type == HTX_BLK_HDR) {
+ if (unlikely(hdr >= sizeof(list) / sizeof(list[0]) - 1))
+ goto fail;
list[hdr].n = htx_get_blk_name(htx, blk);
list[hdr].v = htx_get_blk_value(htx, blk);
hdr++;
}
/* Decode a field section from the <raw> buffer of <len> bytes. Each parsed
- * header is inserted into <list> and uses <tmp> as a storage for some elements
- * pointing into it. An end marker is inserted at the end of the list with
- * empty strings as name/value.
+ * header is inserted into <list> of <list_size> entries max and uses <tmp> as
+ * a storage for some elements pointing into it. An end marker is inserted at
+ * the end of the list with empty strings as name/value.
*
* Returns 0 on success. In case of error, a negative code QPACK_ERR_* is
* returned.
*/
int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp,
- struct http_hdr *list)
+ struct http_hdr *list, int list_size)
{
uint64_t enc_ric, db;
int s;
(unsigned long long)enc_ric, (unsigned long long)db, !!s);
/* Decode field lines */
while (len) {
+ if (hdr_idx >= list_size) {
+ qpack_debug_printf(stderr, "##ERR@%d\n", __LINE__);
+ ret = -QPACK_ERR_TOO_LARGE;
+ goto out;
+ }
+
/* parse field line representation */
efl_type = *raw & QPACK_EFL_BITMASK;
qpack_debug_printf(stderr, "efl_type=0x%02x\n", efl_type);
qpack_debug_printf(stderr, "\n");
}
+ if (hdr_idx >= list_size) {
+ qpack_debug_printf(stderr, "##ERR@%d\n", __LINE__);
+ ret = -QPACK_ERR_TOO_LARGE;
+ goto out;
+ }
+
/* put an end marker */
list[hdr_idx].n = list[hdr_idx].v = IST_NULL;