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_indefinite_string(void ** _CBOR_UNUSED (_state))221 static void test_serialize_indefinite_string(void **_CBOR_UNUSED(_state)) {
222 cbor_item_t *item = cbor_new_indefinite_string();
223 cbor_item_t *chunk = cbor_new_definite_string();
224
225 unsigned char *data = malloc(12);
226 strncpy((char *)data, "Hello world!", 12);
227 cbor_string_set_handle(chunk, data, 12);
228
229 assert_true(cbor_string_add_chunk(item, cbor_move(chunk)));
230 assert_size_equal(cbor_string_chunk_count(item), 1);
231
232 assert_size_equal(15, cbor_serialize(item, buffer, 512));
233 assert_memory_equal(
234 buffer,
235 ((unsigned char[]){0x7F, 0x6C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77,
236 0x6F, 0x72, 0x6C, 0x64, 0x21, 0xFF}),
237 15);
238 assert_size_equal(cbor_serialized_size(item), 15);
239 cbor_decref(&item);
240 }
241
test_serialize_string_no_space(void ** _CBOR_UNUSED (_state))242 static void test_serialize_string_no_space(void **_CBOR_UNUSED(_state)) {
243 cbor_item_t *item = cbor_new_definite_string();
244 unsigned char *data = malloc(12);
245 cbor_string_set_handle(item, data, 12);
246
247 assert_size_equal(cbor_serialize(item, buffer, 1), 0);
248
249 cbor_decref(&item);
250 }
251
test_serialize_indefinite_string_no_space(void ** _CBOR_UNUSED (_state))252 static void test_serialize_indefinite_string_no_space(
253 void **_CBOR_UNUSED(_state)) {
254 cbor_item_t *item = cbor_new_indefinite_string();
255 cbor_item_t *chunk = cbor_new_definite_string();
256 unsigned char *data = malloc(256);
257 cbor_string_set_handle(chunk, data, 256);
258 assert_true(cbor_string_add_chunk(item, cbor_move(chunk)));
259
260 // Not enough space for the leading byte
261 assert_size_equal(cbor_serialize(item, buffer, 0), 0);
262
263 // Not enough space for the chunk
264 assert_size_equal(cbor_serialize(item, buffer, 30), 0);
265
266 // Not enough space for the indef break
267 assert_size_equal(
268 cbor_serialize(item, buffer, 1 + cbor_serialized_size(chunk)), 0);
269
270 cbor_decref(&item);
271 }
272
test_serialize_definite_array(void ** _CBOR_UNUSED (_state))273 static void test_serialize_definite_array(void **_CBOR_UNUSED(_state)) {
274 cbor_item_t *item = cbor_new_definite_array(2);
275 cbor_item_t *one = cbor_build_uint8(1);
276 cbor_item_t *two = cbor_build_uint8(2);
277
278 assert_true(cbor_array_push(item, one));
279 assert_true(cbor_array_set(item, 1, two));
280 assert_true(cbor_array_replace(item, 0, one));
281
282 assert_size_equal(3, cbor_serialize(item, buffer, 512));
283 assert_memory_equal(buffer, ((unsigned char[]){0x82, 0x01, 0x02}), 3);
284 assert_size_equal(cbor_serialized_size(item), 3);
285 cbor_decref(&item);
286 cbor_decref(&one);
287 cbor_decref(&two);
288 }
289
test_serialize_array_no_space(void ** _CBOR_UNUSED (_state))290 static void test_serialize_array_no_space(void **_CBOR_UNUSED(_state)) {
291 cbor_item_t *item = cbor_new_indefinite_array();
292 cbor_item_t *one = cbor_build_uint8(1);
293 assert_true(cbor_array_push(item, one));
294 assert_size_equal(cbor_serialized_size(item), 3);
295
296 // Not enough space for the leading byte
297 assert_size_equal(0, cbor_serialize(item, buffer, 0));
298
299 // Not enough space for the item
300 assert_size_equal(0, cbor_serialize(item, buffer, 1));
301
302 // Not enough space for the indef break
303 assert_size_equal(0, cbor_serialize(item, buffer, 2));
304
305 cbor_decref(&item);
306 cbor_decref(&one);
307 }
308
test_serialize_indefinite_array(void ** _CBOR_UNUSED (_state))309 static void test_serialize_indefinite_array(void **_CBOR_UNUSED(_state)) {
310 cbor_item_t *item = cbor_new_indefinite_array();
311 cbor_item_t *one = cbor_build_uint8(1);
312 cbor_item_t *two = cbor_build_uint8(2);
313
314 assert_true(cbor_array_push(item, one));
315 assert_true(cbor_array_push(item, two));
316
317 assert_size_equal(4, cbor_serialize(item, buffer, 512));
318 assert_memory_equal(buffer, ((unsigned char[]){0x9F, 0x01, 0x02, 0xFF}), 4);
319 assert_size_equal(cbor_serialized_size(item), 4);
320 cbor_decref(&item);
321 cbor_decref(&one);
322 cbor_decref(&two);
323 }
324
test_serialize_definite_map(void ** _CBOR_UNUSED (_state))325 static void test_serialize_definite_map(void **_CBOR_UNUSED(_state)) {
326 cbor_item_t *item = cbor_new_definite_map(2);
327 cbor_item_t *one = cbor_build_uint8(1);
328 cbor_item_t *two = cbor_build_uint8(2);
329
330 assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two}));
331 assert_true(cbor_map_add(item, (struct cbor_pair){.key = two, .value = one}));
332
333 assert_size_equal(5, cbor_serialize(item, buffer, 512));
334 assert_memory_equal(buffer, ((unsigned char[]){0xA2, 0x01, 0x02, 0x02, 0x01}),
335 5);
336 assert_size_equal(cbor_serialized_size(item), 5);
337 cbor_decref(&item);
338 cbor_decref(&one);
339 cbor_decref(&two);
340 }
341
test_serialize_indefinite_map(void ** _CBOR_UNUSED (_state))342 static void test_serialize_indefinite_map(void **_CBOR_UNUSED(_state)) {
343 cbor_item_t *item = cbor_new_indefinite_map();
344 cbor_item_t *one = cbor_build_uint8(1);
345 cbor_item_t *two = cbor_build_uint8(2);
346
347 assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two}));
348 assert_true(cbor_map_add(item, (struct cbor_pair){.key = two, .value = one}));
349
350 assert_size_equal(6, cbor_serialize(item, buffer, 512));
351 assert_memory_equal(
352 buffer, ((unsigned char[]){0xBF, 0x01, 0x02, 0x02, 0x01, 0xFF}), 6);
353 assert_size_equal(cbor_serialized_size(item), 6);
354 cbor_decref(&item);
355 cbor_decref(&one);
356 cbor_decref(&two);
357 }
358
test_serialize_map_no_space(void ** _CBOR_UNUSED (_state))359 static void test_serialize_map_no_space(void **_CBOR_UNUSED(_state)) {
360 cbor_item_t *item = cbor_new_indefinite_map();
361 cbor_item_t *one = cbor_build_uint8(1);
362 cbor_item_t *two = cbor_build_uint8(2);
363 assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two}));
364 assert_size_equal(cbor_serialized_size(item), 4);
365
366 // Not enough space for the leading byte
367 assert_size_equal(cbor_serialize(item, buffer, 0), 0);
368
369 // Not enough space for the key
370 assert_size_equal(cbor_serialize(item, buffer, 1), 0);
371
372 // Not enough space for the value
373 assert_size_equal(cbor_serialize(item, buffer, 2), 0);
374
375 // Not enough space for the indef break
376 assert_size_equal(cbor_serialize(item, buffer, 3), 0);
377
378 cbor_decref(&item);
379 cbor_decref(&one);
380 cbor_decref(&two);
381 }
382
test_serialize_tags(void ** _CBOR_UNUSED (_state))383 static void test_serialize_tags(void **_CBOR_UNUSED(_state)) {
384 cbor_item_t *item = cbor_new_tag(21);
385 cbor_item_t *one = cbor_build_uint8(1);
386 cbor_tag_set_item(item, one);
387
388 assert_size_equal(2, cbor_serialize(item, buffer, 512));
389 assert_memory_equal(buffer, ((unsigned char[]){0xD5, 0x01}), 2);
390 assert_size_equal(cbor_serialized_size(item), 2);
391 cbor_decref(&item);
392 cbor_decref(&one);
393 }
394
test_serialize_tags_no_space(void ** _CBOR_UNUSED (_state))395 static void test_serialize_tags_no_space(void **_CBOR_UNUSED(_state)) {
396 cbor_item_t *item = cbor_new_tag(21);
397 cbor_item_t *one = cbor_build_uint8(1);
398 cbor_tag_set_item(item, one);
399 assert_size_equal(cbor_serialized_size(item), 2);
400
401 // Not enough space for the leading byte
402 assert_size_equal(cbor_serialize(item, buffer, 0), 0);
403
404 // Not enough space for the item
405 assert_size_equal(cbor_serialize(item, buffer, 1), 0);
406
407 cbor_decref(&item);
408 cbor_decref(&one);
409 }
410
test_serialize_half(void ** _CBOR_UNUSED (_state))411 static void test_serialize_half(void **_CBOR_UNUSED(_state)) {
412 cbor_item_t *item = cbor_new_float2();
413 cbor_set_float2(item, NAN);
414
415 assert_size_equal(3, cbor_serialize(item, buffer, 512));
416 assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x7E, 0x00}), 3);
417 assert_size_equal(cbor_serialized_size(item), 3);
418 cbor_decref(&item);
419 }
420
test_serialize_single(void ** _CBOR_UNUSED (_state))421 static void test_serialize_single(void **_CBOR_UNUSED(_state)) {
422 cbor_item_t *item = cbor_new_float4();
423 cbor_set_float4(item, 100000.0f);
424
425 assert_size_equal(5, cbor_serialize(item, buffer, 512));
426 assert_memory_equal(buffer, ((unsigned char[]){0xFA, 0x47, 0xC3, 0x50, 0x00}),
427 5);
428 assert_size_equal(cbor_serialized_size(item), 5);
429 cbor_decref(&item);
430 }
431
test_serialize_double(void ** _CBOR_UNUSED (_state))432 static void test_serialize_double(void **_CBOR_UNUSED(_state)) {
433 cbor_item_t *item = cbor_new_float8();
434 cbor_set_float8(item, -4.1);
435
436 assert_size_equal(9, cbor_serialize(item, buffer, 512));
437 assert_memory_equal(
438 buffer,
439 ((unsigned char[]){0xFB, 0xC0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}),
440 9);
441 assert_size_equal(cbor_serialized_size(item), 9);
442 cbor_decref(&item);
443 }
444
test_serialize_ctrl(void ** _CBOR_UNUSED (_state))445 static void test_serialize_ctrl(void **_CBOR_UNUSED(_state)) {
446 cbor_item_t *item = cbor_new_undef();
447
448 assert_size_equal(1, cbor_serialize(item, buffer, 512));
449 assert_memory_equal(buffer, ((unsigned char[]){0xF7}), 1);
450 assert_size_equal(cbor_serialized_size(item), 1);
451 cbor_decref(&item);
452 }
453
test_serialize_long_ctrl(void ** _CBOR_UNUSED (_state))454 static void test_serialize_long_ctrl(void **_CBOR_UNUSED(_state)) {
455 cbor_item_t *item = cbor_new_ctrl();
456 cbor_set_ctrl(item, 254);
457
458 assert_size_equal(2, cbor_serialize(item, buffer, 512));
459 assert_memory_equal(buffer, ((unsigned char[]){0xF8, 0xFE}), 2);
460 assert_size_equal(cbor_serialized_size(item), 2);
461 cbor_decref(&item);
462 }
463
test_auto_serialize(void ** _CBOR_UNUSED (_state))464 static void test_auto_serialize(void **_CBOR_UNUSED(_state)) {
465 cbor_item_t *item = cbor_new_definite_array(4);
466 for (size_t i = 0; i < 4; i++) {
467 assert_true(cbor_array_push(item, cbor_move(cbor_build_uint64(0))));
468 }
469
470 unsigned char *output;
471 size_t output_size;
472 assert_size_equal(cbor_serialize_alloc(item, &output, &output_size), 37);
473 assert_size_equal(output_size, 37);
474 assert_size_equal(cbor_serialized_size(item), 37);
475 assert_memory_equal(output, ((unsigned char[]){0x84, 0x1B}), 2);
476 cbor_decref(&item);
477 _cbor_free(output);
478 }
479
test_auto_serialize_no_size(void ** _CBOR_UNUSED (_state))480 static void test_auto_serialize_no_size(void **_CBOR_UNUSED(_state)) {
481 cbor_item_t *item = cbor_build_uint8(1);
482
483 unsigned char *output;
484 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
485 assert_memory_equal(output, ((unsigned char[]){0x01}), 1);
486 assert_size_equal(cbor_serialized_size(item), 1);
487 cbor_decref(&item);
488 _cbor_free(output);
489 }
490
test_auto_serialize_too_large(void ** _CBOR_UNUSED (_state))491 static void test_auto_serialize_too_large(void **_CBOR_UNUSED(_state)) {
492 cbor_item_t *item = cbor_new_indefinite_string();
493 cbor_item_t *chunk = cbor_new_definite_string();
494 assert_true(cbor_string_add_chunk(item, chunk));
495
496 // Pretend the chunk is huge
497 chunk->metadata.string_metadata.length = SIZE_MAX;
498 assert_true(SIZE_MAX + 2 == 1);
499 assert_size_equal(cbor_serialized_size(item), 0);
500 unsigned char *output;
501 size_t output_size;
502 assert_size_equal(cbor_serialize_alloc(item, &output, &output_size), 0);
503 assert_size_equal(output_size, 0);
504 assert_null(output);
505
506 chunk->metadata.string_metadata.length = 0;
507 cbor_decref(&chunk);
508 cbor_decref(&item);
509 }
510
test_auto_serialize_alloc_fail(void ** _CBOR_UNUSED (_state))511 static void test_auto_serialize_alloc_fail(void **_CBOR_UNUSED(_state)) {
512 cbor_item_t *item = cbor_build_uint8(42);
513
514 WITH_FAILING_MALLOC({
515 unsigned char *output;
516 size_t output_size;
517 assert_size_equal(cbor_serialize_alloc(item, &output, &output_size), 0);
518 assert_size_equal(output_size, 0);
519 assert_null(output);
520 });
521
522 cbor_decref(&item);
523 }
524
test_auto_serialize_zero_len_bytestring(void ** _CBOR_UNUSED (_state))525 static void test_auto_serialize_zero_len_bytestring(
526 void **_CBOR_UNUSED(_state)) {
527 cbor_item_t *item = cbor_build_bytestring((cbor_data) "", 0);
528
529 unsigned char *output;
530 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
531 assert_memory_equal(output, ((unsigned char[]){0x40}), 1);
532 assert_size_equal(cbor_serialized_size(item), 1);
533 cbor_decref(&item);
534 _cbor_free(output);
535 }
536
test_auto_serialize_zero_len_string(void ** _CBOR_UNUSED (_state))537 static void test_auto_serialize_zero_len_string(void **_CBOR_UNUSED(_state)) {
538 cbor_item_t *item = cbor_build_string("");
539
540 unsigned char *output;
541 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
542 assert_memory_equal(output, ((unsigned char[]){0x60}), 1);
543 assert_size_equal(cbor_serialized_size(item), 1);
544 cbor_decref(&item);
545 _cbor_free(output);
546 }
547
test_auto_serialize_zero_len_bytestring_chunk(void ** _CBOR_UNUSED (_state))548 static void test_auto_serialize_zero_len_bytestring_chunk(
549 void **_CBOR_UNUSED(_state)) {
550 cbor_item_t *item = cbor_new_indefinite_bytestring();
551
552 assert_true(cbor_bytestring_add_chunk(
553 item, cbor_move(cbor_build_bytestring((cbor_data) "", 0))));
554
555 unsigned char *output;
556 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 3);
557 assert_memory_equal(output, ((unsigned char[]){0x5f, 0x40, 0xff}), 3);
558 assert_size_equal(cbor_serialized_size(item), 3);
559 cbor_decref(&item);
560 _cbor_free(output);
561 }
562
test_auto_serialize_zero_len_string_chunk(void ** _CBOR_UNUSED (_state))563 static void test_auto_serialize_zero_len_string_chunk(
564 void **_CBOR_UNUSED(_state)) {
565 cbor_item_t *item = cbor_new_indefinite_string();
566
567 assert_true(cbor_string_add_chunk(item, cbor_move(cbor_build_string(""))));
568
569 unsigned char *output;
570 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 3);
571 assert_memory_equal(output, ((unsigned char[]){0x7f, 0x60, 0xff}), 3);
572 assert_size_equal(cbor_serialized_size(item), 3);
573 cbor_decref(&item);
574 _cbor_free(output);
575 }
576
test_auto_serialize_zero_len_array(void ** _CBOR_UNUSED (_state))577 static void test_auto_serialize_zero_len_array(void **_CBOR_UNUSED(_state)) {
578 cbor_item_t *item = cbor_new_definite_array(0);
579
580 unsigned char *output;
581 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
582 assert_memory_equal(output, ((unsigned char[]){0x80}), 1);
583 assert_size_equal(cbor_serialized_size(item), 1);
584 cbor_decref(&item);
585 _cbor_free(output);
586 }
587
test_auto_serialize_zero_len_indef_array(void ** _CBOR_UNUSED (_state))588 static void test_auto_serialize_zero_len_indef_array(
589 void **_CBOR_UNUSED(_state)) {
590 cbor_item_t *item = cbor_new_indefinite_array();
591
592 unsigned char *output;
593 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 2);
594 assert_memory_equal(output, ((unsigned char[]){0x9f, 0xff}), 2);
595 assert_size_equal(cbor_serialized_size(item), 2);
596 cbor_decref(&item);
597 _cbor_free(output);
598 }
599
test_auto_serialize_zero_len_map(void ** _CBOR_UNUSED (_state))600 static void test_auto_serialize_zero_len_map(void **_CBOR_UNUSED(_state)) {
601 cbor_item_t *item = cbor_new_definite_map(0);
602
603 unsigned char *output;
604 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 1);
605 assert_memory_equal(output, ((unsigned char[]){0xa0}), 1);
606 assert_size_equal(cbor_serialized_size(item), 1);
607 cbor_decref(&item);
608 _cbor_free(output);
609 }
610
test_auto_serialize_zero_len_indef_map(void ** _CBOR_UNUSED (_state))611 static void test_auto_serialize_zero_len_indef_map(
612 void **_CBOR_UNUSED(_state)) {
613 cbor_item_t *item = cbor_new_indefinite_map();
614
615 unsigned char *output;
616 assert_size_equal(cbor_serialize_alloc(item, &output, NULL), 2);
617 assert_memory_equal(output, ((unsigned char[]){0xbf, 0xff}), 2);
618 assert_size_equal(cbor_serialized_size(item), 2);
619 cbor_decref(&item);
620 _cbor_free(output);
621 }
622
main(void)623 int main(void) {
624 const struct CMUnitTest tests[] = {
625 cmocka_unit_test(test_serialize_uint8_embed),
626 cmocka_unit_test(test_serialize_uint8),
627 cmocka_unit_test(test_serialize_uint16),
628 cmocka_unit_test(test_serialize_uint32),
629 cmocka_unit_test(test_serialize_uint64),
630 cmocka_unit_test(test_serialize_negint8_embed),
631 cmocka_unit_test(test_serialize_negint8),
632 cmocka_unit_test(test_serialize_negint16),
633 cmocka_unit_test(test_serialize_negint32),
634 cmocka_unit_test(test_serialize_negint64),
635 cmocka_unit_test(test_serialize_definite_bytestring),
636 cmocka_unit_test(test_serialize_indefinite_bytestring),
637 cmocka_unit_test(test_serialize_bytestring_size_overflow),
638 cmocka_unit_test(test_serialize_bytestring_no_space),
639 cmocka_unit_test(test_serialize_indefinite_bytestring_no_space),
640 cmocka_unit_test(test_serialize_definite_string),
641 cmocka_unit_test(test_serialize_indefinite_string),
642 cmocka_unit_test(test_serialize_string_no_space),
643 cmocka_unit_test(test_serialize_indefinite_string_no_space),
644 cmocka_unit_test(test_serialize_definite_array),
645 cmocka_unit_test(test_serialize_indefinite_array),
646 cmocka_unit_test(test_serialize_array_no_space),
647 cmocka_unit_test(test_serialize_definite_map),
648 cmocka_unit_test(test_serialize_indefinite_map),
649 cmocka_unit_test(test_serialize_map_no_space),
650 cmocka_unit_test(test_serialize_tags),
651 cmocka_unit_test(test_serialize_tags_no_space),
652 cmocka_unit_test(test_serialize_half),
653 cmocka_unit_test(test_serialize_single),
654 cmocka_unit_test(test_serialize_double),
655 cmocka_unit_test(test_serialize_ctrl),
656 cmocka_unit_test(test_serialize_long_ctrl),
657 cmocka_unit_test(test_auto_serialize),
658 cmocka_unit_test(test_auto_serialize_no_size),
659 cmocka_unit_test(test_auto_serialize_too_large),
660 cmocka_unit_test(test_auto_serialize_alloc_fail),
661 cmocka_unit_test(test_auto_serialize_zero_len_bytestring),
662 cmocka_unit_test(test_auto_serialize_zero_len_string),
663 cmocka_unit_test(test_auto_serialize_zero_len_bytestring_chunk),
664 cmocka_unit_test(test_auto_serialize_zero_len_string_chunk),
665 cmocka_unit_test(test_auto_serialize_zero_len_array),
666 cmocka_unit_test(test_auto_serialize_zero_len_indef_array),
667 cmocka_unit_test(test_auto_serialize_zero_len_map),
668 cmocka_unit_test(test_auto_serialize_zero_len_indef_map),
669 };
670 return cmocka_run_group_tests(tests, NULL, NULL);
671 }
672