1 /*
2 * Copyright (c) 2013-2016 MsgPuck Authors
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or
6 * without modification, are permitted provided that the following
7 * conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the
11 * following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
29 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 #include <assert.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <inttypes.h>
37 #include <limits.h>
38 #include <math.h>
39
40 #include "msgpuck.h"
41 #include "test.h"
42
43 #define BUF_MAXLEN ((1L << 18) - 1)
44 #define STRBIN_MAXLEN (BUF_MAXLEN - 10)
45
46 static char buf[BUF_MAXLEN + 1];
47 static char str[STRBIN_MAXLEN];
48 static char *data = buf + 1; /* use unaligned address to fail early */
49
50 #define header() note("*** %s ***", __func__)
51 #define footer() note("*** %s: done ***", __func__)
52
53 #define SCALAR(x) x
54 #define COMPLEX(x)
55
56 #define COMMA ,
57
58 #define DEFINE_TEST(_type, _complex, _ext, _v, _r, _rl) ({ \
59 _ext(int8_t ext_type = 0); \
60 const char *d1 = mp_encode_##_type(data, _ext(ext_type COMMA) (_v)); \
61 const char *d2 = data; \
62 _complex(const char *d3 = data); \
63 _complex(const char *d4 = data); \
64 note(""#_type" "#_v""); \
65 is(mp_check_##_type(data, d1), 0, "mp_check_"#_type"("#_v") == 0"); \
66 is(mp_decode_##_type(&d2 _ext(COMMA &ext_type)), (_v), "mp_decode(mp_encode("#_v")) == "#_v);\
67 _complex(mp_next(&d3)); \
68 _complex(ok(!mp_check(&d4, d3 + _rl), "mp_check("#_v")")); \
69 is((d1 - data), (_rl), "len(mp_encode_"#_type"("#_v")"); \
70 is(d1, d2, "len(mp_decode_"#_type"("#_v"))"); \
71 _complex(is(d1, d3, "len(mp_next_"#_type"("#_v"))")); \
72 _complex(is(d1, d4, "len(mp_check_"#_type"("#_v"))")); \
73 is(mp_sizeof_##_type(_v), _rl, "mp_sizeof_"#_type"("#_v")"); \
74 is(memcmp(data, (_r), (_rl)), 0, "mp_encode("#_v") == "#_r); \
75 })
76
77
78 #define DEFINE_TEST_STRBINEXT(_type, _not_ext, _ext, _vl) ({ \
79 note(""#_type" len="#_vl""); \
80 char *s1 = str; \
81 for (uint32_t i = 0; i < _vl; i++) { \
82 s1[i] = 'a' + i % 26; \
83 } \
84 _ext(int8_t ext_type = 0); \
85 const char *d1 = mp_encode_##_type(data, _ext(ext_type COMMA) s1, _vl);\
86 const char *d2; \
87 uint32_t len2; \
88 d2 = data; \
89 const char *s2 = mp_decode_##_type(&d2, _ext(&ext_type COMMA) &len2); \
90 is(_vl, len2, "len(mp_decode_"#_type"(x, %u))", _vl); \
91 _ext(is(ext_type, 0, "type(mp_decode_"#_type"(x))")); \
92 d2 = data; \
93 _not_ext((void) mp_decode_strbin(&d2, &len2)); \
94 _ext((void) mp_decode_ext(&d2, &ext_type, &len2)); \
95 is(_vl, len2, "len(mp_decode_strbin(x, %u))", _vl); \
96 const char *d3 = data; \
97 mp_next(&d3); \
98 const char *d4 = data; \
99 ok(!mp_check(&d4, d3 + _vl), \
100 "mp_check_"#_type"(mp_encode_"#_type"(x, "#_vl"))"); \
101 is(d1, d2, "len(mp_decode_"#_type"(x, "#_vl")"); \
102 is(d1, d3, "len(mp_next_"#_type"(x, "#_vl")"); \
103 is(d1, d4, "len(mp_check_"#_type"(x, "#_vl")"); \
104 is(mp_sizeof_##_type(_vl), (uint32_t) (d1 - data), \
105 "mp_sizeof_"#_type"("#_vl")"); \
106 is(memcmp(s1, s2, _vl), 0, "mp_encode_"#_type"(x, "#_vl") == x"); \
107 })
108
109 #define test_uint(...) DEFINE_TEST(uint, SCALAR, COMPLEX, __VA_ARGS__)
110 #define test_int(...) DEFINE_TEST(int, SCALAR, COMPLEX, __VA_ARGS__)
111 #define test_bool(...) DEFINE_TEST(bool, SCALAR, COMPLEX, __VA_ARGS__)
112 #define test_float(...) DEFINE_TEST(float, SCALAR, COMPLEX, __VA_ARGS__)
113 #define test_double(...) DEFINE_TEST(double, SCALAR, COMPLEX, __VA_ARGS__)
114 #define test_strl(...) DEFINE_TEST(strl, COMPLEX, COMPLEX, __VA_ARGS__)
115 #define test_binl(...) DEFINE_TEST(binl, COMPLEX, COMPLEX, __VA_ARGS__)
116 #define test_extl(...) DEFINE_TEST(extl, COMPLEX, SCALAR, __VA_ARGS__)
117 #define test_array(...) DEFINE_TEST(array, COMPLEX, COMPLEX, __VA_ARGS__)
118 #define test_map(...) DEFINE_TEST(map, COMPLEX, COMPLEX, __VA_ARGS__)
119 #define test_str(...) DEFINE_TEST_STRBINEXT(str, SCALAR, COMPLEX, __VA_ARGS__)
120 #define test_bin(...) DEFINE_TEST_STRBINEXT(bin, SCALAR, COMPLEX, __VA_ARGS__)
121 #define test_ext(...) DEFINE_TEST_STRBINEXT(ext, COMPLEX, SCALAR, __VA_ARGS__)
122
123 static int
test_uints(void)124 test_uints(void)
125 {
126 plan(135);
127 header();
128
129 test_uint(0U, "\x00", 1);
130 test_uint(1U, "\x01", 1);
131 test_uint(0x7eU, "\x7e", 1);
132 test_uint(0x7fU, "\x7f", 1);
133
134 test_uint(0x80U, "\xcc\x80", 2);
135 test_uint(0xfeU, "\xcc\xfe", 2);
136 test_uint(0xffU, "\xcc\xff", 2);
137
138 test_uint(0xfffeU, "\xcd\xff\xfe", 3);
139 test_uint(0xffffU, "\xcd\xff\xff", 3);
140
141 test_uint(0x10000U, "\xce\x00\x01\x00\x00", 5);
142 test_uint(0xfffffffeU, "\xce\xff\xff\xff\xfe", 5);
143 test_uint(0xffffffffU, "\xce\xff\xff\xff\xff", 5);
144
145 test_uint(0x100000000ULL,
146 "\xcf\x00\x00\x00\x01\x00\x00\x00\x00", 9);
147 test_uint(0xfffffffffffffffeULL,
148 "\xcf\xff\xff\xff\xff\xff\xff\xff\xfe", 9);
149 test_uint(0xffffffffffffffffULL,
150 "\xcf\xff\xff\xff\xff\xff\xff\xff\xff", 9);
151
152 footer();
153 return check_plan();
154 }
155
156 static int
test_ints(void)157 test_ints(void)
158 {
159 plan(153);
160 header();
161
162 test_int(-0x01, "\xff", 1);
163 test_int(-0x1e, "\xe2", 1);
164 test_int(-0x1f, "\xe1", 1);
165 test_int(-0x20, "\xe0", 1);
166 test_int(-0x21, "\xd0\xdf", 2);
167
168 test_int(-0x7f, "\xd0\x81", 2);
169 test_int(-0x80, "\xd0\x80", 2);
170
171 test_int(-0x81, "\xd1\xff\x7f", 3);
172 test_int(-0x7fff, "\xd1\x80\x01", 3);
173 test_int(-0x8000, "\xd1\x80\x00", 3);
174
175 test_int(-0x8001, "\xd2\xff\xff\x7f\xff", 5);
176 test_int(-0x7fffffff, "\xd2\x80\x00\x00\x01", 5);
177 test_int(-0x80000000LL, "\xd2\x80\x00\x00\x00", 5);
178
179 test_int(-0x80000001LL,
180 "\xd3\xff\xff\xff\xff\x7f\xff\xff\xff", 9);
181 test_int(-0x80000001LL,
182 "\xd3\xff\xff\xff\xff\x7f\xff\xff\xff", 9);
183 test_int(-0x7fffffffffffffffLL,
184 "\xd3\x80\x00\x00\x00\x00\x00\x00\x01", 9);
185 test_int((int64_t)-0x8000000000000000LL,
186 "\xd3\x80\x00\x00\x00\x00\x00\x00\x00", 9);
187
188 footer();
189 return check_plan();
190 }
191
192 static int
test_bools(void)193 test_bools(void)
194 {
195 plan(18);
196 header();
197
198 test_bool(true, "\xc3", 1);
199 test_bool(false, "\xc2", 1);
200
201 footer();
202 return check_plan();
203 }
204
205 static int
test_floats(void)206 test_floats(void)
207 {
208 plan(27);
209 header();
210
211 test_float((float) 1.0, "\xca\x3f\x80\x00\x00", 5);
212 test_float((float) 3.141593, "\xca\x40\x49\x0f\xdc", 5);
213 test_float((float) -1e38f, "\xca\xfe\x96\x76\x99", 5);
214
215 footer();
216 return check_plan();
217 }
218
219 static int
test_doubles(void)220 test_doubles(void)
221 {
222 plan(27);
223 header();
224
225 test_double((double) 1.0,
226 "\xcb\x3f\xf0\x00\x00\x00\x00\x00\x00", 9);
227 test_double((double) 3.141592653589793,
228 "\xcb\x40\x09\x21\xfb\x54\x44\x2d\x18", 9);
229 test_double((double) -1e99,
230 "\xcb\xd4\x7d\x42\xae\xa2\x87\x9f\x2e", 9);
231
232 footer();
233 return check_plan();
234 }
235
236 static int
test_nils(void)237 test_nils(void)
238 {
239 plan(6);
240 header();
241
242 const char *d1 = mp_encode_nil(data);
243 const char *d2 = data;
244 const char *d3 = data;
245 const char *d4 = data;
246 note("nil");
247 mp_decode_nil(&d2);
248 mp_next(&d3);
249 ok(!mp_check(&d4, d3 + 1), "mp_check_nil()");
250 is((d1 - data), 1, "len(mp_encode_nil() == 1");
251 is(d1, d2, "len(mp_decode_nil()) == 1");
252 is(d1, d3, "len(mp_next_nil()) == 1");
253 is(d1, d4, "len(mp_check_nil()) == 1");
254 is(mp_sizeof_nil(), 1, "mp_sizeof_nil() == 1");
255
256 footer();
257 return check_plan();
258 }
259
260 static int
test_arrays(void)261 test_arrays(void)
262 {
263 plan(54);
264 header();
265
266 test_array(0, "\x90", 1);
267 test_array(1, "\x91", 1);
268 test_array(15, "\x9f", 1);
269 test_array(16, "\xdc\x00\x10", 3);
270 test_array(0xfffe, "\xdc\xff\xfe", 3);
271 test_array(0xffff, "\xdc\xff\xff", 3);
272 test_array(0x10000, "\xdd\x00\x01\x00\x00", 5);
273 test_array(0xfffffffeU, "\xdd\xff\xff\xff\xfe", 5);
274 test_array(0xffffffffU, "\xdd\xff\xff\xff\xff", 5);
275
276 footer();
277 return check_plan();
278 }
279
280 static int
test_maps(void)281 test_maps(void)
282 {
283 plan(54);
284 header();
285
286 test_map(0, "\x80", 1);
287 test_map(1, "\x81", 1);
288 test_map(15, "\x8f", 1);
289 test_map(16, "\xde\x00\x10", 3);
290 test_map(0xfffe, "\xde\xff\xfe", 3);
291 test_map(0xffff, "\xde\xff\xff", 3);
292 test_map(0x10000, "\xdf\x00\x01\x00\x00", 5);
293 test_map(0xfffffffeU, "\xdf\xff\xff\xff\xfe", 5);
294 test_map(0xffffffffU, "\xdf\xff\xff\xff\xff", 5);
295
296 footer();
297 return check_plan();
298 }
299
300 static int
test_strls(void)301 test_strls(void)
302 {
303 plan(78);
304 header();
305
306 test_strl(0x00U, "\xa0", 1);
307 test_strl(0x01U, "\xa1", 1);
308 test_strl(0x1eU, "\xbe", 1);
309 test_strl(0x1fU, "\xbf", 1);
310
311 test_strl(0x20U, "\xd9\x20", 2);
312 test_strl(0xfeU, "\xd9\xfe", 2);
313 test_strl(0xffU, "\xd9\xff", 2);
314
315 test_strl(0x0100U, "\xda\x01\x00", 3);
316 test_strl(0xfffeU, "\xda\xff\xfe", 3);
317 test_strl(0xffffU, "\xda\xff\xff", 3);
318
319 test_strl(0x00010000U, "\xdb\x00\x01\x00\x00", 5);
320 test_strl(0xfffffffeU, "\xdb\xff\xff\xff\xfe", 5);
321 test_strl(0xffffffffU, "\xdb\xff\xff\xff\xff", 5);
322
323 footer();
324 return check_plan();
325 }
326
327 static int
test_binls(void)328 test_binls(void)
329 {
330 plan(78);
331 header();
332
333 test_binl(0x00U, "\xc4\x00", 2);
334 test_binl(0x01U, "\xc4\x01", 2);
335 test_binl(0x1eU, "\xc4\x1e", 2);
336 test_binl(0x1fU, "\xc4\x1f", 2);
337
338 test_binl(0x20U, "\xc4\x20", 2);
339 test_binl(0xfeU, "\xc4\xfe", 2);
340 test_binl(0xffU, "\xc4\xff", 2);
341
342 test_binl(0x0100U, "\xc5\x01\x00", 3);
343 test_binl(0xfffeU, "\xc5\xff\xfe", 3);
344 test_binl(0xffffU, "\xc5\xff\xff", 3);
345
346 test_binl(0x00010000U, "\xc6\x00\x01\x00\x00", 5);
347 test_binl(0xfffffffeU, "\xc6\xff\xff\xff\xfe", 5);
348 test_binl(0xffffffffU, "\xc6\xff\xff\xff\xff", 5);
349
350 footer();
351 return check_plan();
352 }
353
354 static int
test_extls(void)355 test_extls(void)
356 {
357 plan(168);
358 header();
359
360 /* fixext 1,2,4,8,16 */
361 test_extl(0x01U, "\xd4\x00", 2);
362 test_extl(0x02U, "\xd5\x00", 2);
363 test_extl(0x04U, "\xd6\x00", 2);
364 test_extl(0x08U, "\xd7\x00", 2);
365 test_extl(0x10U, "\xd8\x00", 2);
366
367 /* ext 8 */
368 test_extl(0x11U, "\xc7\x11\x00", 3);
369 test_extl(0xfeU, "\xc7\xfe\x00", 3);
370 test_extl(0xffU, "\xc7\xff\x00", 3);
371
372 test_extl(0x00U, "\xc7\x00\x00", 3);
373 test_extl(0x03U, "\xc7\x03\x00", 3);
374 test_extl(0x05U, "\xc7\x05\x00", 3);
375 test_extl(0x06U, "\xc7\x06\x00", 3);
376 test_extl(0x07U, "\xc7\x07\x00", 3);
377 test_extl(0x09U, "\xc7\x09\x00", 3);
378 test_extl(0x0aU, "\xc7\x0a\x00", 3);
379 test_extl(0x0bU, "\xc7\x0b\x00", 3);
380 test_extl(0x0cU, "\xc7\x0c\x00", 3);
381 test_extl(0x0dU, "\xc7\x0d\x00", 3);
382 test_extl(0x0eU, "\xc7\x0e\x00", 3);
383 test_extl(0x0fU, "\xc7\x0f\x00", 3);
384
385 /* ext 16 */
386 test_extl(0x0100U, "\xc8\x01\x00\x00", 4);
387 test_extl(0x0101U, "\xc8\x01\x01\x00", 4);
388 test_extl(0xfffeU, "\xc8\xff\xfe\x00", 4);
389 test_extl(0xffffU, "\xc8\xff\xff\x00", 4);
390
391 /* ext 32 */
392 test_extl(0x00010000U, "\xc9\x00\x01\x00\x00\x00", 6);
393 test_extl(0x00010001U, "\xc9\x00\x01\x00\x01\x00", 6);
394 test_extl(0xfffffffeU, "\xc9\xff\xff\xff\xfe\x00", 6);
395 test_extl(0xffffffffU, "\xc9\xff\xff\xff\xff\x00", 6);
396
397 footer();
398 return check_plan();
399 }
400
401 static int
test_strs(void)402 test_strs(void)
403 {
404 plan(96);
405 header();
406
407 test_str(0x01);
408 test_str(0x1e);
409 test_str(0x1f);
410 test_str(0x20);
411 test_str(0xfe);
412 test_str(0xff);
413 test_str(0x100);
414 test_str(0x101);
415 test_str(0xfffe);
416 test_str(0xffff);
417 test_str(0x10000);
418 test_str(0x10001);
419
420 footer();
421 return check_plan();
422 }
423
424 static int
test_bins(void)425 test_bins(void)
426 {
427 plan(96);
428 header();
429
430 test_bin(0x01);
431 test_bin(0x1e);
432 test_bin(0x1f);
433 test_bin(0x20);
434 test_bin(0xfe);
435 test_bin(0xff);
436 test_bin(0x100);
437 test_bin(0x101);
438 test_bin(0xfffe);
439 test_bin(0xffff);
440 test_bin(0x10000);
441 test_bin(0x10001);
442
443 footer();
444 return check_plan();
445 }
446
447 static int
test_exts(void)448 test_exts(void)
449 {
450 plan(225);
451 header();
452
453 test_ext(0x01);
454 test_ext(0x02);
455 test_ext(0x03);
456 test_ext(0x04);
457 test_ext(0x05);
458 test_ext(0x06);
459 test_ext(0x07);
460 test_ext(0x08);
461 test_ext(0x09);
462 test_ext(0x0a);
463 test_ext(0x0b);
464 test_ext(0x0c);
465 test_ext(0x0d);
466 test_ext(0x0e);
467 test_ext(0x0f);
468 test_ext(0x10);
469
470 test_ext(0x11);
471 test_ext(0xfe);
472 test_ext(0xff);
473
474 test_ext(0x0100);
475 test_ext(0x0101);
476 test_ext(0xfffe);
477 test_ext(0xffff);
478
479 test_ext(0x00010000);
480 test_ext(0x00010001);
481
482 footer();
483 return check_plan();
484 }
485
486 static void
test_next_on_array(uint32_t count)487 test_next_on_array(uint32_t count)
488 {
489 note("next/check on array(%u)", count);
490 char *d1 = data;
491 d1 = mp_encode_array(d1, count);
492 for (uint32_t i = 0; i < count; i++) {
493 d1 = mp_encode_uint(d1, i % 0x7f); /* one byte */
494 }
495 uint32_t len = count + mp_sizeof_array(count);
496 const char *d2 = data;
497 const char *d3 = data;
498 ok(!mp_check(&d2, data + BUF_MAXLEN), "mp_check(array %u))", count);
499 is((d1 - data), (ptrdiff_t)len, "len(array %u) == %u", count, len);
500 is((d2 - data), (ptrdiff_t)len, "len(mp_check(array %u)) == %u", count, len);
501 mp_next(&d3);
502 is((d3 - data), (ptrdiff_t)len, "len(mp_next(array %u)) == %u", count, len);
503 }
504
505 static int
test_next_on_arrays(void)506 test_next_on_arrays(void)
507 {
508 plan(52);
509 header();
510
511 test_next_on_array(0x00);
512 test_next_on_array(0x01);
513 test_next_on_array(0x0f);
514 test_next_on_array(0x10);
515 test_next_on_array(0x11);
516 test_next_on_array(0xfe);
517 test_next_on_array(0xff);
518 test_next_on_array(0x100);
519 test_next_on_array(0x101);
520 test_next_on_array(0xfffe);
521 test_next_on_array(0xffff);
522 test_next_on_array(0x10000);
523 test_next_on_array(0x10001);
524
525 footer();
526 return check_plan();
527 }
528
529 static void
test_next_on_map(uint32_t count)530 test_next_on_map(uint32_t count)
531 {
532 note("next/check on map(%u)", count);
533 char *d1 = data;
534 d1 = mp_encode_map(d1, count);
535 for (uint32_t i = 0; i < 2 * count; i++) {
536 d1 = mp_encode_uint(d1, i % 0x7f); /* one byte */
537 }
538 uint32_t len = 2 * count + mp_sizeof_map(count);
539 const char *d2 = data;
540 const char *d3 = data;
541 ok(!mp_check(&d2, data + BUF_MAXLEN), "mp_check(map %u))", count);
542 is((d1 - data), (ptrdiff_t)len, "len(map %u) == %u", count, len);
543 is((d2 - data), (ptrdiff_t)len, "len(mp_check(map %u)) == %u", count, len);
544 mp_next(&d3);
545 is((d3 - data), (ptrdiff_t)len, "len(mp_next(map %u)) == %u", count, len);
546 }
547
548 static int
test_next_on_maps(void)549 test_next_on_maps(void)
550 {
551 plan(52);
552 header();
553
554 test_next_on_map(0x00);
555 test_next_on_map(0x01);
556 test_next_on_map(0x0f);
557 test_next_on_map(0x10);
558 test_next_on_map(0x11);
559 test_next_on_map(0xfe);
560 test_next_on_map(0xff);
561 test_next_on_map(0x100);
562 test_next_on_map(0x101);
563 test_next_on_map(0xfffe);
564 test_next_on_map(0xffff);
565 test_next_on_map(0x10000);
566 test_next_on_map(0x10001);
567
568 footer();
569 return check_plan();
570 }
571
572 static void
test_compare_uint(uint64_t a,uint64_t b)573 test_compare_uint(uint64_t a, uint64_t b)
574 {
575 char bufa[9];
576 char bufb[9];
577 mp_encode_uint(bufa, a);
578 mp_encode_uint(bufb, b);
579 int r = mp_compare_uint(bufa, bufb);
580 if (a < b) {
581 ok(r < 0, "mp_compare_uint(%"PRIu64", %" PRIu64 ") < 0", a, b);
582 } else if (a > b) {
583 ok(r > 0, "mp_compare_uint(%"PRIu64", %" PRIu64") > 0", a, b);
584 } else {
585 ok(r == 0, "mp_compare_uint(%"PRIu64", %"PRIu64") == 0", a, b);
586 }
587 }
588
589 static int
test_compare_uints(void)590 test_compare_uints(void)
591 {
592 plan(227);
593 header();
594
595 test_compare_uint(0, 0);
596 test_compare_uint(0, 0);
597
598 uint64_t nums[] = {
599 0, 1, 0x7eU, 0x7fU, 0x80U, 0xfeU, 0xffU, 0xfffeU, 0xffffU,
600 0x10000U, 0xfffffffeU, 0xffffffffU, 0x100000000ULL,
601 0xfffffffffffffffeULL, 0xffffffffffffffffULL
602 };
603
604 int count = sizeof(nums) / sizeof(*nums);
605 for (int i = 0; i < count; i++) {
606 for (int j = 0; j < count; j++) {
607 test_compare_uint(nums[i], nums[j]);
608 }
609 }
610
611 footer();
612 return check_plan();
613 }
614
615 static bool
fequal(float a,float b)616 fequal(float a, float b)
617 {
618 return a > b ? a - b < 1e-5f : b - a < 1e-5f;
619 }
620
621 static bool
dequal(double a,double b)622 dequal(double a, double b)
623 {
624 return a > b ? a - b < 1e-10 : b - a < 1e-10;
625 }
626
627 static int
test_format(void)628 test_format(void)
629 {
630 plan(282);
631 header();
632
633 const size_t buf_size = 1024;
634 char buf[buf_size];
635 size_t sz;
636 const char *fmt;
637 const char *p, *c, *e;
638 uint32_t len = 0;
639
640 fmt = "%d %u %i %ld %lu %li %lld %llu %lli"
641 "%hd %hu %hi %hhd %hhu %hhi";
642 sz = mp_format(buf, buf_size, fmt, 1, 2, 3,
643 (long)4, (long)5, (long)6,
644 (long long)7, (long long)8, (long long)9,
645 (short)10, (short)11, (short)12,
646 (char)13, (char)14, (char)15);
647 p = buf;
648 for (unsigned i = 0; i < 15; i++) {
649 ok(mp_typeof(*p) == MP_UINT, "Test type on step %d", i);
650 ok(mp_decode_uint(&p) == i + 1, "Test value on step %d", i);
651 }
652 sz = mp_format(buf, buf_size, fmt, -1, -2, -3,
653 (long)-4, (long)-5, (long)-6,
654 (long long)-7, (long long)-8, (long long)-9,
655 (short)-10, (unsigned short)-11, (short)-12,
656 (signed char)-13, (unsigned char)-14, (signed char)-15);
657 p = buf;
658 for (int i = 0; i < 15; i++) {
659 uint64_t expects[5] = { UINT_MAX - 1,
660 ULONG_MAX - 4,
661 ULLONG_MAX - 7,
662 USHRT_MAX - 10,
663 UCHAR_MAX - 13 };
664 if (i % 3 == 1) {
665 ok(mp_typeof(*p) == MP_UINT, "Test type on step %d", i);
666 ok(mp_decode_uint(&p) == expects[i / 3],
667 "Test value on step %d", i);
668 } else {
669 ok(mp_typeof(*p) == MP_INT, "Test type on step %d", i);
670 ok(mp_decode_int(&p) == - i - 1,
671 "Test value on step %d", i);
672 }
673 }
674
675 char data1[32];
676 char *data1_end = data1;
677 data1_end = mp_encode_array(data1_end, 2);
678 data1_end = mp_encode_str(data1_end, "ABC", 3);
679 data1_end = mp_encode_uint(data1_end, 11);
680 size_t data1_len = data1_end - data1;
681 assert(data1_len <= sizeof(data1));
682
683 char data2[32];
684 char *data2_end = data2;
685 data2_end = mp_encode_int(data2_end, -1234567890);
686 data2_end = mp_encode_str(data2_end, "DEFGHIJKLMN", 11);
687 data2_end = mp_encode_uint(data2_end, 321);
688 size_t data2_len = data2_end - data2;
689 assert(data2_len <= sizeof(data2));
690
691 fmt = "%d NIL [%d %b %b] this is test"
692 "[%d %%%% [[ %d {%s %f %% %.*s %lf %.*s NIL}"
693 "%p %d %.*p ]] %d%d%d]";
694 #define TEST_PARAMS 0, 1, true, false, -1, 2, \
695 "flt", 0.1, 6, "double#ignored", 0.2, 0, "ignore", \
696 data1, 3, data2_len, data2, 4, 5, 6
697 sz = mp_format(buf, buf_size, fmt, TEST_PARAMS);
698 p = buf;
699 e = buf + sz;
700
701 c = p;
702 ok(mp_check(&c, e) == 0, "check");
703 ok(mp_typeof(*p) == MP_UINT, "type");
704 ok(mp_decode_uint(&p) == 0, "decode");
705
706 c = p;
707 ok(mp_check(&c, e) == 0, "check");
708 ok(mp_typeof(*p) == MP_NIL, "type");
709 mp_decode_nil(&p);
710
711 c = p;
712 ok(mp_check(&c, e) == 0, "check");
713 ok(mp_typeof(*p) == MP_ARRAY, "type");
714 ok(mp_decode_array(&p) == 3, "decode");
715
716 c = p;
717 ok(mp_check(&c, e) == 0, "check");
718 ok(mp_typeof(*p) == MP_UINT, "type");
719 ok(mp_decode_uint(&p) == 1, "decode");
720
721 c = p;
722 ok(mp_check(&c, e) == 0, "check");
723 ok(mp_typeof(*p) == MP_BOOL, "type");
724 ok(mp_decode_bool(&p) == true, "decode");
725
726 c = p;
727 ok(mp_check(&c, e) == 0, "check");
728 ok(mp_typeof(*p) == MP_BOOL, "type");
729 ok(mp_decode_bool(&p) == false, "decode");
730
731 c = p;
732 ok(mp_check(&c, e) == 0, "check");
733 ok(mp_typeof(*p) == MP_ARRAY, "type");
734 ok(mp_decode_array(&p) == 5, "decode");
735
736 c = p;
737 ok(mp_check(&c, e) == 0, "check");
738 ok(mp_typeof(*p) == MP_INT, "type");
739 ok(mp_decode_int(&p) == -1, "decode");
740
741 c = p;
742 ok(mp_check(&c, e) == 0, "check");
743 ok(mp_typeof(*p) == MP_ARRAY, "type");
744 ok(mp_decode_array(&p) == 1, "decode");
745
746 c = p;
747 ok(mp_check(&c, e) == 0, "check");
748 ok(mp_typeof(*p) == MP_ARRAY, "type");
749 ok(mp_decode_array(&p) == 5, "decode");
750
751 c = p;
752 ok(mp_check(&c, e) == 0, "check");
753 ok(mp_typeof(*p) == MP_UINT, "type");
754 ok(mp_decode_uint(&p) == 2, "decode");
755
756 c = p;
757 ok(mp_check(&c, e) == 0, "check");
758 ok(mp_typeof(*p) == MP_MAP, "type");
759 ok(mp_decode_map(&p) == 3, "decode");
760
761 c = p;
762 ok(mp_check(&c, e) == 0, "check");
763 ok(mp_typeof(*p) == MP_STR, "type");
764 c = mp_decode_str(&p, &len);
765 ok(len == 3, "decode");
766 ok(memcmp(c, "flt", 3) == 0, "compare");
767
768 c = p;
769 ok(mp_check(&c, e) == 0, "check");
770 ok(mp_typeof(*p) == MP_FLOAT, "type");
771 ok(fequal(mp_decode_float(&p), 0.1), "decode");
772
773 c = p;
774 ok(mp_check(&c, e) == 0, "check");
775 ok(mp_typeof(*p) == MP_STR, "type");
776 c = mp_decode_str(&p, &len);
777 ok(len == 6, "decode");
778 ok(memcmp(c, "double", 6) == 0, "compare");
779
780 c = p;
781 ok(mp_check(&c, e) == 0, "check");
782 ok(mp_typeof(*p) == MP_DOUBLE, "type");
783 ok(dequal(mp_decode_double(&p), 0.2), "decode");
784
785 c = p;
786 ok(mp_check(&c, e) == 0, "check");
787 ok(mp_typeof(*p) == MP_STR, "type");
788 c = mp_decode_str(&p, &len);
789 ok(len == 0, "decode");
790
791 c = p;
792 ok(mp_check(&c, e) == 0, "check");
793 ok(mp_typeof(*p) == MP_NIL, "type");
794 mp_decode_nil(&p);
795
796 c = p;
797 ok(mp_check(&c, e) == 0, "check");
798 ok(((size_t)(c - p) == data1_len) &&
799 memcmp(p, data1, data1_len) == 0, "compare");
800 p = c;
801
802 c = p;
803 ok(mp_check(&c, e) == 0, "check");
804 ok(mp_typeof(*p) == MP_UINT, "type");
805 ok(mp_decode_uint(&p) == 3, "decode");
806
807 c = p;
808 ok(mp_check(&c, e) == 0, "check");
809 ok(mp_typeof(*p) == MP_INT, "type");
810 ok(mp_decode_int(&p) == -1234567890, "decode");
811
812 c = p;
813 ok(mp_check(&c, e) == 0, "check");
814 ok(mp_typeof(*p) == MP_STR, "type");
815 c = mp_decode_str(&p, &len);
816 ok(len == 11, "decode");
817 ok(memcmp(c, "DEFGHIJKLMN", 11) == 0, "compare");
818
819 c = p;
820 ok(mp_check(&c, e) == 0, "check");
821 ok(mp_typeof(*p) == MP_UINT, "type");
822 ok(mp_decode_uint(&p) == 321, "decode");
823
824 c = p;
825 ok(mp_check(&c, e) == 0, "check");
826 ok(mp_typeof(*p) == MP_UINT, "type");
827 ok(mp_decode_uint(&p) == 4, "decode");
828
829 c = p;
830 ok(mp_check(&c, e) == 0, "check");
831 ok(mp_typeof(*p) == MP_UINT, "type");
832 ok(mp_decode_uint(&p) == 5, "decode");
833
834 c = p;
835 ok(mp_check(&c, e) == 0, "check");
836 ok(mp_typeof(*p) == MP_UINT, "type");
837 ok(mp_decode_uint(&p) == 6, "decode");
838
839 ok(p == e, "nothing more");
840
841 ok(sz < 70, "no magic detected");
842
843 for (size_t lim = 0; lim <= 70; lim++) {
844 memset(buf, 0, buf_size);
845 size_t test_sz = mp_format(buf, lim, fmt, TEST_PARAMS);
846 ok(test_sz == sz, "return value on step %d", (int)lim);
847 bool all_zero = true;
848 for(size_t z = lim; z < buf_size; z++)
849 all_zero = all_zero && (buf[z] == 0);
850 ok(all_zero, "buffer overflow on step %d", (int)lim);
851
852 }
853
854 #undef TEST_PARAMS
855
856 footer();
857 return check_plan();
858 }
859
860 int
test_mp_print()861 test_mp_print()
862 {
863 plan(12);
864 header();
865
866 char msgpack[128];
867 char *d = msgpack;
868 d = mp_encode_array(d, 8);
869 d = mp_encode_int(d, -5);
870 d = mp_encode_uint(d, 42);
871 d = mp_encode_str(d, "kill bill", 9);
872 d = mp_encode_array(d, 0);
873 d = mp_encode_map(d, 6);
874 d = mp_encode_str(d, "bool true", 9);
875 d = mp_encode_bool(d, true);
876 d = mp_encode_str(d, "bool false", 10);
877 d = mp_encode_bool(d, false);
878 d = mp_encode_str(d, "null", 4);
879 d = mp_encode_nil(d);
880 d = mp_encode_str(d, "float", 5);
881 d = mp_encode_float(d, 3.14);
882 d = mp_encode_str(d, "double", 6);
883 d = mp_encode_double(d, 3.14);
884 d = mp_encode_uint(d, 100);
885 d = mp_encode_uint(d, 500);
886 /* MP_EXT with type 123 and of size 3 bytes. */
887 d = mp_encode_extl(d, 123, 3);
888 memcpy(d, "str", 3);
889 d += 3;
890 char bin[] = "\x12test\x34\b\t\n\"bla\\-bla\"\f\r";
891 d = mp_encode_bin(d, bin, sizeof(bin));
892 d = mp_encode_map(d, 0);
893 assert(d <= msgpack + sizeof(msgpack));
894
895 const char *expected =
896 "[-5, 42, \"kill bill\", [], "
897 "{\"bool true\": true, \"bool false\": false, \"null\": null, "
898 "\"float\": 3.14, \"double\": 3.14, 100: 500}, "
899 "(extension: type 123, len 3), "
900 "\"\\u0012test4\\b\\t\\n\\\"bla\\\\-bla\\\"\\f\\r\\u0000\", {}]";
901 int esize = strlen(expected);
902
903 char result[256];
904
905 int fsize = mp_snprint(result, sizeof(result), msgpack);
906 ok(fsize == esize, "mp_snprint return value");
907 ok(strcmp(result, expected) == 0, "mp_snprint result");
908
909 fsize = mp_snprint(NULL, 0, msgpack);
910 ok(fsize == esize, "mp_snprint limit = 0");
911
912 fsize = mp_snprint(result, 1, msgpack);
913 ok(fsize == esize && result[0] == '\0', "mp_snprint limit = 1");
914
915 fsize = mp_snprint(result, 2, msgpack);
916 ok(fsize == esize && result[1] == '\0', "mp_snprint limit = 2");
917
918 fsize = mp_snprint(result, esize, msgpack);
919 ok(fsize == esize && result[esize - 1] == '\0',
920 "mp_snprint limit = expected");
921
922 fsize = mp_snprint(result, esize + 1, msgpack);
923 ok(fsize == esize && result[esize] == '\0',
924 "mp_snprint limit = expected + 1");
925
926 FILE *tmpf = tmpfile();
927 if (tmpf != NULL) {
928 int fsize = mp_fprint(tmpf, msgpack);
929 ok(fsize == esize, "mp_fprint return value");
930 (void) rewind(tmpf);
931 int rsize = fread(result, 1, sizeof(result), tmpf);
932 ok(rsize == esize && memcmp(result, expected, esize) == 0,
933 "mp_fprint result");
934 fclose(tmpf);
935 }
936
937 /* stdin is read-only */
938 int rc = mp_fprint(stdin, msgpack);
939 is(rc, -1, "mp_fprint I/O error");
940
941 /* Test mp_snprint max nesting depth. */
942 int mp_buff_sz = (MP_PRINT_MAX_DEPTH + 1) * mp_sizeof_array(1) +
943 mp_sizeof_uint(1);
944 int exp_str_sz = 2 * (MP_PRINT_MAX_DEPTH + 1) + 3 + 1;
945 char *mp_buff = malloc(mp_buff_sz);
946 char *exp_str = malloc(exp_str_sz);
947 char *decoded = malloc(exp_str_sz);
948 char *buff_wptr = mp_buff;
949 char *exp_str_wptr = exp_str;
950 for (int i = 0; i <= 2 * (MP_PRINT_MAX_DEPTH + 1); i++) {
951 int exp_str_rest = exp_str_sz - (exp_str_wptr - exp_str);
952 assert(exp_str_rest > 0);
953 if (i < MP_PRINT_MAX_DEPTH + 1) {
954 buff_wptr = mp_encode_array(buff_wptr, 1);
955 rc = snprintf(exp_str_wptr, exp_str_rest, "[");
956 } else if (i == MP_PRINT_MAX_DEPTH + 1) {
957 buff_wptr = mp_encode_uint(buff_wptr, 1);
958 rc = snprintf(exp_str_wptr, exp_str_rest, "...");
959 } else {
960 rc = snprintf(exp_str_wptr, exp_str_rest, "]");
961 }
962 exp_str_wptr += rc;
963 }
964 assert(exp_str_wptr + 1 == exp_str + exp_str_sz);
965 rc = mp_snprint(decoded, exp_str_sz, mp_buff);
966 ok(rc == exp_str_sz - 1, "mp_snprint max nesting depth return value");
967 ok(strcmp(decoded, exp_str) == 0, "mp_snprint max nesting depth result");
968 free(decoded);
969 free(exp_str);
970 free(mp_buff);
971 footer();
972 return check_plan();
973 }
974
975 enum mp_ext_test_type {
976 MP_EXT_TEST_PLAIN,
977 MP_EXT_TEST_MSGPACK,
978 };
979
980 static int
mp_fprint_ext_test(FILE * file,const char ** data,int depth)981 mp_fprint_ext_test(FILE *file, const char **data, int depth)
982 {
983 int8_t type;
984 uint32_t len = mp_decode_extl(data, &type);
985 const char *ext = *data;
986 *data += len;
987 switch(type) {
988 case MP_EXT_TEST_PLAIN:
989 return fprintf(file, "%.*s", len, ext);
990 case MP_EXT_TEST_MSGPACK:
991 return mp_fprint_recursion(file, &ext, depth);
992 }
993 return fprintf(file, "undefined");
994 }
995
996 static int
mp_snprint_ext_test(char * buf,int size,const char ** data,int depth)997 mp_snprint_ext_test(char *buf, int size, const char **data, int depth)
998 {
999 int8_t type;
1000 uint32_t len = mp_decode_extl(data, &type);
1001 const char *ext = *data;
1002 *data += len;
1003 switch(type) {
1004 case MP_EXT_TEST_PLAIN:
1005 return snprintf(buf, size, "%.*s", len, ext);
1006 case MP_EXT_TEST_MSGPACK:
1007 return mp_snprint_recursion(buf, size, &ext, depth);
1008 }
1009 return snprintf(buf, size, "undefined");
1010 }
1011
1012 static int
test_mp_print_ext(void)1013 test_mp_print_ext(void)
1014 {
1015 plan(5);
1016 header();
1017 mp_snprint_ext = mp_snprint_ext_test;
1018 mp_fprint_ext = mp_fprint_ext_test;
1019
1020 char *pos = buf;
1021 const char *plain = "plain-str";
1022 size_t plain_len = strlen(plain);
1023 pos = mp_encode_array(pos, 4);
1024 pos = mp_encode_uint(pos, 100);
1025 pos = mp_encode_ext(pos, MP_EXT_TEST_PLAIN, plain, plain_len);
1026 pos = mp_encode_extl(pos, MP_EXT_TEST_MSGPACK,
1027 mp_sizeof_str(plain_len));
1028 pos = mp_encode_str(pos, plain, plain_len);
1029 pos = mp_encode_uint(pos, 200);
1030
1031 int size = mp_snprint(NULL, 0, buf);
1032 int real_size = mp_snprint(str, sizeof(str), buf);
1033 is(size, real_size, "mp_snrpint size match");
1034 const char *expected = "[100, plain-str, \"plain-str\", 200]";
1035 is(strcmp(str, expected), 0, "str is correct");
1036
1037 FILE *tmpf = tmpfile();
1038 if (tmpf == NULL)
1039 abort();
1040 real_size = mp_fprint(tmpf, buf);
1041 is(size, real_size, "mp_fprint size match");
1042 rewind(tmpf);
1043 real_size = (int) fread(str, 1, sizeof(str), tmpf);
1044 is(real_size, size, "mp_fprint written correct number of bytes");
1045 str[real_size] = 0;
1046 is(strcmp(str, expected), 0, "str is correct");
1047 fclose(tmpf);
1048
1049 mp_snprint_ext = mp_snprint_ext_default;
1050 mp_fprint_ext = mp_fprint_ext_default;
1051 footer();
1052 return check_plan();
1053 }
1054
1055 int
test_mp_check()1056 test_mp_check()
1057 {
1058 plan(65);
1059 header();
1060
1061 #define invalid(data, fmt, ...) ({ \
1062 const char *p = data; \
1063 isnt(mp_check(&p, p + sizeof(data) - 1), 0, fmt, ## __VA_ARGS__); \
1064 });
1065
1066 /* fixmap */
1067 invalid("\x81", "invalid fixmap 1");
1068 invalid("\x81\x01", "invalid fixmap 2");
1069 invalid("\x8f\x01", "invalid fixmap 3");
1070
1071 /* fixarray */
1072 invalid("\x91", "invalid fixarray 1");
1073 invalid("\x92\x01", "invalid fixarray 2");
1074 invalid("\x9f\x01", "invalid fixarray 3");
1075
1076 /* fixstr */
1077 invalid("\xa1", "invalid fixstr 1");
1078 invalid("\xa2\x00", "invalid fixstr 2");
1079 invalid("\xbf\x00", "invalid fixstr 3");
1080
1081 /* bin8 */
1082 invalid("\xc4", "invalid bin8 1");
1083 invalid("\xc4\x01", "invalid bin8 2");
1084
1085 /* bin16 */
1086 invalid("\xc5", "invalid bin16 1");
1087 invalid("\xc5\x00\x01", "invalid bin16 2");
1088
1089 /* bin32 */
1090 invalid("\xc6", "invalid bin32 1");
1091 invalid("\xc6\x00\x00\x00\x01", "invalid bin32 2");
1092
1093 /* ext8 */
1094 invalid("\xc7", "invalid ext8 1");
1095 invalid("\xc7\x00", "invalid ext8 2");
1096 invalid("\xc7\x01\xff", "invalid ext8 3");
1097 invalid("\xc7\x02\xff\x00", "invalid ext8 4");
1098
1099 /* ext16 */
1100 invalid("\xc8", "invalid ext16 1");
1101 invalid("\xc8\x00\x00", "invalid ext16 2");
1102 invalid("\xc8\x00\x01\xff", "invalid ext16 3");
1103 invalid("\xc8\x00\x02\xff\x00", "invalid ext16 4");
1104
1105 /* ext32 */
1106 invalid("\xc9", "invalid ext32 1");
1107 invalid("\xc9\x00\x00\x00\x00", "invalid ext32 2");
1108 invalid("\xc9\x00\x00\x00\x01\xff", "invalid ext32 3");
1109 invalid("\xc9\x00\x00\x00\x02\xff\x00", "invalid ext32 4");
1110
1111 /* float32 */
1112 invalid("\xca", "invalid float32 1");
1113 invalid("\xca\x00\x00\x00", "invalid float32 2");
1114
1115 /* float64 */
1116 invalid("\xcb", "invalid float64 1");
1117 invalid("\xcb\x00\x00\x00\x00\x00\x00\x00", "invalid float64 2");
1118
1119 /* uint8 */
1120 invalid("\xcc", "invalid uint8 1");
1121
1122 /* uint16 */
1123 invalid("\xcd\x00", "invalid uint16 1");
1124
1125 /* uint32 */
1126 invalid("\xce\x00\x00\x00", "invalid uint32 1");
1127
1128 /* uint64 */
1129 invalid("\xcf\x00\x00\x00\x00\x00\x00\x00", "invalid uint64 1");
1130
1131 /* int8 */
1132 invalid("\xd0", "invalid int8 1");
1133
1134 /* int16 */
1135 invalid("\xd1\x00", "invalid int16 1");
1136
1137 /* int32 */
1138 invalid("\xd2\x00\x00\x00", "invalid int32 1");
1139
1140 /* int64 */
1141 invalid("\xd3\x00\x00\x00\x00\x00\x00\x00", "invalid int64 1");
1142
1143 /* fixext8 */
1144 invalid("\xd4", "invalid fixext8 1");
1145 invalid("\xd4\x05", "invalid fixext8 2");
1146
1147 /* fixext16 */
1148 invalid("\xd5", "invalid fixext16 1");
1149 invalid("\xd5\x05\x05", "invalid fixext16 2");
1150
1151 /* fixext32 */
1152 invalid("\xd6", "invalid fixext32 1");
1153 invalid("\xd6\x00\x00\x05\x05", "invalid fixext32 2");
1154
1155 /* fixext64 */
1156 invalid("\xd7", "invalid fixext64 1");
1157 invalid("\xd7\x00\x00\x00\x00\x00\x00\x05\x05", "invalid fixext64 2");
1158
1159 /* fixext128 */
1160 invalid("\xd8", "invalid fixext128 1");
1161 invalid("\xd8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
1162 "\x00\x05\x05", "invalid fixext128 2");
1163
1164 /* str8 */
1165 invalid("\xd9", "invalid str8 1");
1166 invalid("\xd9\x01", "invalid str8 2");
1167
1168 /* str16 */
1169 invalid("\xda", "invalid str16 1");
1170 invalid("\xda\x00\x01", "invalid str16 2");
1171
1172 /* str32 */
1173 invalid("\xdb", "invalid str32 1");
1174 invalid("\xdb\x00\x00\x00\x01", "invalid str32 2");
1175
1176 /* array16 */
1177 invalid("\xdc", "invalid array16 1");
1178 invalid("\xdc\x00\x01", "invalid array16 2");
1179
1180 /* array32 */
1181 invalid("\xdd", "invalid array32 1");
1182 invalid("\xdd\x00\x00\x00\x01", "invalid array32 2");
1183
1184 /* map16 */
1185 invalid("\xde", "invalid map16 1");
1186 invalid("\xde\x00\x01", "invalid map16 2");
1187 invalid("\xde\x00\x01\x5", "invalid map16 2");
1188
1189 /* map32 */
1190 invalid("\xdf", "invalid map32 1");
1191 invalid("\xdf\x00\x00\x00\x01", "invalid map32 2");
1192 invalid("\xdf\x00\x00\x00\x01\x5", "invalid map32 3");
1193
1194 footer();
1195
1196 return check_plan();
1197 }
1198
1199 #define int_eq(a, b) (((a) - (b)) == 0)
1200 #define double_eq(a, b) (fabs((a) - (b)) < 1e-15)
1201
1202 #define test_read_number(_func, _eq, _type, _mp_type, _val, _success) do { \
1203 const char *s = #_func "(mp_encode_" #_mp_type "(" #_val "))"; \
1204 const char *d1 = data; \
1205 const char *d2 = mp_encode_##_mp_type(data, _val); \
1206 _type v; \
1207 int ret = _func(&d1, &v); \
1208 if (_success) { \
1209 is(ret, 0, "%s check success", s); \
1210 is(d1, d2, "%s check pos advanced", s); \
1211 ok(_eq(v, _val), "%s check result", s); \
1212 } else { \
1213 is(ret, -1, "%s check fail", s); \
1214 is(d1, data, "%s check pos unchanged", s); \
1215 } \
1216 } while (0)
1217
1218 #define test_read_int32(...) test_read_number(mp_read_int32, int_eq, int32_t, __VA_ARGS__)
1219 #define test_read_int64(...) test_read_number(mp_read_int64, int_eq, int64_t, __VA_ARGS__)
1220 #define test_read_double(...) test_read_number(mp_read_double, double_eq, double, __VA_ARGS__)
1221
1222 static int
test_numbers()1223 test_numbers()
1224 {
1225 plan(96);
1226 header();
1227
1228 test_read_int32(uint, 123, true);
1229 test_read_int32(uint, 12345, true);
1230 test_read_int32(uint, 2147483647, true);
1231 test_read_int32(uint, 2147483648, false);
1232 test_read_int32(int, -123, true);
1233 test_read_int32(int, -12345, true);
1234 test_read_int32(int, -2147483648, true);
1235 test_read_int32(int, -2147483649LL, false);
1236 test_read_int32(float, -1e2, false);
1237 test_read_int32(double, 1.2345, false);
1238 test_read_int32(map, 5, false);
1239
1240 test_read_int64(uint, 123, true);
1241 test_read_int64(uint, 12345, true);
1242 test_read_int64(uint, 123456789, true);
1243 test_read_int64(uint, 9223372036854775807ULL, true);
1244 test_read_int64(uint, 9223372036854775808ULL, false);
1245 test_read_int64(int, -123, true);
1246 test_read_int64(int, -12345, true);
1247 test_read_int64(int, -123456789, true);
1248 test_read_int64(int, -9223372036854775807LL, true);
1249 test_read_int64(float, 100, false);
1250 test_read_int64(double, -5.4321, false);
1251 test_read_int64(array, 10, false);
1252
1253 test_read_double(uint, 123, true);
1254 test_read_double(uint, 12345, true);
1255 test_read_double(uint, 123456789, true);
1256 test_read_double(uint, 1234567890000ULL, true);
1257 test_read_double(uint, 123456789123456789ULL, false);
1258 test_read_double(int, -123, true);
1259 test_read_double(int, -12345, true);
1260 test_read_double(int, -123456789, true);
1261 test_read_double(int, -1234567890000LL, true);
1262 test_read_double(int, -123456789123456789LL, false);
1263 test_read_double(float, 6.565e6, true);
1264 test_read_double(double, -5.555, true);
1265 test_read_double(strl, 100, false);
1266
1267 footer();
1268 return check_plan();
1269 }
1270
1271 static int
test_overflow()1272 test_overflow()
1273 {
1274 plan(4);
1275 header();
1276
1277 const char *chk;
1278 char *d;
1279 d = data;
1280 chk = data;
1281 d = mp_encode_array(d, 1);
1282 d = mp_encode_array(d, UINT32_MAX);
1283 is(mp_check(&chk, d), 1, "mp_check array overflow")
1284
1285 d = data;
1286 chk = data;
1287 d = mp_encode_array(d, 1);
1288 d = mp_encode_map(d, UINT32_MAX);
1289 is(mp_check(&chk, d), 1, "mp_check map overflow")
1290
1291 d = data;
1292 chk = data;
1293 d = mp_encode_array(d, 2);
1294 d = mp_encode_str(d, "", 0);
1295 d = mp_encode_strl(d, UINT32_MAX);
1296 is(mp_check(&chk, d), 1, "mp_check str overflow")
1297
1298 d = data;
1299 chk = data;
1300 d = mp_encode_array(d, 2);
1301 d = mp_encode_bin(d, "", 0);
1302 d = mp_encode_binl(d, UINT32_MAX);
1303 is(mp_check(&chk, d), 1, "mp_check bin overflow")
1304
1305 footer();
1306 return check_plan();
1307 }
1308
1309
main()1310 int main()
1311 {
1312 plan(23);
1313 test_uints();
1314 test_ints();
1315 test_bools();
1316 test_floats();
1317 test_doubles();
1318 test_nils();
1319 test_strls();
1320 test_binls();
1321 test_extls();
1322 test_strs();
1323 test_bins();
1324 test_exts();
1325 test_arrays();
1326 test_maps();
1327 test_next_on_arrays();
1328 test_next_on_maps();
1329 test_compare_uints();
1330 test_format();
1331 test_mp_print();
1332 test_mp_print_ext();
1333 test_mp_check();
1334 test_numbers();
1335 test_overflow();
1336
1337 return check_plan();
1338 }
1339