diff --git a/lib/bencode.c b/lib/bencode.c index bb9509a09..9588001a8 100644 --- a/lib/bencode.c +++ b/lib/bencode.c @@ -36,7 +36,7 @@ static bencode_item_t __bencode_end_marker = { }; -static bencode_item_t *__bencode_decode(arena_t *buf, const char *s, const char *end); +static bencode_item_t *__bencode_decode(arena_t *buf, const char *s, const char *end, unsigned int depth); @@ -359,7 +359,9 @@ static void __bencode_hash_insert(bencode_item_t *key, struct __bencode_hash *ha } } -static bencode_item_t *__bencode_decode_dictionary(arena_t *buf, const char *s, const char *end) { +static bencode_item_t *__bencode_decode_dictionary(arena_t *buf, const char *s, const char *end, + unsigned int depth) +{ bencode_item_t *ret, *key, *value; struct __bencode_hash *hash; @@ -376,7 +378,7 @@ static bencode_item_t *__bencode_decode_dictionary(arena_t *buf, const char *s, memset(hash, 0, sizeof(*hash)); while (s < end) { - key = __bencode_decode(buf, s, end); + key = __bencode_decode(buf, s, end, depth); if (!key) return NULL; s += key->str_len; @@ -388,7 +390,7 @@ static bencode_item_t *__bencode_decode_dictionary(arena_t *buf, const char *s, if (s >= end) return NULL; - value = __bencode_decode(buf, s, end); + value = __bencode_decode(buf, s, end, depth); if (!value) return NULL; s += value->str_len; @@ -402,7 +404,9 @@ static bencode_item_t *__bencode_decode_dictionary(arena_t *buf, const char *s, return ret; } -static bencode_item_t *__bencode_decode_list(arena_t *buf, const char *s, const char *end) { +static bencode_item_t *__bencode_decode_list(arena_t *buf, const char *s, const char *end, + unsigned int depth) +{ bencode_item_t *ret, *item; if (*s != 'l') @@ -415,7 +419,7 @@ static bencode_item_t *__bencode_decode_list(arena_t *buf, const char *s, const __bencode_list_init(ret); while (s < end) { - item = __bencode_decode(buf, s, end); + item = __bencode_decode(buf, s, end, depth); if (!item) return NULL; s += item->str_len; @@ -518,15 +522,17 @@ done: return ret; } -static bencode_item_t *__bencode_decode(arena_t *buf, const char *s, const char *end) { +static bencode_item_t *__bencode_decode(arena_t *buf, const char *s, const char *end, unsigned int depth) { if (s >= end) return NULL; + if (depth > 64) // max recursions + return NULL; switch (*s) { case 'd': - return __bencode_decode_dictionary(buf, s, end); + return __bencode_decode_dictionary(buf, s, end, depth + 1); case 'l': - return __bencode_decode_list(buf, s, end); + return __bencode_decode_list(buf, s, end, depth + 1); case 'i': return __bencode_decode_integer(buf, s, end); case 'e': @@ -549,7 +555,7 @@ static bencode_item_t *__bencode_decode(arena_t *buf, const char *s, const char bencode_item_t *bencode_decode(arena_t *buf, const char *s, size_t len) { assert(s != NULL); - return __bencode_decode(buf, s, s + len); + return __bencode_decode(buf, s, s + len, 0); }