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