1 /*
2 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3 *
4 * libcbor is free software; you can redistribute it and/or modify
5 * it under the terms of the MIT license. See LICENSE for details.
6 */
7
8 // cbor_serialize_alloc
9 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
10 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
11
12 #include <math.h>
13 #include <setjmp.h>
14 #include <stdarg.h>
15 #include <stddef.h>
16 #include <stdint.h>
17 #include <string.h>
18
19 #include <cmocka.h>
20
21 #include "assertions.h"
22 #include "cbor.h"
23 #include "test_allocator.h"
24
25 unsigned char buffer[512];
26
test_serialize_uint8_embed(void ** _CBOR_UNUSED (_state))27 static void test_serialize_uint8_embed(void **_CBOR_UNUSED(_state)) {
28 cbor_item_t *item = cbor_new_int8();
29 cbor_set_uint8(item, 0);
30 assert_size_equal(1, cbor_serialize(item, buffer, 512));
31 assert_memory_equal(buffer, (unsigned char[]){0x00}, 1);
32 assert_size_equal(cbor_serialized_size(item), 1);
33 cbor_decref(&item);
34 }
35
test_serialize_uint8(void ** _CBOR_UNUSED (_state))36 static void test_serialize_uint8(void **_CBOR_UNUSED(_state)) {
37 cbor_item_t *item = cbor_new_int8();
38 cbor_set_uint8(item, 42);
39 assert_size_equal(2, cbor_serialize(item, buffer, 512));
40 assert_memory_equal(buffer, ((unsigned char[]){0x18, 0x2a}), 2);
41 assert_size_equal(cbor_serialized_size(item), 2);
42 cbor_decref(&item);
43 }
44
test_serialize_uint16(void ** _CBOR_UNUSED (_state))45 static void test_serialize_uint16(void **_CBOR_UNUSED(_state)) {
46 cbor_item_t *item = cbor_new_int16();
47 cbor_set_uint16(item, 1000);
48 assert_size_equal(3, cbor_serialize(item, buffer, 512));
49 assert_memory_equal(buffer, ((unsigned char[]){0x19, 0x03, 0xE8}), 3);
50 assert_size_equal(cbor_serialized_size(item), 3);
51 cbor_decref(&item);
52 }
53
test_serialize_uint32(void ** _CBOR_UNUSED (_state))54 static void test_serialize_uint32(void **_CBOR_UNUSED(_state)) {
55 cbor_item_t *item = cbor_new_int32();
56 cbor_set_uint32(item, 1000000);
57 assert_size_equal(5, cbor_serialize(item, buffer, 512));
58 assert_memory_equal(buffer, ((unsigned char[]){0x1A, 0x00, 0x0F, 0x42, 0x40}),
59 5);
60 assert_size_equal(cbor_serialized_size(item), 5);
61 cbor_decref(&item);
62 }
63
test_serialize_uint64(void ** _CBOR_UNUSED (_state))64 static void test_serialize_uint64(void **_CBOR_UNUSED(_state)) {
65 cbor_item_t *item = cbor_new_int64();
66 cbor_set_uint64(item, 1000000000000);
67 assert_size_equal(9, cbor_serialize(item, buffer, 512));
68 assert_memory_equal(
69 buffer,
70 ((unsigned char[]){0x1B, 0x00, 0x00, 0x00, 0xE8, 0xD4, 0xA5, 0x10, 0x00}),
71 9);
72 assert_size_equal(cbor_serialized_size(item), 9);
73 cbor_decref(&item);
74 }
75
test_serialize_negint8_embed(void ** _CBOR_UNUSED (_state))76 static void test_serialize_negint8_embed(void **_CBOR_UNUSED(_state)) {
77 cbor_item_t *item = cbor_new_int8();
78 cbor_set_uint8(item, 0);
79 cbor_mark_negint(item);
80 assert_size_equal(1, cbor_serialize(item, buffer, 512));
81 assert_memory_equal(buffer, (unsigned char[]){0x20}, 1);
82 assert_size_equal(cbor_serialized_size(item), 1);
83 cbor_decref(&item);
84 }
85
test_serialize_negint8(void ** _CBOR_UNUSED (_state))86 static void test_serialize_negint8(void **_CBOR_UNUSED(_state)) {
87 cbor_item_t *item = cbor_new_int8();
88 cbor_set_uint8(item, 42);
89 cbor_mark_negint(item);
90 assert_size_equal(2, cbor_serialize(item, buffer, 512));
91 assert_memory_equal(buffer, ((unsigned char[]){0x38, 0x2a}), 2);
92 assert_size_equal(cbor_serialized_size(item), 2);
93 cbor_decref(&item);
94 }
95
test_serialize_negint16(void ** _CBOR_UNUSED (_state))96 static void test_serialize_negint16(void **_CBOR_UNUSED(_state)) {
97 cbor_item_t *item = cbor_new_int16();
98 cbor_set_uint16(item, 1000);
99 cbor_mark_negint(item);
100 assert_size_equal(3, cbor_serialize(item, buffer, 512));
101 assert_memory_equal(buffer, ((unsigned char[]){0x39, 0x03, 0xE8}), 3);
102 assert_size_equal(cbor_serialized_size(item), 3);
103 cbor_decref(&item);
104 }
105
test_serialize_negint32(void ** _CBOR_UNUSED (_state))106 static void test_serialize_negint32(void **_CBOR_UNUSED(_state)) {
107 cbor_item_t *item = cbor_new_int32();
108 cbor_set_uint32(item, 1000000);
109 cbor_mark_negint(item);
110 assert_size_equal(5, cbor_serialize(item, buffer, 512));
111 assert_memory_equal(buffer, ((unsigned char[]){0x3A, 0x00, 0x0F, 0x42, 0x40}),
112 5);
113 assert_size_equal(cbor_serialized_size(item), 5);
114 cbor_decref(&item);
115 }
116
test_serialize_negint64(void ** _CBOR_UNUSED (_state))117 static void test_serialize_negint64(void **_CBOR_UNUSED(_state)) {
118 cbor_item_t *item = cbor_new_int64();
119 cbor_set_uint64(item, 1000000000000);
120 cbor_mark_negint(item);
121 assert_size_equal(9, cbor_serialize(item, buffer, 512));
122 assert_memory_equal(
123 buffer,
124 ((unsigned char[]){0x3B, 0x00, 0x00, 0x00, 0xE8, 0xD4, 0xA5, 0x10, 0x00}),
125 9);
126 assert_size_equal(cbor_serialized_size(item), 9);
127 cbor_decref(&item);
128 }
129
test_serialize_definite_bytestring(void ** _CBOR_UNUSED (_state))130 static void test_serialize_definite_bytestring(void **_CBOR_UNUSED(_state)) {
131 cbor_item_t *item = cbor_new_definite_bytestring();
132 unsigned char *data = malloc(256);
133 cbor_bytestring_set_handle(item, data, 256);
134 memset(data, 0, 256); /* Prevent undefined behavior in comparison */
135 assert_size_equal(256 + 3, cbor_serialize(item, buffer, 512));
136 assert_memory_equal(buffer, ((unsigned char[]){0x59, 0x01, 0x00}), 3);
137 assert_memory_equal(buffer + 3, data, 256);
138 assert_size_equal(cbor_serialized_size(item), 259);
139 cbor_decref(&item);
140 }
141
test_serialize_indefinite_bytestring(void ** _CBOR_UNUSED (_state))142 static void test_serialize_indefinite_bytestring(void **_CBOR_UNUSED(_state)) {
143 cbor_item_t *item = cbor_new_indefinite_bytestring();
144
145 cbor_item_t *chunk = cbor_new_definite_bytestring();
146 unsigned char *data = malloc(256);
147 memset(data, 0, 256); /* Prevent undefined behavior in comparison */
148 cbor_bytestring_set_handle(chunk, data, 256);
149
150 assert_true(cbor_bytestring_add_chunk(item, cbor_move(chunk)));
151 assert_size_equal(cbor_bytestring_chunk_count(item), 1);
152
153 assert_size_equal(1 + 3 + 256 + 1, cbor_serialize(item, buffer, 512));
154 assert_memory_equal(buffer, ((unsigned char[]){0x5F, 0x59, 0x01, 0x00}), 4);
155 assert_memory_equal(buffer + 4, data, 256);
156 assert_memory_equal(buffer + 4 + 256, ((unsigned char[]){0xFF}), 1);
157 assert_size_equal(cbor_serialized_size(item), 261);
158 cbor_decref(&item);
159 }
160
test_serialize_bytestring_size_overflow(void ** _CBOR_UNUSED (_state))161 static void test_serialize_bytestring_size_overflow(
162 void **_CBOR_UNUSED(_state)) {
163 cbor_item_t *item = cbor_new_definite_bytestring();
164
165 // Fake having a huge chunk of data
166 unsigned char *data = malloc(1);
167 cbor_bytestring_set_handle(item, data, SIZE_MAX);
168
169 // Would require 1 + 8 + SIZE_MAX bytes, which overflows size_t
170 assert_size_equal(cbor_serialize(item, buffer, 512), 0);
171 assert_size_equal(cbor_serialized_size(item), 0);
172 cbor_decref(&item);
173 }
174
test_serialize_bytestring_no_space(void ** _CBOR_UNUSED (_state))175 static void test_serialize_bytestring_no_space(void **_CBOR_UNUSED(_state)) {
176 cbor_item_t *item = cbor_new_definite_bytestring();
177 unsigned char *data = malloc(12);
178 cbor_bytestring_set_handle(item, data, 12);
179
180 assert_size_equal(cbor_serialize(item, buffer, 1), 0);
181
182 cbor_decref(&item);
183 }
184
test_serialize_indefinite_bytestring_no_space(void ** _CBOR_UNUSED (_state))185 static void test_serialize_indefinite_bytestring_no_space(
186 void **_CBOR_UNUSED(_state)) {
187 cbor_item_t *item = cbor_new_indefinite_bytestring();
188 cbor_item_t *chunk = cbor_new_definite_bytestring();
189 unsigned char *data = malloc(256);
190 cbor_bytestring_set_handle(chunk, data, 256);
191 assert_true(cbor_bytestring_add_chunk(item, cbor_move(chunk)));
192
193 // Not enough space for the leading byte
194 assert_size_equal(cbor_serialize(item, buffer, 0), 0);
195
196 // Not enough space for the chunk
197 assert_size_equal(cbor_serialize(item, buffer, 30), 0);
198
199 // Not enough space for the indef break
200 assert_size_equal(
201 cbor_serialize(item, buffer, 1 + cbor_serialized_size(chunk)), 0);
202
203 cbor_decref(&item);
204 }
205
test_serialize_definite_string(void ** _CBOR_UNUSED (_state))206 static void test_serialize_definite_string(void **_CBOR_UNUSED(_state)) {
207 cbor_item_t *item = cbor_new_definite_string();
208 unsigned char *data = malloc(12);
209 strncpy((char *)data, "Hello world!", 12);
210 cbor_string_set_handle(item, data, 12);
211 assert_size_equal(1 + 12, cbor_serialize(item, buffer, 512));
212 assert_memory_equal(
213 buffer,
214 ((unsigned char[]){0x6C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F,
215 0x72, 0x6C, 0x64, 0x21}),
216 13);
217 assert_size_equal(cbor_serialized_size(item), 13);
218 cbor_decref(&item);
219 }
220
test_serialize_definite_string_4b_header(void ** _CBOR_UNUSED (_state))221 static void test_serialize_definite_string_4b_header(
222 void **_CBOR_UNUSED(_state)) {
223 #if SIZE_MAX > UINT16_MAX
224 cbor_item_t *item = cbor_new_definite_string();
225 const size_t size = (size_t)UINT16_MAX + 1;
226 unsigned char *data = malloc(size);
227 memset(data, 0, size);
228 cbor_string_set_handle(item, data, size);
229 assert_size_equal(cbor_serialized_size(item), 1 + 4 + size);
230 cbor_decref(&item);
231 #endif
232 }
233
test_serialize_definite_string_8b_header(void ** _CBOR_UNUSED (_state))234 static void test_serialize_definite_string_8b_header(
235 void **_CBOR_UNUSED(_state)) {
236 #if SIZE_MAX > UINT32_MAX
237 cbor_item_t *item = cbor_new_definite_string();
238 const size_t size = (size_t)UINT32_MAX + 1;
239 unsigned char *data = malloc(1);
240 data[0] = '\0';
241 cbor_string_set_handle(item, data, 1);
242 // Pretend that we have a big item to avoid the huge malloc
243 item->metadata.string_metadata.length = size;
244 assert_size_equal(cbor_serialized_size(item), 1 + 8 + size);
245 cbor_decref(&item);
246 #endif
247 }
248
test_serialize_indefinite_string(void ** _CBOR_UNUSED (_state))249 static void test_serialize_indefinite_string(void **_CBOR_UNUSED(_state)) {
250 cbor_item_t *item = cbor_new_indefinite_string();
251 cbor_item_t *chunk = cbor_new_definite_string();
252
253 unsigned char *data = malloc(12);
254 strncpy((char *)data, "Hello world!", 12);
255 cbor_string_set_handle(chunk, data, 12);
256
257 assert_true(cbor_string_add_chunk(item, cbor_move(chunk)));
258 assert_size_equal(cbor_string_chunk_count(item), 1);
259
260 assert_size_equal(15, cbor_serialize(item, buffer, 512));
261 assert_memory_equal(
262 buffer,
263 ((unsigned char[]){0x7F, 0x6C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77,
264 0x6F, 0x72, 0x6C, 0x64, 0x21, 0xFF}),
265 15);
266 assert_size_equal(cbor_serialized_size(item), 15);
267 cbor_decref(&item);
268 }
269
test_serialize_string_no_space(void ** _CBOR_UNUSED (_state))270 static void test_serialize_string_no_space(void **_CBOR_UNUSED(_state)) {
271 cbor_item_t *item = cbor_new_definite_string();
272 unsigned char *data = malloc(12);
273 memset(data, 0, 12);
274 cbor_string_set_handle(item, data, 12);
275
276 assert_size_equal(cbor_serialize(item, buffer, 1), 0);
277
278 cbor_decref(&item);
279 }
280
test_serialize_indefinite_string_no_space(void ** _CBOR_UNUSED (_state))281 static void test_serialize_indefinite_string_no_space(
282 void **_CBOR_UNUSED(_state)) {
283 cbor_item_t *item = cbor_new_indefinite_string();
284 cbor_item_t *chunk = cbor_new_definite_string();
285 unsigned char *data = malloc(256);
286 memset(data, 0, 256);
287 cbor_string_set_handle(chunk, data, 256);
288 assert_true(cbor_string_add_chunk(item, cbor_move(chunk)));
289
290 // Not enough space for the leading byte
291 assert_size_equal(cbor_serialize(item, buffer, 0), 0);
292
293 // Not enough space for the chunk
294 assert_size_equal(cbor_serialize(item, buffer, 30), 0);
295
296 // Not enough space for the indef break
297 assert_size_equal(
298 cbor_serialize(item, buffer, 1 + cbor_serialized_size(chunk)), 0);
299
300 cbor_decref(&item);
301 }
302
test_serialize_definite_array(void ** _CBOR_UNUSED (_state))303 static void test_serialize_definite_array(void **_CBOR_UNUSED(_state)) {
304 cbor_item_t *item = cbor_new_definite_array(2);
305 cbor_item_t *one = cbor_build_uint8(1);
306 cbor_item_t *two = cbor_build_uint8(2);
307
308 assert_true(cbor_array_push(item, one));
309 assert_true(cbor_array_set(item, 1, two));
310 assert_true(cbor_array_replace(item, 0, one));
311
312 assert_size_equal(3, cbor_serialize(item, buffer, 512));
313 assert_memory_equal(buffer, ((unsigned char[]){0x82, 0x01, 0x02}), 3);
314 assert_size_equal(cbor_serialized_size(item), 3);
315 cbor_decref(&item);
316 cbor_decref(&one);
317 cbor_decref(&two);
318 }
319
test_serialize_array_no_space(void ** _CBOR_UNUSED (_state))320 static void test_serialize_array_no_space(void **_CBOR_UNUSED(_state)) {
321 cbor_item_t *item = cbor_new_indefinite_array();
322 cbor_item_t *one = cbor_build_uint8(1);
323 assert_true(cbor_array_push(item, one));
324 assert_size_equal(cbor_serialized_size(item), 3);
325
326 // Not enough space for the leading byte
327 assert_size_equal(0, cbor_serialize(item, buffer, 0));
328
329 // Not enough space for the item
330 assert_size_equal(0, cbor_serialize(item, buffer, 1));
331
332 // Not enough space for the indef break
333 assert_size_equal(0, cbor_serialize(item, buffer, 2));
334
335 cbor_decref(&item);
336 cbor_decref(&one);
337 }
338
test_serialize_indefinite_array(void ** _CBOR_UNUSED (_state))339 static void test_serialize_indefinite_array(void **_CBOR_UNUSED(_state)) {
340 cbor_item_t *item = cbor_new_indefinite_array();
341 cbor_item_t *one = cbor_build_uint8(1);
342 cbor_item_t *two = cbor_build_uint8(2);
343
344 assert_true(cbor_array_push(item, one));
345 assert_true(cbor_array_push(item, two));
346
347 assert_size_equal(4, cbor_serialize(item, buffer, 512));
348 assert_memory_equal(buffer, ((unsigned char[]){0x9F, 0x01, 0x02, 0xFF}), 4);
349 assert_size_equal(cbor_serialized_size(item), 4);
350 cbor_decref(&item);
351 cbor_decref(&one);
352 cbor_decref(&two);
353 }
354
test_serialize_definite_map(void ** _CBOR_UNUSED (_state))355 static void test_serialize_definite_map(void **_CBOR_UNUSED(_state)) {
356 cbor_item_t *item = cbor_new_definite_map(2);
357 cbor_item_t *one = cbor_build_uint8(1);
358 cbor_item_t *two = cbor_build_uint8(2);
359
360 assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two}));
361 assert_true(cbor_map_add(item, (struct cbor_pair){.key = two, .value = one}));
362
363 assert_size_equal(5, cbor_serialize(item, buffer, 512));
364 assert_memory_equal(buffer, ((unsigned char[]){0xA2, 0x01, 0x02, 0x02, 0x01}),
365 5);
366 assert_size_equal(cbor_serialized_size(item), 5);
367 cbor_decref(&item);
368 cbor_decref(&one);
369 cbor_decref(&two);
370 }
371
test_serialize_indefinite_map(void ** _CBOR_UNUSED (_state))372 static void test_serialize_indefinite_map(void **_CBOR_UNUSED(_state)) {
373 cbor_item_t *item = cbor_new_indefinite_map();
374 cbor_item_t *one = cbor_build_uint8(1);
375 cbor_item_t *two = cbor_build_uint8(2);
376
377 assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two}));
378 assert_true(cbor_map_add(item, (struct cbor_pair){.key = two, .value = one}));
379
380 assert_size_equal(6, cbor_serialize(item, buffer, 512));
381 assert_memory_equal(
382 buffer, ((unsigned char[]){0xBF, 0x01, 0x02, 0x02, 0x01, 0xFF}), 6);
383 assert_size_equal(cbor_serialized_size(item), 6);
384 cbor_decref(&item);
385 cbor_decref(&one);
386 cbor_decref(&two);
387 }
388
test_serialize_map_no_space(void ** _CBOR_UNUSED (_state))389 static void test_serialize_map_no_space(void **_CBOR_UNUSED(_state)) {
390 cbor_item_t *item = cbor_new_indefinite_map();
391 cbor_item_t *one = cbor_build_uint8(1);
392 cbor_item_t *two = cbor_build_uint8(2);
393 assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two}));
394 assert_size_equal(cbor_serialized_size(item), 4);
395
396 // Not enough space for the leading byte
397 assert_size_equal(cbor_serialize(item, buffer, 0), 0);
398
399 // Not enough space for the key
400 assert_size_equal(cbor_serialize(item, buffer, 1), 0);
401
402 // Not enough space for the value
403 assert_size_equal(cbor_serialize(item, buffer, 2), 0);
404
405 // Not enough space for the indef break
406 assert_size_equal(cbor_serialize(item, buffer, 3), 0);
407
408 cbor_decref(&item);
409 cbor_decref(&one);
410 cbor_decref(&two);
411 }
412
test_serialize_tags(void ** _CBOR_UNUSED (_state))413 static void test_serialize_tags(void **_CBOR_UNUSED(_state)) {
414 cbor_item_t *item = cbor_new_tag(21);
415 cbor_item_t *one = cbor_build_uint8(1);
416 cbor_tag_set_item(item, one);
417
418 assert_size_equal(2, cbor_serialize(item, buffer, 512));
419 assert_memory_equal(buffer, ((unsigned char[]){0xD5, 0x01}), 2);
420 assert_size_equal(cbor_serialized_size(item), 2);
421 cbor_decref(&item);
422 cbor_decref(&one);
423 }
424
test_serialize_tags_no_space(void ** _CBOR_UNUSED (_state))425 static void test_serialize_tags_no_space(void **_CBOR_UNUSED(_state)) {
426 cbor_item_t *item = cbor_new_tag(21);
427 cbor_item_t *one = cbor_build_uint8(1);
428 cbor_tag_set_item(item, one);
429 assert_size_equal(cbor_serialized_size(item), 2);
430
431 // Not enough space for the leading byte
432 assert_size_equal(cbor_serialize(item, buffer, 0), 0);
433
434 // Not enough space for the item
435 assert_size_equal(cbor_serialize(item, buffer, 1), 0);
436
437 cbor_decref(&item);
438 cbor_decref(&one);
439 }
440
test_serialize_half(void ** _CBOR_UNUSED (_state))441 static void test_serialize_half(void **_CBOR_UNUSED(_state)) {
442 cbor_item_t *item = cbor_new_float2();
443 cbor_set_float2(item, NAN);
444
445 assert_size_equal(3, cbor_serialize(item, buffer, 512));
446 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x7E, 0x00}), 3);
447 assert_size_equal(cbor_serialized_size(item), 3);
448 cbor_decref(&item);
449 }
450
test_serialize_single(void ** _CBOR_UNUSED (_state))451 static void test_serialize_single(void **_CBOR_UNUSED(_state)) {
452 cbor_item_t *item = cbor_new_float4();
453 cbor_set_float4(item, 100000.0f);
454
455 assert_size_equal(5, cbor_serialize(item, buffer, 512));
456 assert_memory_equal(buffer, ((unsigned char[]){0xFA, 0x47, 0xC3, 0x50, 0x00}),
457 5);
458 assert_size_equal(cbor_serialized_size(item), 5);
459 cbor_decref(&item);
460 }
461
test_serialize_double(void ** _CBOR_UNUSED (_state))462 static void test_serialize_double(void **_CBOR_UNUSED(_state)) {
463 cbor_item_t *item = cbor_new_float8();
464 cbor_set_float8(item, -4.1);
465
466 assert_size_equal(9, cbor_serialize(item, buffer, 512));
467 assert_memory_equal(
468 buffer,
469 ((unsigned char[]){0xFB, 0xC0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}),
470 9);
471 assert_size_equal(cbor_serialized_size(item), 9);
472 cbor_decref(&item);
473 }
474
test_serialize_ctrl(void ** _CBOR_UNUSED (_state))475 static void test_serialize_ctrl(void **_CBOR_UNUSED(_state)) {
476 cbor_item_t *item = cbor_new_undef();
477
478 assert_size_equal(1, cbor_serialize(item, buffer, 512));
479 assert_memory_equal(buffer, ((unsigned char[]){0xF7}), 1);
480 assert_size_equal(cbor_serialized_size(item), 1);
481 cbor_decref(&item);
482 }
483
test_serialize_long_ctrl(void ** _CBOR_UNUSED (_state))484 static void test_serialize_long_ctrl(void **_CBOR_UNUSED(_state)) {
485 cbor_item_t *item = cbor_new_ctrl();
486 cbor_set_ctrl(item, 254);
487
488 assert_size_equal(2, cbor_serialize(item, buffer, 512));
489 assert_memory_equal(buffer, ((unsigned char[]){0xF8, 0xFE}), 2);
490 assert_size_equal(cbor_serialized_size(item), 2);
491 cbor_decref(&item);
492 }
493
test_auto_serialize(void ** _CBOR_UNUSED (_state))494 static void test_auto_serialize(void **_CBOR_UNUSED(_state)) {
495 cbor_item_t *item = cbor_new_definite_array(4);
496 for (size_t i = 0; i < 4; i++) {
497 assert_true(cbor_array_push(item, cbor_move(cbor_build_uint64(0))));
498 }
499
500 unsigned char *output;
501 size_t output_size;
502 assert_size_equal(cbor_serialize_alloc(item, &output, &output_size), 37);
503 assert_size_equal(output_size, 37);
504 assert_size_equal(cbor_serialized_size(item), 37);
505 assert_memory_equal(output, ((unsigned char[]){0x84, 0x1B}), 2);
506 cbor_decref(&item);
507 _cbor_free(output);
508 }
509
test_auto_serialize_no_size(void ** _CBOR_UNUSED (_state))510 static void test_auto_serialize_no_size(void **_CBOR_UNUSED(_state)) {
511 cbor_item_t *item = cbor_build_uint8(1);
512
513 unsigned char *output;
514 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
515 assert_memory_equal(output, ((unsigned char[]){0x01}), 1);
516 assert_size_equal(cbor_serialized_size(item), 1);
517 cbor_decref(&item);
518 _cbor_free(output);
519 }
520
test_auto_serialize_too_large(void ** _CBOR_UNUSED (_state))521 static void test_auto_serialize_too_large(void **_CBOR_UNUSED(_state)) {
522 cbor_item_t *item = cbor_new_indefinite_string();
523 cbor_item_t *chunk = cbor_new_definite_string();
524 assert_true(cbor_string_add_chunk(item, chunk));
525
526 // Pretend the chunk is huge
527 chunk->metadata.string_metadata.length = SIZE_MAX;
528 assert_true(SIZE_MAX + 2 == 1);
529 assert_size_equal(cbor_serialized_size(item), 0);
530 unsigned char *output;
531 size_t output_size;
532 assert_size_equal(cbor_serialize_alloc(item, &output, &output_size), 0);
533 assert_size_equal(output_size, 0);
534 assert_null(output);
535
536 chunk->metadata.string_metadata.length = 0;
537 cbor_decref(&chunk);
538 cbor_decref(&item);
539 }
540
test_auto_serialize_alloc_fail(void ** _CBOR_UNUSED (_state))541 static void test_auto_serialize_alloc_fail(void **_CBOR_UNUSED(_state)) {
542 cbor_item_t *item = cbor_build_uint8(42);
543
544 WITH_FAILING_MALLOC({
545 unsigned char *output;
546 size_t output_size;
547 assert_size_equal(cbor_serialize_alloc(item, &output, &output_size), 0);
548 assert_size_equal(output_size, 0);
549 assert_null(output);
550 });
551
552 cbor_decref(&item);
553 }
554
test_auto_serialize_zero_len_bytestring(void ** _CBOR_UNUSED (_state))555 static void test_auto_serialize_zero_len_bytestring(
556 void **_CBOR_UNUSED(_state)) {
557 cbor_item_t *item = cbor_build_bytestring((cbor_data) "", 0);
558
559 unsigned char *output;
560 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
561 assert_memory_equal(output, ((unsigned char[]){0x40}), 1);
562 assert_size_equal(cbor_serialized_size(item), 1);
563 cbor_decref(&item);
564 _cbor_free(output);
565 }
566
test_auto_serialize_zero_len_string(void ** _CBOR_UNUSED (_state))567 static void test_auto_serialize_zero_len_string(void **_CBOR_UNUSED(_state)) {
568 cbor_item_t *item = cbor_build_string("");
569
570 unsigned char *output;
571 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
572 assert_memory_equal(output, ((unsigned char[]){0x60}), 1);
573 assert_size_equal(cbor_serialized_size(item), 1);
574 cbor_decref(&item);
575 _cbor_free(output);
576 }
577
test_auto_serialize_zero_len_bytestring_chunk(void ** _CBOR_UNUSED (_state))578 static void test_auto_serialize_zero_len_bytestring_chunk(
579 void **_CBOR_UNUSED(_state)) {
580 cbor_item_t *item = cbor_new_indefinite_bytestring();
581
582 assert_true(cbor_bytestring_add_chunk(
583 item, cbor_move(cbor_build_bytestring((cbor_data) "", 0))));
584
585 unsigned char *output;
586 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 3);
587 assert_memory_equal(output, ((unsigned char[]){0x5f, 0x40, 0xff}), 3);
588 assert_size_equal(cbor_serialized_size(item), 3);
589 cbor_decref(&item);
590 _cbor_free(output);
591 }
592
test_auto_serialize_zero_len_string_chunk(void ** _CBOR_UNUSED (_state))593 static void test_auto_serialize_zero_len_string_chunk(
594 void **_CBOR_UNUSED(_state)) {
595 cbor_item_t *item = cbor_new_indefinite_string();
596
597 assert_true(cbor_string_add_chunk(item, cbor_move(cbor_build_string(""))));
598
599 unsigned char *output;
600 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 3);
601 assert_memory_equal(output, ((unsigned char[]){0x7f, 0x60, 0xff}), 3);
602 assert_size_equal(cbor_serialized_size(item), 3);
603 cbor_decref(&item);
604 _cbor_free(output);
605 }
606
test_auto_serialize_zero_len_array(void ** _CBOR_UNUSED (_state))607 static void test_auto_serialize_zero_len_array(void **_CBOR_UNUSED(_state)) {
608 cbor_item_t *item = cbor_new_definite_array(0);
609
610 unsigned char *output;
611 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
612 assert_memory_equal(output, ((unsigned char[]){0x80}), 1);
613 assert_size_equal(cbor_serialized_size(item), 1);
614 cbor_decref(&item);
615 _cbor_free(output);
616 }
617
test_auto_serialize_zero_len_indef_array(void ** _CBOR_UNUSED (_state))618 static void test_auto_serialize_zero_len_indef_array(
619 void **_CBOR_UNUSED(_state)) {
620 cbor_item_t *item = cbor_new_indefinite_array();
621
622 unsigned char *output;
623 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 2);
624 assert_memory_equal(output, ((unsigned char[]){0x9f, 0xff}), 2);
625 assert_size_equal(cbor_serialized_size(item), 2);
626 cbor_decref(&item);
627 _cbor_free(output);
628 }
629
test_auto_serialize_zero_len_map(void ** _CBOR_UNUSED (_state))630 static void test_auto_serialize_zero_len_map(void **_CBOR_UNUSED(_state)) {
631 cbor_item_t *item = cbor_new_definite_map(0);
632
633 unsigned char *output;
634 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
635 assert_memory_equal(output, ((unsigned char[]){0xa0}), 1);
636 assert_size_equal(cbor_serialized_size(item), 1);
637 cbor_decref(&item);
638 _cbor_free(output);
639 }
640
test_auto_serialize_zero_len_indef_map(void ** _CBOR_UNUSED (_state))641 static void test_auto_serialize_zero_len_indef_map(
642 void **_CBOR_UNUSED(_state)) {
643 cbor_item_t *item = cbor_new_indefinite_map();
644
645 unsigned char *output;
646 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 2);
647 assert_memory_equal(output, ((unsigned char[]){0xbf, 0xff}), 2);
648 assert_size_equal(cbor_serialized_size(item), 2);
649 cbor_decref(&item);
650 _cbor_free(output);
651 }
652
main(void)653 int main(void) {
654 const struct CMUnitTest tests[] = {
655 cmocka_unit_test(test_serialize_uint8_embed),
656 cmocka_unit_test(test_serialize_uint8),
657 cmocka_unit_test(test_serialize_uint16),
658 cmocka_unit_test(test_serialize_uint32),
659 cmocka_unit_test(test_serialize_uint64),
660 cmocka_unit_test(test_serialize_negint8_embed),
661 cmocka_unit_test(test_serialize_negint8),
662 cmocka_unit_test(test_serialize_negint16),
663 cmocka_unit_test(test_serialize_negint32),
664 cmocka_unit_test(test_serialize_negint64),
665 cmocka_unit_test(test_serialize_definite_bytestring),
666 cmocka_unit_test(test_serialize_indefinite_bytestring),
667 cmocka_unit_test(test_serialize_bytestring_size_overflow),
668 cmocka_unit_test(test_serialize_bytestring_no_space),
669 cmocka_unit_test(test_serialize_indefinite_bytestring_no_space),
670 cmocka_unit_test(test_serialize_definite_string),
671 cmocka_unit_test(test_serialize_definite_string_4b_header),
672 cmocka_unit_test(test_serialize_definite_string_8b_header),
673 cmocka_unit_test(test_serialize_indefinite_string),
674 cmocka_unit_test(test_serialize_string_no_space),
675 cmocka_unit_test(test_serialize_indefinite_string_no_space),
676 cmocka_unit_test(test_serialize_definite_array),
677 cmocka_unit_test(test_serialize_indefinite_array),
678 cmocka_unit_test(test_serialize_array_no_space),
679 cmocka_unit_test(test_serialize_definite_map),
680 cmocka_unit_test(test_serialize_indefinite_map),
681 cmocka_unit_test(test_serialize_map_no_space),
682 cmocka_unit_test(test_serialize_tags),
683 cmocka_unit_test(test_serialize_tags_no_space),
684 cmocka_unit_test(test_serialize_half),
685 cmocka_unit_test(test_serialize_single),
686 cmocka_unit_test(test_serialize_double),
687 cmocka_unit_test(test_serialize_ctrl),
688 cmocka_unit_test(test_serialize_long_ctrl),
689 cmocka_unit_test(test_auto_serialize),
690 cmocka_unit_test(test_auto_serialize_no_size),
691 cmocka_unit_test(test_auto_serialize_too_large),
692 cmocka_unit_test(test_auto_serialize_alloc_fail),
693 cmocka_unit_test(test_auto_serialize_zero_len_bytestring),
694 cmocka_unit_test(test_auto_serialize_zero_len_string),
695 cmocka_unit_test(test_auto_serialize_zero_len_bytestring_chunk),
696 cmocka_unit_test(test_auto_serialize_zero_len_string_chunk),
697 cmocka_unit_test(test_auto_serialize_zero_len_array),
698 cmocka_unit_test(test_auto_serialize_zero_len_indef_array),
699 cmocka_unit_test(test_auto_serialize_zero_len_map),
700 cmocka_unit_test(test_auto_serialize_zero_len_indef_map),
701 };
702 return cmocka_run_group_tests(tests, NULL, NULL);
703 }
704