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