A clone of btpd with my configuration changes.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

benc.c 6.2 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #include <assert.h>
  2. #include <ctype.h>
  3. #include <errno.h>
  4. #include <inttypes.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include "benc.h"
  8. #define benc_safeset(out, val) if ((out) != NULL) *(out) = (val)
  9. static const char *benc_validate_aux(const char *p, const char *end);
  10. int
  11. benc_validate(const char *p, size_t len)
  12. {
  13. const char *end = p + len - 1;
  14. if (len <= 0)
  15. return EINVAL;
  16. return benc_validate_aux(p, end) == end ? 0 : EINVAL;
  17. }
  18. static const char *
  19. benc_validate_aux(const char *p, const char *end)
  20. {
  21. size_t d = 0;
  22. switch (*p) {
  23. case 'd':
  24. d = 1;
  25. case 'l':
  26. for (p++; p <= end && *p != 'e'; p++) {
  27. if (d != 0) {
  28. if (d % 2 == 1 && !isdigit(*p))
  29. return NULL;
  30. else
  31. d++;
  32. }
  33. if ((p = benc_validate_aux(p, end)) == NULL)
  34. return NULL;
  35. }
  36. if (p > end || (d != 0 && d % 2 != 1))
  37. return NULL;
  38. break;
  39. case 'i':
  40. p++;
  41. if (p > end)
  42. return NULL;
  43. if (*p == '-')
  44. p++;
  45. if (p > end || !isdigit(*p))
  46. return NULL;
  47. p++;
  48. while (p <= end && isdigit(*p))
  49. p++;
  50. if (p > end || *p != 'e')
  51. return NULL;
  52. break;
  53. default:
  54. if (isdigit(*p)) {
  55. size_t len = 0;
  56. while (p <= end && isdigit(*p)) {
  57. len *= 10;
  58. len += *p - '0';
  59. p++;
  60. }
  61. if (p <= end && *p == ':' && p + len <= end)
  62. p += len;
  63. else
  64. return NULL;
  65. }
  66. else
  67. return NULL;
  68. break;
  69. }
  70. return p;
  71. }
  72. size_t
  73. benc_length(const char *p)
  74. {
  75. size_t blen;
  76. const char *next;
  77. switch (*p) {
  78. case 'd':
  79. case 'l':
  80. blen = 2; // [l|d]...e
  81. next = benc_first(p);
  82. while (*next != 'e') {
  83. size_t len = benc_length(next);
  84. blen += len;
  85. next += len;
  86. }
  87. return blen;
  88. case 'i':
  89. for (next = p + 1; *next != 'e'; next++)
  90. ;
  91. return next - p + 1;
  92. default:
  93. assert(benc_str(p, &next, &blen, NULL) == 0);
  94. return next - p + blen;
  95. }
  96. }
  97. size_t
  98. benc_nelems(const char *p)
  99. {
  100. size_t nelems = 0;
  101. for (p = benc_first(p); p != NULL; p = benc_next(p))
  102. nelems++;
  103. return nelems;
  104. }
  105. const char *
  106. benc_first(const char *p)
  107. {
  108. assert(benc_islst(p));
  109. return *(p + 1) == 'e' ? NULL : p + 1;
  110. }
  111. const char *
  112. benc_next(const char *p)
  113. {
  114. size_t blen = benc_length(p);
  115. return *(p + blen) == 'e' ? NULL : p + blen;
  116. }
  117. int
  118. benc_str(const char *p, const char **out, size_t *len, const char**next)
  119. {
  120. size_t blen = 0;
  121. assert(isdigit(*p));
  122. blen = *p - '0';
  123. p++;
  124. while (isdigit(*p)) {
  125. blen *= 10;
  126. blen += *p - '0';
  127. p++;
  128. }
  129. assert(*p == ':');
  130. benc_safeset(len, blen);
  131. benc_safeset(out, p + 1);
  132. benc_safeset(next, *(p + blen + 1) == 'e' ? NULL : p + blen + 1);
  133. return 0;
  134. }
  135. int
  136. benc_strz(const char *p, char **out, size_t *len, const char **next)
  137. {
  138. int err;
  139. size_t blen;
  140. const char *bstr;
  141. if ((err = benc_str(p, &bstr, &blen, next)) == 0) {
  142. if ((*out = malloc(blen + 1)) != NULL) {
  143. memcpy(*out, bstr, blen);
  144. (*out)[blen] = '\0';
  145. benc_safeset(len, blen);
  146. } else
  147. err = ENOMEM;
  148. }
  149. return err;
  150. }
  151. int
  152. benc_stra(const char *p, char **out, size_t *len, const char **next)
  153. {
  154. int err;
  155. size_t blen;
  156. const char *bstr;
  157. if ((err = benc_str(p, &bstr, &blen, next)) == 0) {
  158. if ((*out = malloc(blen)) != NULL) {
  159. memcpy(*out, bstr, blen);
  160. benc_safeset(len, blen);
  161. } else
  162. err = ENOMEM;
  163. }
  164. return err;
  165. }
  166. int
  167. benc_int64(const char *p, int64_t *out, const char **next)
  168. {
  169. int sign = 1;
  170. int64_t res = 0;
  171. assert(*p == 'i');
  172. p++;
  173. if (*p == '-') {
  174. sign = -1;
  175. p++;
  176. }
  177. assert(isdigit(*p));
  178. res += sign * (*p - '0');
  179. p++;
  180. while (isdigit(*p)) {
  181. res *= sign * 10;
  182. res += sign * (*p - '0');
  183. p++;
  184. }
  185. assert(*p == 'e');
  186. benc_safeset(out, res);
  187. benc_safeset(next, *(p + 1) == 'e' ? NULL : p + 1);
  188. return 0;
  189. }
  190. int
  191. benc_uint32(const char *p, uint32_t *out, const char **next)
  192. {
  193. int err;
  194. int64_t res;
  195. if ((err = benc_int64(p, &res, next)) == 0) {
  196. if (res >= 0 && res <= 0xffffffffUL)
  197. *out = (uint32_t)res;
  198. else
  199. err = EINVAL;
  200. }
  201. return err;
  202. }
  203. int
  204. benc_dget_any(const char *p, const char *key, const char **val)
  205. {
  206. int res;
  207. size_t len, blen;
  208. const char *bstr;
  209. assert(benc_isdct(p));
  210. len = strlen(key);
  211. p = benc_first(p);
  212. while (p != NULL) {
  213. if ((res = benc_str(p, &bstr, &blen, &p)) != 0)
  214. return res;
  215. res = strncmp(bstr, key, blen);
  216. if (res == 0 && len == blen) {
  217. *val = p;
  218. return 0;
  219. } else if (res <= 0) {
  220. p = benc_next(p);
  221. } else
  222. return ENOENT;
  223. }
  224. return ENOENT;
  225. }
  226. int
  227. benc_dget_lst(const char *p, const char *key, const char **val)
  228. {
  229. int err;
  230. if ((err = benc_dget_any(p, key, val)) == 0)
  231. if (!benc_islst(*val))
  232. err = EINVAL;
  233. return err;
  234. }
  235. int
  236. benc_dget_dct(const char *p, const char *key, const char **val)
  237. {
  238. int err;
  239. if ((err = benc_dget_any(p, key, val)) == 0)
  240. if (!benc_isdct(*val))
  241. err = EINVAL;
  242. return err;
  243. }
  244. int
  245. benc_dget_str(const char *p, const char *key, const char **val, size_t *len)
  246. {
  247. int err;
  248. const char *sp;
  249. if ((err = benc_dget_any(p, key, &sp)) == 0)
  250. err = benc_isstr(sp) ? benc_str(sp, val, len, NULL) : EINVAL;
  251. return err;
  252. }
  253. int
  254. benc_dget_stra(const char *p, const char *key, char **val, size_t *len)
  255. {
  256. int err;
  257. const char *sp;
  258. if ((err = benc_dget_any(p, key, &sp)) == 0)
  259. err = benc_isstr(sp) ? benc_stra(sp, val, len, NULL) : EINVAL;
  260. return err;
  261. }
  262. int
  263. benc_dget_strz(const char *p, const char *key, char **val, size_t *len)
  264. {
  265. int err;
  266. const char *sp;
  267. if ((err = benc_dget_any(p, key, &sp)) == 0)
  268. err = benc_isstr(sp) ? benc_strz(sp, val, len, NULL) : EINVAL;
  269. return err;
  270. }
  271. int
  272. benc_dget_int64(const char *p, const char *key, int64_t *val)
  273. {
  274. int err;
  275. const char *ip;
  276. if ((err = benc_dget_any(p, key, &ip)) == 0)
  277. err = benc_isint(ip) ? benc_int64(ip, val, NULL) : EINVAL;
  278. return err;
  279. }
  280. int
  281. benc_dget_uint32(const char *p, const char *key, uint32_t *val)
  282. {
  283. int err;
  284. const char *ip;
  285. if ((err = benc_dget_any(p, key, &ip)) == 0)
  286. err = benc_isint(ip) ? benc_uint32(ip, val, NULL) : EINVAL;
  287. return err;
  288. }
  289. int
  290. benc_islst(const char *p)
  291. {
  292. return *p == 'l' || *p == 'd';
  293. }
  294. int
  295. benc_isdct(const char *p)
  296. {
  297. return *p == 'd';
  298. }
  299. int
  300. benc_isint(const char *p)
  301. {
  302. return *p == 'i';
  303. }
  304. int
  305. benc_isstr(const char *p)
  306. {
  307. return isdigit(*p);
  308. }