DEBUG: hpack: add more traces to the hpack decoder
These ones are only enabled when DEBUG_HPACK is defined so they have no
effect on the production code.
diff --git a/src/hpack-dec.c b/src/hpack-dec.c
index dfbcaff..7c3605b 100644
--- a/src/hpack-dec.c
+++ b/src/hpack-dec.c
@@ -30,10 +30,12 @@
#include <stdlib.h>
#include <string.h>
+#include <common/standard.h>
#include <common/hpack-dec.h>
#include <common/hpack-huff.h>
#include <common/hpack-tbl.h>
#include <common/chunk.h>
+#include <common/h2.h>
#include <common/ist.h>
#include <types/global.h>
@@ -41,8 +43,10 @@
#if defined(DEBUG_HPACK)
#define hpack_debug_printf printf
+#define hpack_debug_hexdump debug_hexdump
#else
#define hpack_debug_printf(...) do { } while (0)
+#define hpack_debug_hexdump(...) do { } while (0)
#endif
/* reads a varint from <raw>'s lowest <b> bits and <len> bytes max (raw included).
@@ -155,6 +159,8 @@
int must_index;
int ret;
+ hpack_debug_hexdump(stderr, "[HPACK-DEC] ", (const char *)raw, 0, len);
+
chunk_reset(tmp);
ret = 0;
while (len) {
@@ -173,17 +179,22 @@
idx = get_var_int(&raw, &len, 7);
if (len == (uint32_t)-1) { // truncated
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TRUNCATED;
goto leave;
}
+ hpack_debug_printf(" idx=%u ", idx);
+
if (!hpack_valid_idx(dht, idx)) {
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
value = hpack_alloc_string(tmp, idx, hpack_idx_to_value(dht, idx));
if (!value.ptr) {
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
@@ -194,6 +205,7 @@
if (!name.len) {
name = hpack_alloc_string(tmp, idx, hpack_idx_to_name(dht, idx));
if (!name.ptr) {
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
@@ -202,17 +214,22 @@
}
else if (*raw >= 0x20 && *raw <= 0x3f) {
/* max dyn table size change */
+ hpack_debug_printf("%02x: p18: dynamic table size update : ", code);
+
if (ret) {
/* 7541#4.2.1 : DHT size update must only be at the beginning */
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
idx = get_var_int(&raw, &len, 5);
if (len == (uint32_t)-1) { // truncated
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TRUNCATED;
goto leave;
}
+ hpack_debug_printf(" new len=%u\n", idx);
continue;
}
else if (!(*raw & (*raw - 0x10))) {
@@ -233,6 +250,7 @@
/* retrieve name */
if (!len) { // truncated
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TRUNCATED;
goto leave;
}
@@ -240,6 +258,8 @@
huff = *raw & 0x80;
nlen = get_var_int(&raw, &len, 7);
if (len == (uint32_t)-1 || len < nlen) { // truncated
+ hpack_debug_printf("##ERR@%d## (truncated): nlen=%d len=%d\n",
+ __LINE__, (int)nlen, (int)len);
ret = -HPACK_ERR_TRUNCATED;
goto leave;
}
@@ -252,6 +272,7 @@
if (huff) {
char *ntrash = chunk_newstr(tmp);
if (!ntrash) {
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
@@ -262,12 +283,15 @@
ret = -HPACK_ERR_HUFFMAN;
goto leave;
}
+ hpack_debug_printf(" [name huff %d->%d] ", (int)name.len, (int)nlen);
+
tmp->len += nlen; // make room for the value
name = ist2(ntrash, nlen);
}
/* retrieve value */
if (!len) { // truncated
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TRUNCATED;
goto leave;
}
@@ -275,6 +299,8 @@
huff = *raw & 0x80;
vlen = get_var_int(&raw, &len, 7);
if (len == (uint32_t)-1 || len < vlen) { // truncated
+ hpack_debug_printf("##ERR@%d## : vlen=%d len=%d\n",
+ __LINE__, (int)vlen, (int)len);
ret = -HPACK_ERR_TRUNCATED;
goto leave;
}
@@ -286,6 +312,7 @@
if (huff) {
char *vtrash = chunk_newstr(tmp);
if (!vtrash) {
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
@@ -296,6 +323,8 @@
ret = -HPACK_ERR_HUFFMAN;
goto leave;
}
+ hpack_debug_printf(" [value huff %d->%d] ", (int)value.len, (int)vlen);
+
tmp->len += vlen; // make room for the value
value = ist2(vtrash, vlen);
}
@@ -322,12 +351,16 @@
else
idx = get_var_int(&raw, &len, 4);
+ hpack_debug_printf(" idx=%u ", idx);
+
if (len == (uint32_t)-1 || !len) { // truncated
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TRUNCATED;
goto leave;
}
if (!hpack_valid_idx(dht, idx)) {
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
@@ -336,6 +369,7 @@
huff = *raw & 0x80;
vlen = get_var_int(&raw, &len, 7);
if (len == (uint32_t)-1 || len < vlen) { // truncated
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TRUNCATED;
goto leave;
}
@@ -347,13 +381,16 @@
if (huff) {
char *vtrash = chunk_newstr(tmp);
if (!vtrash) {
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
vlen = huff_dec((const uint8_t *)value.ptr, value.len, vtrash, tmp->size - tmp->len);
if (vlen == (uint32_t)-1) {
- hpack_debug_printf("1: can't decode huffman.\n");
+ hpack_debug_printf("##ERR@%d## can't decode huffman : ilen=%d osize=%d\n",
+ __LINE__, (int)value.len, (int)(tmp->size - tmp->len));
+ hpack_debug_hexdump(stderr, "[HUFFMAN] ", value.ptr, 0, value.len);
ret = -HPACK_ERR_HUFFMAN;
goto leave;
}
@@ -368,6 +405,7 @@
if (!name.len) {
name = hpack_alloc_string(tmp, idx, hpack_idx_to_name(dht, idx));
if (!name.ptr) {
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
@@ -382,6 +420,7 @@
* - name.ptr != NULL || must_index : general header, unknown pseudo-header or index needed
*/
if (ret >= list_size) {
+ hpack_debug_printf("##ERR@%d##\n", __LINE__);
ret = -HPACK_ERR_TOO_LARGE;
goto leave;
}
@@ -397,11 +436,11 @@
}
hpack_debug_printf("\e[1;34m%s\e[0m: ",
- istpad(trash.str, name.ptr ? name : hpack_idx_to_name(dht, idx)).ptr);
+ name.ptr ? istpad(trash.str, name).ptr : h2_phdr_to_str(name.len));
- hpack_debug_printf("\e[1;35m%s\e[0m [idx=%d, used=%d]\n",
- istpad(trash.str, value).ptr,
- must_index, dht->used);
+ hpack_debug_printf("\e[1;35m%s\e[0m [mustidx=%d, used=%d] [n=(%p,%d) v=(%p,%d)]\n",
+ istpad(trash.str, value).ptr, must_index, dht->used,
+ name.ptr, (int)name.len, value.ptr, (int)value.len);
}
if (ret >= list_size) {
@@ -414,5 +453,6 @@
ret++;
leave:
+ hpack_debug_printf("-- done: ret=%d list_size=%d --\n", (int)ret, (int)list_size);
return ret;
}