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