1 /*
2  * This file Copyright (C) 2008-2014 Mnemosyne LLC
3  *
4  * It may be used under the GNU GPL versions 2 or 3
5  * or any future license endorsed by Mnemosyne LLC.
6  *
7  */
8 
9 #include <ctype.h> /* isdigit() */
10 #include <errno.h>
11 #include <stdlib.h> /* strtoul() */
12 #include <string.h> /* strlen(), memchr() */
13 
14 #include <event2/buffer.h>
15 
16 #include "ConvertUTF.h"
17 
18 #define __LIBTRANSMISSION_VARIANT_MODULE__
19 
20 #include "transmission.h"
21 #include "ptrarray.h"
22 #include "utils.h" /* tr_snprintf() */
23 #include "variant.h"
24 #include "variant-common.h"
25 
26 #define MAX_BENC_STR_LENGTH (128 * 1024 * 1024) /* arbitrary */
27 
28 /***
29 ****  tr_variantParse()
30 ****  tr_variantLoad()
31 ***/
32 
33 /**
34  * The initial i and trailing e are beginning and ending delimiters.
35  * You can have negative numbers such as i-3e. You cannot prefix the
36  * number with a zero such as i04e. However, i0e is valid.
37  * Example: i3e represents the integer "3"
38  * NOTE: The maximum number of bit of this integer is unspecified,
39  * but to handle it as a signed 64bit integer is mandatory to handle
40  * "large files" aka .torrent for more that 4Gbyte
41  */
tr_bencParseInt(uint8_t const * buf,uint8_t const * bufend,uint8_t const ** setme_end,int64_t * setme_val)42 int tr_bencParseInt(uint8_t const* buf, uint8_t const* bufend, uint8_t const** setme_end, int64_t* setme_val)
43 {
44     char* endptr;
45     void const* begin;
46     void const* end;
47     int64_t val;
48 
49     if (buf >= bufend)
50     {
51         return EILSEQ;
52     }
53 
54     if (*buf != 'i')
55     {
56         return EILSEQ;
57     }
58 
59     begin = buf + 1;
60     end = memchr(begin, 'e', (bufend - buf) - 1);
61 
62     if (end == NULL)
63     {
64         return EILSEQ;
65     }
66 
67     errno = 0;
68     val = evutil_strtoll(begin, &endptr, 10);
69 
70     if (errno != 0 || endptr != end) /* incomplete parse */
71     {
72         return EILSEQ;
73     }
74 
75     if (val != 0 && *(char const*)begin == '0') /* no leading zeroes! */
76     {
77         return EILSEQ;
78     }
79 
80     *setme_end = (uint8_t const*)end + 1;
81     *setme_val = val;
82     return 0;
83 }
84 
85 /**
86  * Byte strings are encoded as follows:
87  * <string length encoded in base ten ASCII>:<string data>
88  * Note that there is no constant beginning delimiter, and no ending delimiter.
89  * Example: 4:spam represents the string "spam"
90  */
tr_bencParseStr(uint8_t const * buf,uint8_t const * bufend,uint8_t const ** setme_end,uint8_t const ** setme_str,size_t * setme_strlen)91 int tr_bencParseStr(uint8_t const* buf, uint8_t const* bufend, uint8_t const** setme_end, uint8_t const** setme_str,
92     size_t* setme_strlen)
93 {
94     void const* end;
95     size_t len;
96     char* ulend;
97     uint8_t const* strbegin;
98     uint8_t const* strend;
99 
100     if (buf >= bufend)
101     {
102         goto err;
103     }
104 
105     if (!isdigit(*buf))
106     {
107         goto err;
108     }
109 
110     end = memchr(buf, ':', bufend - buf);
111 
112     if (end == NULL)
113     {
114         goto err;
115     }
116 
117     errno = 0;
118     len = strtoul((char const*)buf, &ulend, 10);
119 
120     if (errno != 0 || ulend != end || len > MAX_BENC_STR_LENGTH)
121     {
122         goto err;
123     }
124 
125     strbegin = (uint8_t const*)end + 1;
126     strend = strbegin + len;
127 
128     if (strend < strbegin || strend > bufend)
129     {
130         goto err;
131     }
132 
133     *setme_end = (uint8_t const*)end + 1 + len;
134     *setme_str = (uint8_t const*)end + 1;
135     *setme_strlen = len;
136     return 0;
137 
138 err:
139     *setme_end = NULL;
140     *setme_str = NULL;
141     *setme_strlen = 0;
142     return EILSEQ;
143 }
144 
get_node(tr_ptrArray * stack,tr_quark * key,tr_variant * top,int * err)145 static tr_variant* get_node(tr_ptrArray* stack, tr_quark* key, tr_variant* top, int* err)
146 {
147     tr_variant* node = NULL;
148 
149     if (tr_ptrArrayEmpty(stack))
150     {
151         node = top;
152     }
153     else
154     {
155         tr_variant* parent = tr_ptrArrayBack(stack);
156 
157         if (tr_variantIsList(parent))
158         {
159             node = tr_variantListAdd(parent);
160         }
161         else if (*key != 0 && tr_variantIsDict(parent))
162         {
163             node = tr_variantDictAdd(parent, *key);
164             *key = 0;
165         }
166         else
167         {
168             *err = EILSEQ;
169         }
170     }
171 
172     return node;
173 }
174 
175 /**
176  * This function's previous recursive implementation was
177  * easier to read, but was vulnerable to a smash-stacking
178  * attack via maliciously-crafted bencoded data. (#667)
179  */
tr_variantParseBenc(void const * buf_in,void const * bufend_in,tr_variant * top,char const ** setme_end)180 int tr_variantParseBenc(void const* buf_in, void const* bufend_in, tr_variant* top, char const** setme_end)
181 {
182     int err = 0;
183     uint8_t const* buf = buf_in;
184     uint8_t const* bufend = bufend_in;
185     tr_ptrArray stack = TR_PTR_ARRAY_INIT;
186     tr_quark key = 0;
187 
188     tr_variantInit(top, 0);
189 
190     while (buf != bufend)
191     {
192         if (buf > bufend) /* no more text to parse... */
193         {
194             err = EILSEQ;
195         }
196 
197         if (err != 0)
198         {
199             break;
200         }
201 
202         if (*buf == 'i') /* int */
203         {
204             int64_t val;
205             uint8_t const* end;
206             tr_variant* v;
207 
208             if ((err = tr_bencParseInt(buf, bufend, &end, &val)) != 0)
209             {
210                 break;
211             }
212 
213             buf = end;
214 
215             if ((v = get_node(&stack, &key, top, &err)) != NULL)
216             {
217                 tr_variantInitInt(v, val);
218             }
219         }
220         else if (*buf == 'l') /* list */
221         {
222             tr_variant* v;
223 
224             ++buf;
225 
226             if ((v = get_node(&stack, &key, top, &err)) != NULL)
227             {
228                 tr_variantInitList(v, 0);
229                 tr_ptrArrayAppend(&stack, v);
230             }
231         }
232         else if (*buf == 'd') /* dict */
233         {
234             tr_variant* v;
235 
236             ++buf;
237 
238             if ((v = get_node(&stack, &key, top, &err)) != NULL)
239             {
240                 tr_variantInitDict(v, 0);
241                 tr_ptrArrayAppend(&stack, v);
242             }
243         }
244         else if (*buf == 'e') /* end of list or dict */
245         {
246             ++buf;
247 
248             if (tr_ptrArrayEmpty(&stack) || key != 0)
249             {
250                 err = EILSEQ;
251                 break;
252             }
253             else
254             {
255                 tr_ptrArrayPop(&stack);
256 
257                 if (tr_ptrArrayEmpty(&stack))
258                 {
259                     break;
260                 }
261             }
262         }
263         else if (isdigit(*buf)) /* string? */
264         {
265             tr_variant* v;
266             uint8_t const* end;
267             uint8_t const* str;
268             size_t str_len;
269 
270             if ((err = tr_bencParseStr(buf, bufend, &end, &str, &str_len)) != 0)
271             {
272                 break;
273             }
274 
275             buf = end;
276 
277             if (key == 0 && !tr_ptrArrayEmpty(&stack) && tr_variantIsDict(tr_ptrArrayBack(&stack)))
278             {
279                 key = tr_quark_new(str, str_len);
280             }
281             else if ((v = get_node(&stack, &key, top, &err)) != NULL)
282             {
283                 tr_variantInitStr(v, str, str_len);
284             }
285         }
286         else /* invalid bencoded text... march past it */
287         {
288             ++buf;
289         }
290 
291         if (tr_ptrArrayEmpty(&stack))
292         {
293             break;
294         }
295     }
296 
297     if (err == 0 && (top->type == 0 || !tr_ptrArrayEmpty(&stack)))
298     {
299         err = EILSEQ;
300     }
301 
302     if (err == 0)
303     {
304         if (setme_end != NULL)
305         {
306             *setme_end = (char const*)buf;
307         }
308     }
309     else if (top->type != 0)
310     {
311         tr_variantFree(top);
312         tr_variantInit(top, 0);
313     }
314 
315     tr_ptrArrayDestruct(&stack, NULL);
316     return err;
317 }
318 
319 /****
320 *****
321 ****/
322 
saveIntFunc(tr_variant const * val,void * evbuf)323 static void saveIntFunc(tr_variant const* val, void* evbuf)
324 {
325     evbuffer_add_printf(evbuf, "i%" PRId64 "e", val->val.i);
326 }
327 
saveBoolFunc(tr_variant const * val,void * evbuf)328 static void saveBoolFunc(tr_variant const* val, void* evbuf)
329 {
330     if (val->val.b)
331     {
332         evbuffer_add(evbuf, "i1e", 3);
333     }
334     else
335     {
336         evbuffer_add(evbuf, "i0e", 3);
337     }
338 }
339 
saveRealFunc(tr_variant const * val,void * evbuf)340 static void saveRealFunc(tr_variant const* val, void* evbuf)
341 {
342     int len;
343     char buf[128];
344 
345     len = tr_snprintf(buf, sizeof(buf), "%f", val->val.d);
346     evbuffer_add_printf(evbuf, "%d:", len);
347     evbuffer_add(evbuf, buf, len);
348 }
349 
saveStringFunc(tr_variant const * v,void * evbuf)350 static void saveStringFunc(tr_variant const* v, void* evbuf)
351 {
352     size_t len;
353     char const* str;
354     if (!tr_variantGetStr(v, &str, &len))
355     {
356         len = 0;
357         str = NULL;
358     }
359 
360     evbuffer_add_printf(evbuf, "%zu:", len);
361     evbuffer_add(evbuf, str, len);
362 }
363 
saveDictBeginFunc(tr_variant const * val UNUSED,void * evbuf)364 static void saveDictBeginFunc(tr_variant const* val UNUSED, void* evbuf)
365 {
366     evbuffer_add(evbuf, "d", 1);
367 }
368 
saveListBeginFunc(tr_variant const * val UNUSED,void * evbuf)369 static void saveListBeginFunc(tr_variant const* val UNUSED, void* evbuf)
370 {
371     evbuffer_add(evbuf, "l", 1);
372 }
373 
saveContainerEndFunc(tr_variant const * val UNUSED,void * evbuf)374 static void saveContainerEndFunc(tr_variant const* val UNUSED, void* evbuf)
375 {
376     evbuffer_add(evbuf, "e", 1);
377 }
378 
379 static struct VariantWalkFuncs const walk_funcs =
380 {
381     saveIntFunc,
382     saveBoolFunc,
383     saveRealFunc,
384     saveStringFunc,
385     saveDictBeginFunc,
386     saveListBeginFunc,
387     saveContainerEndFunc
388 };
389 
tr_variantToBufBenc(tr_variant const * top,struct evbuffer * buf)390 void tr_variantToBufBenc(tr_variant const* top, struct evbuffer* buf)
391 {
392     tr_variantWalk(top, &walk_funcs, buf, true);
393 }
394