xref: /src/contrib/libcbor/test/cbor_serialize_test.c (revision b5b9517bfe394e55088f5a05882eabae7e9b7b29)
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