diff --git a/lib/bencode.c b/lib/bencode.c index 1bc003bf0..8baa6b5a6 100644 --- a/lib/bencode.c +++ b/lib/bencode.c @@ -44,7 +44,7 @@ static bencode_item_t __bencode_end_marker = { -static bencode_item_t *__bencode_decode(bencode_buffer_t *buf, const char *s, const char *end); +static bencode_item_t *__bencode_decode(bencode_buffer_t *buf, const char *s, const char *end, unsigned int depth); @@ -446,7 +446,9 @@ static void __bencode_hash_insert(bencode_item_t *key, struct __bencode_hash *ha } } -static bencode_item_t *__bencode_decode_dictionary(bencode_buffer_t *buf, const char *s, const char *end) { +static bencode_item_t *__bencode_decode_dictionary(bencode_buffer_t *buf, const char *s, const char *end, + unsigned int depth) +{ bencode_item_t *ret, *key, *value; struct __bencode_hash *hash; @@ -463,7 +465,7 @@ static bencode_item_t *__bencode_decode_dictionary(bencode_buffer_t *buf, const 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; @@ -475,7 +477,7 @@ static bencode_item_t *__bencode_decode_dictionary(bencode_buffer_t *buf, const 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; @@ -489,7 +491,9 @@ static bencode_item_t *__bencode_decode_dictionary(bencode_buffer_t *buf, const return ret; } -static bencode_item_t *__bencode_decode_list(bencode_buffer_t *buf, const char *s, const char *end) { +static bencode_item_t *__bencode_decode_list(bencode_buffer_t *buf, const char *s, const char *end, + unsigned int depth) +{ bencode_item_t *ret, *item; if (*s != 'l') @@ -502,7 +506,7 @@ static bencode_item_t *__bencode_decode_list(bencode_buffer_t *buf, const char * __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; @@ -601,15 +605,17 @@ colon: return ret; } -static bencode_item_t *__bencode_decode(bencode_buffer_t *buf, const char *s, const char *end) { +static bencode_item_t *__bencode_decode(bencode_buffer_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': @@ -632,7 +638,7 @@ static bencode_item_t *__bencode_decode(bencode_buffer_t *buf, const char *s, co bencode_item_t *bencode_decode(bencode_buffer_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); }