decode_unittests.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /* This includes the whole .c file to get access to static functions. */
  2. #define PB_ENABLE_MALLOC
  3. #include "pb_common.c"
  4. #include "pb_decode.c"
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include "unittests.h"
  8. #include "unittestproto.pb.h"
  9. #define S(x) pb_istream_from_buffer((uint8_t*)x, sizeof(x) - 1)
  10. bool stream_callback(pb_istream_t *stream, uint8_t *buf, size_t count)
  11. {
  12. if (stream->state != NULL)
  13. return false; /* Simulate error */
  14. if (buf != NULL)
  15. memset(buf, 'x', count);
  16. return true;
  17. }
  18. /* Verifies that the stream passed to callback matches the byte array pointed to by arg. */
  19. bool callback_check(pb_istream_t *stream, const pb_field_t *field, void **arg)
  20. {
  21. int i;
  22. uint8_t byte;
  23. pb_bytes_array_t *ref = (pb_bytes_array_t*) *arg;
  24. for (i = 0; i < ref->size; i++)
  25. {
  26. if (!pb_read(stream, &byte, 1))
  27. return false;
  28. if (byte != ref->bytes[i])
  29. return false;
  30. }
  31. return true;
  32. }
  33. int main()
  34. {
  35. int status = 0;
  36. {
  37. uint8_t buffer1[] = "foobartest1234";
  38. uint8_t buffer2[sizeof(buffer1)];
  39. pb_istream_t stream = pb_istream_from_buffer(buffer1, sizeof(buffer1));
  40. COMMENT("Test pb_read and pb_istream_t");
  41. TEST(pb_read(&stream, buffer2, 6))
  42. TEST(memcmp(buffer2, "foobar", 6) == 0)
  43. TEST(stream.bytes_left == sizeof(buffer1) - 6)
  44. TEST(pb_read(&stream, buffer2 + 6, stream.bytes_left))
  45. TEST(memcmp(buffer1, buffer2, sizeof(buffer1)) == 0)
  46. TEST(stream.bytes_left == 0)
  47. TEST(!pb_read(&stream, buffer2, 1))
  48. }
  49. {
  50. uint8_t buffer[20];
  51. pb_istream_t stream = {&stream_callback, NULL, 20};
  52. COMMENT("Test pb_read with custom callback");
  53. TEST(pb_read(&stream, buffer, 5))
  54. TEST(memcmp(buffer, "xxxxx", 5) == 0)
  55. TEST(!pb_read(&stream, buffer, 50))
  56. stream.state = (void*)1; /* Simulated error return from callback */
  57. TEST(!pb_read(&stream, buffer, 5))
  58. stream.state = NULL;
  59. TEST(pb_read(&stream, buffer, 15))
  60. }
  61. {
  62. pb_istream_t s;
  63. uint64_t u;
  64. int64_t i;
  65. COMMENT("Test pb_decode_varint");
  66. TEST((s = S("\x00"), pb_decode_varint(&s, &u) && u == 0));
  67. TEST((s = S("\x01"), pb_decode_varint(&s, &u) && u == 1));
  68. TEST((s = S("\xAC\x02"), pb_decode_varint(&s, &u) && u == 300));
  69. TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint(&s, &u) && u == UINT32_MAX));
  70. TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint(&s, (uint64_t*)&i) && i == UINT32_MAX));
  71. TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"),
  72. pb_decode_varint(&s, (uint64_t*)&i) && i == -1));
  73. TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"),
  74. pb_decode_varint(&s, &u) && u == UINT64_MAX));
  75. TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"),
  76. !pb_decode_varint(&s, &u)));
  77. }
  78. {
  79. pb_istream_t s;
  80. uint32_t u;
  81. COMMENT("Test pb_decode_varint32");
  82. TEST((s = S("\x00"), pb_decode_varint32(&s, &u) && u == 0));
  83. TEST((s = S("\x01"), pb_decode_varint32(&s, &u) && u == 1));
  84. TEST((s = S("\xAC\x02"), pb_decode_varint32(&s, &u) && u == 300));
  85. TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint32(&s, &u) && u == UINT32_MAX));
  86. TEST((s = S("\xFF\xFF\xFF\xFF\x8F\x00"), pb_decode_varint32(&s, &u) && u == UINT32_MAX));
  87. TEST((s = S("\xFF\xFF\xFF\xFF\x10"), !pb_decode_varint32(&s, &u)));
  88. TEST((s = S("\xFF\xFF\xFF\xFF\x40"), !pb_decode_varint32(&s, &u)));
  89. TEST((s = S("\xFF\xFF\xFF\xFF\xFF\x01"), !pb_decode_varint32(&s, &u)));
  90. TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x00"), !pb_decode_varint32(&s, &u)));
  91. }
  92. {
  93. pb_istream_t s;
  94. COMMENT("Test pb_skip_varint");
  95. TEST((s = S("\x00""foobar"), pb_skip_varint(&s) && s.bytes_left == 6))
  96. TEST((s = S("\xAC\x02""foobar"), pb_skip_varint(&s) && s.bytes_left == 6))
  97. TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01""foobar"),
  98. pb_skip_varint(&s) && s.bytes_left == 6))
  99. TEST((s = S("\xFF"), !pb_skip_varint(&s)))
  100. }
  101. {
  102. pb_istream_t s;
  103. COMMENT("Test pb_skip_string")
  104. TEST((s = S("\x00""foobar"), pb_skip_string(&s) && s.bytes_left == 6))
  105. TEST((s = S("\x04""testfoobar"), pb_skip_string(&s) && s.bytes_left == 6))
  106. TEST((s = S("\x04"), !pb_skip_string(&s)))
  107. TEST((s = S("\xFF"), !pb_skip_string(&s)))
  108. }
  109. {
  110. pb_istream_t s = S("\x01\x00");
  111. pb_field_iter_t f;
  112. uint32_t d;
  113. f.type = PB_LTYPE_VARINT;
  114. f.data_size = sizeof(d);
  115. f.pData = &d;
  116. COMMENT("Test pb_dec_varint using uint32_t")
  117. TEST(pb_dec_varint(&s, &f) && d == 1)
  118. /* Verify that no more than data_size is written. */
  119. d = 0xFFFFFFFF;
  120. f.data_size = 1;
  121. TEST(pb_dec_varint(&s, &f) && (d == 0xFFFFFF00 || d == 0x00FFFFFF))
  122. }
  123. {
  124. pb_istream_t s;
  125. pb_field_iter_t f;
  126. int32_t d;
  127. f.type = PB_LTYPE_SVARINT;
  128. f.data_size = sizeof(d);
  129. f.pData = &d;
  130. COMMENT("Test pb_dec_varint using sint32_t")
  131. TEST((s = S("\x01"), pb_dec_varint(&s, &f) && d == -1))
  132. TEST((s = S("\x02"), pb_dec_varint(&s, &f) && d == 1))
  133. TEST((s = S("\xfe\xff\xff\xff\x0f"), pb_dec_varint(&s, &f) && d == INT32_MAX))
  134. TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_varint(&s, &f) && d == INT32_MIN))
  135. }
  136. {
  137. pb_istream_t s;
  138. pb_field_iter_t f;
  139. int64_t d;
  140. f.type = PB_LTYPE_SVARINT;
  141. f.data_size = sizeof(d);
  142. f.pData = &d;
  143. COMMENT("Test pb_dec_varint using sint64_t")
  144. TEST((s = S("\x01"), pb_dec_varint(&s, &f) && d == -1))
  145. TEST((s = S("\x02"), pb_dec_varint(&s, &f) && d == 1))
  146. TEST((s = S("\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_varint(&s, &f) && d == INT64_MAX))
  147. TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_varint(&s, &f) && d == INT64_MIN))
  148. }
  149. {
  150. pb_istream_t s;
  151. pb_field_iter_t f;
  152. int32_t d;
  153. f.type = PB_LTYPE_SVARINT;
  154. f.data_size = sizeof(d);
  155. f.pData = &d;
  156. COMMENT("Test pb_dec_varint overflow detection using sint32_t");
  157. TEST((s = S("\xfe\xff\xff\xff\x0f"), pb_dec_varint(&s, &f)));
  158. TEST((s = S("\xfe\xff\xff\xff\x10"), !pb_dec_varint(&s, &f)));
  159. TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_varint(&s, &f)));
  160. TEST((s = S("\xff\xff\xff\xff\x10"), !pb_dec_varint(&s, &f)));
  161. }
  162. {
  163. pb_istream_t s;
  164. pb_field_iter_t f;
  165. uint32_t d;
  166. f.type = PB_LTYPE_UVARINT;
  167. f.data_size = sizeof(d);
  168. f.pData = &d;
  169. COMMENT("Test pb_dec_varint using uint32_t")
  170. TEST((s = S("\x01"), pb_dec_varint(&s, &f) && d == 1))
  171. TEST((s = S("\x02"), pb_dec_varint(&s, &f) && d == 2))
  172. TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_varint(&s, &f) && d == UINT32_MAX))
  173. }
  174. {
  175. pb_istream_t s;
  176. pb_field_iter_t f;
  177. uint64_t d;
  178. f.type = PB_LTYPE_UVARINT;
  179. f.data_size = sizeof(d);
  180. f.pData = &d;
  181. COMMENT("Test pb_dec_varint using uint64_t")
  182. TEST((s = S("\x01"), pb_dec_varint(&s, &f) && d == 1))
  183. TEST((s = S("\x02"), pb_dec_varint(&s, &f) && d == 2))
  184. TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_varint(&s, &f) && d == UINT64_MAX))
  185. }
  186. {
  187. pb_istream_t s;
  188. pb_field_iter_t f;
  189. uint32_t d;
  190. f.type = PB_LTYPE_UVARINT;
  191. f.data_size = sizeof(d);
  192. f.pData = &d;
  193. COMMENT("Test pb_dec_varint overflow detection using uint32_t");
  194. TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_varint(&s, &f)));
  195. TEST((s = S("\xff\xff\xff\xff\x10"), !pb_dec_varint(&s, &f)));
  196. }
  197. {
  198. pb_istream_t s;
  199. float d;
  200. COMMENT("Test pb_dec_fixed using float (failures here may be caused by imperfect rounding)")
  201. TEST((s = S("\x00\x00\x00\x00"), pb_decode_fixed32(&s, &d) && d == 0.0f))
  202. TEST((s = S("\x00\x00\xc6\x42"), pb_decode_fixed32(&s, &d) && d == 99.0f))
  203. TEST((s = S("\x4e\x61\x3c\xcb"), pb_decode_fixed32(&s, &d) && d == -12345678.0f))
  204. d = -12345678.0f;
  205. TEST((s = S("\x00"), !pb_decode_fixed32(&s, &d) && d == -12345678.0f))
  206. }
  207. if (sizeof(double) == 8)
  208. {
  209. pb_istream_t s;
  210. double d;
  211. COMMENT("Test pb_dec_fixed64 using double (failures here may be caused by imperfect rounding)")
  212. TEST((s = S("\x00\x00\x00\x00\x00\x00\x00\x00"), pb_decode_fixed64(&s, &d) && d == 0.0))
  213. TEST((s = S("\x00\x00\x00\x00\x00\xc0\x58\x40"), pb_decode_fixed64(&s, &d) && d == 99.0))
  214. TEST((s = S("\x00\x00\x00\xc0\x29\x8c\x67\xc1"), pb_decode_fixed64(&s, &d) && d == -12345678.0f))
  215. }
  216. {
  217. pb_istream_t s;
  218. struct { pb_size_t size; uint8_t bytes[5]; } d;
  219. pb_field_iter_t f;
  220. f.type = PB_LTYPE_BYTES;
  221. f.data_size = sizeof(d);
  222. f.pData = &d;
  223. COMMENT("Test pb_dec_bytes")
  224. TEST((s = S("\x00"), pb_dec_bytes(&s, &f) && d.size == 0))
  225. TEST((s = S("\x01\xFF"), pb_dec_bytes(&s, &f) && d.size == 1 && d.bytes[0] == 0xFF))
  226. TEST((s = S("\x05xxxxx"), pb_dec_bytes(&s, &f) && d.size == 5))
  227. TEST((s = S("\x05xxxx"), !pb_dec_bytes(&s, &f)))
  228. /* Note: the size limit on bytes-fields is not strictly obeyed, as
  229. * the compiler may add some padding to the struct. Using this padding
  230. * is not a very good thing to do, but it is difficult to avoid when
  231. * we use only a single uint8_t to store the size of the field.
  232. * Therefore this tests against a 10-byte string, while otherwise even
  233. * 6 bytes should error out.
  234. */
  235. TEST((s = S("\x10xxxxxxxxxx"), !pb_dec_bytes(&s, &f)))
  236. }
  237. {
  238. pb_istream_t s;
  239. pb_field_iter_t f;
  240. char d[5];
  241. f.type = PB_LTYPE_STRING;
  242. f.data_size = sizeof(d);
  243. f.pData = &d;
  244. COMMENT("Test pb_dec_string")
  245. TEST((s = S("\x00"), pb_dec_string(&s, &f) && d[0] == '\0'))
  246. TEST((s = S("\x04xyzz"), pb_dec_string(&s, &f) && strcmp(d, "xyzz") == 0))
  247. TEST((s = S("\x05xyzzy"), !pb_dec_string(&s, &f)))
  248. }
  249. {
  250. pb_istream_t s;
  251. IntegerArray dest;
  252. COMMENT("Testing pb_decode with repeated int32 field")
  253. TEST((s = S(""), pb_decode(&s, IntegerArray_fields, &dest) && dest.data_count == 0))
  254. TEST((s = S("\x08\x01\x08\x02"), pb_decode(&s, IntegerArray_fields, &dest)
  255. && dest.data_count == 2 && dest.data[0] == 1 && dest.data[1] == 2))
  256. s = S("\x08\x01\x08\x02\x08\x03\x08\x04\x08\x05\x08\x06\x08\x07\x08\x08\x08\x09\x08\x0A");
  257. TEST(pb_decode(&s, IntegerArray_fields, &dest) && dest.data_count == 10 && dest.data[9] == 10)
  258. s = S("\x08\x01\x08\x02\x08\x03\x08\x04\x08\x05\x08\x06\x08\x07\x08\x08\x08\x09\x08\x0A\x08\x0B");
  259. TEST(!pb_decode(&s, IntegerArray_fields, &dest))
  260. }
  261. {
  262. pb_istream_t s;
  263. IntegerArray dest;
  264. COMMENT("Testing pb_decode with packed int32 field")
  265. TEST((s = S("\x0A\x00"), pb_decode(&s, IntegerArray_fields, &dest)
  266. && dest.data_count == 0))
  267. TEST((s = S("\x0A\x01\x01"), pb_decode(&s, IntegerArray_fields, &dest)
  268. && dest.data_count == 1 && dest.data[0] == 1))
  269. TEST((s = S("\x0A\x0A\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A"), pb_decode(&s, IntegerArray_fields, &dest)
  270. && dest.data_count == 10 && dest.data[0] == 1 && dest.data[9] == 10))
  271. TEST((s = S("\x0A\x0B\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B"), !pb_decode(&s, IntegerArray_fields, &dest)))
  272. /* Test invalid wire data */
  273. TEST((s = S("\x0A\xFF"), !pb_decode(&s, IntegerArray_fields, &dest)))
  274. TEST((s = S("\x0A\x01"), !pb_decode(&s, IntegerArray_fields, &dest)))
  275. }
  276. {
  277. pb_istream_t s;
  278. IntegerArray dest;
  279. COMMENT("Testing pb_decode with unknown fields")
  280. TEST((s = S("\x18\x0F\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)
  281. && dest.data_count == 1 && dest.data[0] == 1))
  282. TEST((s = S("\x19\x00\x00\x00\x00\x00\x00\x00\x00\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)
  283. && dest.data_count == 1 && dest.data[0] == 1))
  284. TEST((s = S("\x1A\x00\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)
  285. && dest.data_count == 1 && dest.data[0] == 1))
  286. TEST((s = S("\x1B\x08\x01"), !pb_decode(&s, IntegerArray_fields, &dest)))
  287. TEST((s = S("\x1D\x00\x00\x00\x00\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)
  288. && dest.data_count == 1 && dest.data[0] == 1))
  289. }
  290. {
  291. pb_istream_t s;
  292. CallbackArray dest;
  293. struct { pb_size_t size; uint8_t bytes[10]; } ref;
  294. dest.data.funcs.decode = &callback_check;
  295. dest.data.arg = &ref;
  296. COMMENT("Testing pb_decode with callbacks")
  297. /* Single varint */
  298. ref.size = 1; ref.bytes[0] = 0x55;
  299. TEST((s = S("\x08\x55"), pb_decode(&s, CallbackArray_fields, &dest)))
  300. /* Packed varint */
  301. ref.size = 3; ref.bytes[0] = ref.bytes[1] = ref.bytes[2] = 0x55;
  302. TEST((s = S("\x0A\x03\x55\x55\x55"), pb_decode(&s, CallbackArray_fields, &dest)))
  303. /* Packed varint with loop */
  304. ref.size = 1; ref.bytes[0] = 0x55;
  305. TEST((s = S("\x0A\x03\x55\x55\x55"), pb_decode(&s, CallbackArray_fields, &dest)))
  306. /* Single fixed32 */
  307. ref.size = 4; ref.bytes[0] = ref.bytes[1] = ref.bytes[2] = ref.bytes[3] = 0xAA;
  308. TEST((s = S("\x0D\xAA\xAA\xAA\xAA"), pb_decode(&s, CallbackArray_fields, &dest)))
  309. /* Single fixed64 */
  310. ref.size = 8; memset(ref.bytes, 0xAA, 8);
  311. TEST((s = S("\x09\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"), pb_decode(&s, CallbackArray_fields, &dest)))
  312. /* Unsupported field type */
  313. TEST((s = S("\x0B\x00"), !pb_decode(&s, CallbackArray_fields, &dest)))
  314. /* Just make sure that our test function works */
  315. ref.size = 1; ref.bytes[0] = 0x56;
  316. TEST((s = S("\x08\x55"), !pb_decode(&s, CallbackArray_fields, &dest)))
  317. }
  318. {
  319. pb_istream_t s;
  320. IntegerArray dest;
  321. COMMENT("Testing pb_decode message termination")
  322. TEST((s = S(""), pb_decode(&s, IntegerArray_fields, &dest)))
  323. TEST((s = S("\x08\x01"), pb_decode(&s, IntegerArray_fields, &dest)))
  324. TEST((s = S("\x08"), !pb_decode(&s, IntegerArray_fields, &dest)))
  325. }
  326. {
  327. pb_istream_t s;
  328. IntegerArray dest;
  329. COMMENT("Testing pb_decode_ex null termination")
  330. TEST((s = S("\x00"), pb_decode_ex(&s, IntegerArray_fields, &dest, PB_DECODE_NULLTERMINATED)))
  331. TEST((s = S("\x08\x01\x00"), pb_decode_ex(&s, IntegerArray_fields, &dest, PB_DECODE_NULLTERMINATED)))
  332. }
  333. {
  334. pb_istream_t s;
  335. IntegerArray dest;
  336. COMMENT("Testing pb_decode with invalid tag numbers")
  337. TEST((s = S("\x9f\xea"), !pb_decode(&s, IntegerArray_fields, &dest)));
  338. TEST((s = S("\x00"), !pb_decode(&s, IntegerArray_fields, &dest)));
  339. }
  340. {
  341. pb_istream_t s;
  342. IntegerContainer dest = {{0}};
  343. COMMENT("Testing pb_decode_delimited")
  344. TEST((s = S("\x09\x0A\x07\x0A\x05\x01\x02\x03\x04\x05"),
  345. pb_decode_delimited(&s, IntegerContainer_fields, &dest)) &&
  346. dest.submsg.data_count == 5)
  347. }
  348. {
  349. pb_istream_t s = {0};
  350. void *data = NULL;
  351. COMMENT("Testing allocate_field")
  352. TEST(allocate_field(&s, &data, 10, 10) && data != NULL);
  353. TEST(allocate_field(&s, &data, 10, 20) && data != NULL);
  354. {
  355. void *oldvalue = data;
  356. size_t very_big = (size_t)-1;
  357. size_t somewhat_big = very_big / 2 + 1;
  358. size_t not_so_big = (size_t)1 << (4 * sizeof(size_t));
  359. TEST(!allocate_field(&s, &data, very_big, 2) && data == oldvalue);
  360. TEST(!allocate_field(&s, &data, somewhat_big, 2) && data == oldvalue);
  361. TEST(!allocate_field(&s, &data, not_so_big, not_so_big) && data == oldvalue);
  362. }
  363. pb_free(data);
  364. }
  365. if (status != 0)
  366. fprintf(stdout, "\n\nSome tests FAILED!\n");
  367. return status;
  368. }