blob: 9c25468a1ffef8d39f66c158899eb2a5d4481fba [file] [log] [blame]
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001/*==============================================================================
2Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28==============================================================================*/
29
Laurence Lundblade9e3651c2018-10-10 11:49:55 +080030/*==============================================================================
31 Modifications beyond the version released on CAF are under the MIT license:
32
33 Copyright 2018 Laurence Lundblade
34
35 Permission is hereby granted, free of charge, to any person obtaining
36 a copy of this software and associated documentation files (the
37 "Software"), to deal in the Software without restriction, including
38 without limitation the rights to use, copy, modify, merge, publish,
39 distribute, sublicense, and/or sell copies of the Software, and to
40 permit persons to whom the Software is furnished to do so, subject to
41 the following conditions:
42
43 The above copyright notice and this permission notice shall be included
44 in all copies or substantial portions of the Software.
45
46 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
47 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
48 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
49 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
50 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
51 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
52 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
53 SOFTWARE.
54 ==============================================================================*/
55
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080056#include "qcbor.h"
57#include "qcbor_decode_tests.h"
58#include <stdio.h>
59#include <strings.h>
Laurence Lundblade9e3651c2018-10-10 11:49:55 +080060#include <math.h> // for fabs()
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080061#include <stdlib.h>
62
63
64// TODO: test other than the normal decoder mode
65
66static void printencoded(const char *szLabel, const uint8_t *pEncoded, size_t nLen)
67{
68 if(szLabel) {
69 printf("%s ", szLabel);
70 }
71
Laurence Lundblade570fab52018-10-13 18:28:27 +080072 size_t i;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080073 for(i = 0; i < nLen; i++) {
74 uint8_t Z = pEncoded[i];
75 printf("%02x ", Z);
76 }
77 printf("\n");
78
79 fflush(stdout);
80}
81
82
83// TODO: -- add a test for counting the top level items and adding it back in with AddRaw()
84
85
86static const uint8_t pExpectedEncodedInts[] = {
87 0x98, 0x2f, 0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff,
88 0xff, 0xff, 0xff, 0x3b, 0x00, 0x00, 0x00, 0x01,
89 0x00, 0x00, 0x00, 0x00, 0x3a, 0xff, 0xff, 0xff,
90 0xff, 0x3a, 0xff, 0xff, 0xff, 0xfe, 0x3a, 0xff,
91 0xff, 0xff, 0xfd, 0x3a, 0x7f, 0xff, 0xff, 0xff,
92 0x3a, 0x7f, 0xff, 0xff, 0xfe, 0x3a, 0x00, 0x01,
93 0x00, 0x01, 0x3a, 0x00, 0x01, 0x00, 0x00, 0x39,
94 0xff, 0xff, 0x39, 0xff, 0xfe, 0x39, 0xff, 0xfd,
95 0x39, 0x01, 0x00, 0x38, 0xff, 0x38, 0xfe, 0x38,
96 0xfd, 0x38, 0x18, 0x37, 0x36, 0x20, 0x00, 0x00,
97 0x01, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19, 0x18,
98 0x1a, 0x18, 0xfe, 0x18, 0xff, 0x19, 0x01, 0x00,
99 0x19, 0x01, 0x01, 0x19, 0xff, 0xfe, 0x19, 0xff,
100 0xff, 0x1a, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x00,
101 0x01, 0x00, 0x01, 0x1a, 0x00, 0x01, 0x00, 0x02,
102 0x1a, 0x7f, 0xff, 0xff, 0xff, 0x1a, 0x7f, 0xff,
103 0xff, 0xff, 0x1a, 0x80, 0x00, 0x00, 0x00, 0x1a,
104 0x80, 0x00, 0x00, 0x01, 0x1a, 0xff, 0xff, 0xff,
105 0xfe, 0x1a, 0xff, 0xff, 0xff, 0xff, 0x1b, 0x00,
106 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
107 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
108 0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
109 0xff, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
110 0xff, 0xff};
111
112
113
114
115
116
117
118
119
120// return CBOR error or -1 if type of value doesn't match
121
122static int IntegerValuesParseTestInternal(QCBORDecodeContext *pDCtx)
123{
124 QCBORItem Item;
125 int nCBORError;
126
127 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
128 return nCBORError;
129 if(Item.uDataType != QCBOR_TYPE_ARRAY)
130 return -1;
131
132 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
133 return nCBORError;
134 if(Item.uDataType != QCBOR_TYPE_INT64 || // Todo; fix this for 32-bit machines
Laurence Lundblade570fab52018-10-13 18:28:27 +0800135 Item.val.int64 != -9223372036854775807LL - 1)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800136 return -1;
137
138 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
139 return nCBORError;
140 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundblade570fab52018-10-13 18:28:27 +0800141 Item.val.int64 != -4294967297)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800142 return -1;
143
144 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
145 return nCBORError;
146 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundblade570fab52018-10-13 18:28:27 +0800147 Item.val.int64 != -4294967296)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800148 return -1;
149
150 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
151 return nCBORError;
152 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundblade570fab52018-10-13 18:28:27 +0800153 Item.val.int64 != -4294967295)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800154 return -1;
155
156 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
157 return nCBORError;
158 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundblade570fab52018-10-13 18:28:27 +0800159 Item.val.int64 != -4294967294)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800160 return -1;
161
162
163 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
164 return nCBORError;
165 if(Item.uDataType != QCBOR_TYPE_INT64 ||
166 Item.val.int64 != -2147483648)
167 return -1;
168
169 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
170 return nCBORError;
171 if(Item.uDataType != QCBOR_TYPE_INT64 ||
172 Item.val.int64 != -2147483647)
173 return -1;
174
175 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
176 return nCBORError;
177 if(Item.uDataType != QCBOR_TYPE_INT64 ||
178 Item.val.int64 != -65538)
179 return -1;
180
181 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
182 return nCBORError;
183 if(Item.uDataType != QCBOR_TYPE_INT64 ||
184 Item.val.int64 != -65537)
185 return -1;
186
187 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
188 return nCBORError;
189 if(Item.uDataType != QCBOR_TYPE_INT64 ||
190 Item.val.int64 != -65536)
191 return -1;
192
193
194 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
195 return nCBORError;
196 if(Item.uDataType != QCBOR_TYPE_INT64 ||
197 Item.val.int64 != -65535)
198 return -1;
199
200
201 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
202 return nCBORError;
203 if(Item.uDataType != QCBOR_TYPE_INT64 ||
204 Item.val.int64 != -65534)
205 return -1;
206
207
208 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
209 return nCBORError;
210 if(Item.uDataType != QCBOR_TYPE_INT64 ||
211 Item.val.int64 != -257)
212 return -1;
213
214 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
215 return nCBORError;
216 if(Item.uDataType != QCBOR_TYPE_INT64 ||
217 Item.val.int64 != -256)
218 return -1;
219
220 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
221 return nCBORError;
222 if(Item.uDataType != QCBOR_TYPE_INT64 ||
223 Item.val.int64 != -255)
224 return -1;
225
226 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
227 return nCBORError;
228 if(Item.uDataType != QCBOR_TYPE_INT64 ||
229 Item.val.int64 != -254)
230 return -1;
231
232
233 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
234 return nCBORError;
235 if(Item.uDataType != QCBOR_TYPE_INT64 ||
236 Item.val.int64 != -25)
237 return -1;
238
239
240 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
241 return nCBORError;
242 if(Item.uDataType != QCBOR_TYPE_INT64 ||
243 Item.val.int64 != -24)
244 return -1;
245
246
247 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
248 return nCBORError;
249 if(Item.uDataType != QCBOR_TYPE_INT64 ||
250 Item.val.int64 != -23)
251 return -1;
252
253
254 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
255 return nCBORError;
256 if(Item.uDataType != QCBOR_TYPE_INT64 ||
257 Item.val.int64 != -1)
258 return -1;
259
260
261 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
262 return nCBORError;
263 if(Item.uDataType != QCBOR_TYPE_INT64 ||
264 Item.val.int64 != 0)
265 return -1;
266
267
268 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
269 return nCBORError;
270 if(Item.uDataType != QCBOR_TYPE_INT64 ||
271 Item.val.int64 != 0)
272 return -1;
273
274 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
275 return nCBORError;
276 if(Item.uDataType != QCBOR_TYPE_INT64 ||
277 Item.val.int64 != 1)
278 return -1;
279
280
281 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
282 return nCBORError;
283 if(Item.uDataType != QCBOR_TYPE_INT64 ||
284 Item.val.int64 != 22)
285 return -1;
286
287
288 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
289 return nCBORError;
290 if(Item.uDataType != QCBOR_TYPE_INT64 ||
291 Item.val.int64 != 23)
292 return -1;
293
294
295 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
296 return nCBORError;
297 if(Item.uDataType != QCBOR_TYPE_INT64 ||
298 Item.val.int64 != 24)
299 return -1;
300
301
302 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
303 return nCBORError;
304 if(Item.uDataType != QCBOR_TYPE_INT64 ||
305 Item.val.int64 != 25)
306 return -1;
307
308 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
309 return nCBORError;
310 if(Item.uDataType != QCBOR_TYPE_INT64 ||
311 Item.val.int64 != 26)
312 return -1;
313
314
315 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
316 return nCBORError;
317 if(Item.uDataType != QCBOR_TYPE_INT64 ||
318 Item.val.int64 != 254)
319 return -1;
320
321
322 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
323 return nCBORError;
324 if(Item.uDataType != QCBOR_TYPE_INT64 ||
325 Item.val.int64 != 255)
326 return -1;
327
328
329 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
330 return nCBORError;
331 if(Item.uDataType != QCBOR_TYPE_INT64 ||
332 Item.val.int64 != 256)
333 return -1;
334
335
336 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
337 return nCBORError;
338 if(Item.uDataType != QCBOR_TYPE_INT64 ||
339 Item.val.int64 != 257)
340 return -1;
341
342 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
343 return nCBORError;
344 if(Item.uDataType != QCBOR_TYPE_INT64 ||
345 Item.val.int64 != 65534)
346 return -1;
347
348
349 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
350 return nCBORError;
351 if(Item.uDataType != QCBOR_TYPE_INT64 ||
352 Item.val.int64 != 65535)
353 return -1;
354
355
356 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
357 return nCBORError;
358 if(Item.uDataType != QCBOR_TYPE_INT64 ||
359 Item.val.int64 != 65536)
360 return -1;
361
362 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
363 return nCBORError;
364 if(Item.uDataType != QCBOR_TYPE_INT64 ||
365 Item.val.int64 != 65537)
366 return -1;
367
368 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
369 return nCBORError;
370 if(Item.uDataType != QCBOR_TYPE_INT64 ||
371 Item.val.int64 != 65538)
372 return -1;
373
374 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
375 return nCBORError;
376 if(Item.uDataType != QCBOR_TYPE_INT64 ||
377 Item.val.int64 != 2147483647)
378 return -1;
379
380 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
381 return nCBORError;
382 if(Item.uDataType != QCBOR_TYPE_INT64 ||
383 Item.val.int64 != 2147483647)
384 return -1;
385
386 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
387 return nCBORError;
388 if(Item.uDataType != QCBOR_TYPE_INT64 ||
389 Item.val.int64 != 2147483648)
390 return -1;
391
392 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
393 return nCBORError;
394 if(Item.uDataType != QCBOR_TYPE_INT64 ||
395 Item.val.int64 != 2147483649)
396 return -1;
397
398 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
399 return nCBORError;
400 if(Item.uDataType != QCBOR_TYPE_INT64 ||
401 Item.val.int64 != 4294967294)
402 return -1;
403
404
405 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
406 return nCBORError;
407 if(Item.uDataType != QCBOR_TYPE_INT64 ||
408 Item.val.int64 != 4294967295)
409 return -1;
410
411
412 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
413 return nCBORError;
414 if(Item.uDataType != QCBOR_TYPE_INT64 ||
415 Item.val.int64 != 4294967296)
416 return -1;
417
418
419 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
420 return nCBORError;
421 if(Item.uDataType != QCBOR_TYPE_INT64 ||
422 Item.val.int64 != 4294967297)
423 return -1;
424
425
426
427 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
428 return nCBORError;
429 if(Item.uDataType != QCBOR_TYPE_INT64 ||
430 Item.val.int64 != 9223372036854775807LL)
431 return -1;
432
433
434 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
435 return nCBORError;
436 if(Item.uDataType != QCBOR_TYPE_UINT64 ||
437 Item.val.uint64 != 18446744073709551615ULL)
438 return -1;
439
440
441 if(QCBORDecode_Finish(pDCtx) != QCBOR_SUCCESS) {
442 return -1;
443 }
444
445 return 0;
446}
447
448
449/*
450 Tests the decoding of lots of different integers sizes
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800451 and values.
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800452 */
453
454int IntegerValuesParseTest()
455{
456 int n;
457 QCBORDecodeContext DCtx;
458
459 QCBORDecode_Init(&DCtx, (UsefulBufC){pExpectedEncodedInts, sizeof(pExpectedEncodedInts)}, QCBOR_DECODE_MODE_NORMAL);
460
461 n = IntegerValuesParseTestInternal(&DCtx);
462
463 return(n);
464}
465
466
467/*
468 Creates a simple CBOR array and returns it in *pEncoded. The array is malloced
469 and needs to be freed. This is used by several tests.
470
471 Two of the inputs can be set. Two other items in the array are fixed.
472
473 */
474
475static int CreateSimpleArray(int nInt1, int nInt2, uint8_t **pEncoded, size_t *pEncodedLen)
476{
477 QCBOREncodeContext ECtx;
478 int nReturn = -1;
479
480 *pEncoded = NULL;
481 *pEncodedLen = INT32_MAX;
482
483 // loop runs CBOR encoding twice. First with no buffer to
484 // calucate the length so buffer can be allocated correctly,
485 // and last with the buffer to do the actual encoding
486 do {
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800487 QCBOREncode_Init(&ECtx, (UsefulBuf){*pEncoded, *pEncodedLen});
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800488 QCBOREncode_OpenArray(&ECtx);
489 QCBOREncode_AddInt64(&ECtx, nInt1);
490 QCBOREncode_AddInt64(&ECtx, nInt2);
491 QCBOREncode_AddBytes(&ECtx, ((UsefulBufC) {"galactic", 8}));
492 QCBOREncode_AddBytes(&ECtx, ((UsefulBufC) {"haven token", 11}));
493 QCBOREncode_CloseArray(&ECtx);
494
495 if(QCBOREncode_Finish(&ECtx, pEncodedLen))
496 goto Done;
497
498 if(*pEncoded != NULL) {
499 nReturn = 0;
500 goto Done;
501 }
502 *pEncoded = malloc(*pEncodedLen);
503 if(*pEncoded == NULL) {
504 nReturn = -1;
505 goto Done;
506 }
507
508 } while(1);
509Done:
510 return (nReturn);
511
512}
513
514
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800515/*
516 {"first integer": 42,
517 "an array of two strings": ["string1", "string2"],
518 "map in a map": {
519 "bytes 1": h'78787878',
520 "bytes 2": h'79797979',
521 "another int": 98, "text 2":
522 "lies, damn lies and statistics"}
523 }
524 */
525
526static uint8_t pValidMapEncoded[] = {
527 0xa3, 0x6d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x18, 0x2a,
528 0x77, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x77, 0x6f, 0x20,
529 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x82, 0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x67,
530 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x6c, 0x6d, 0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20,
531 0x6d, 0x61, 0x70, 0xa4, 0x67, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x31, 0x44, 0x78, 0x78, 0x78, 0x78,
532 0x67, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x32, 0x44, 0x79, 0x79, 0x79, 0x79, 0x6b, 0x61, 0x6e, 0x6f,
533 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x74, 0x18, 0x62, 0x66, 0x74, 0x65, 0x78, 0x74, 0x20, 0x32,
534 0x78, 0x1e, 0x6c, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x64, 0x61, 0x6d, 0x6e, 0x20, 0x6c, 0x69, 0x65, 0x73,
535 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73 } ;
536
537
538
539
540
541
542
543static int ParseOrderedArray(const uint8_t *pEncoded, size_t nLen, int64_t *pInt1, int64_t *pInt2, const uint8_t **pBuf3, size_t *pBuf3Len, const uint8_t **pBuf4, size_t *pBuf4Len)
544{
545 QCBORDecodeContext DCtx;
546 QCBORItem Item;
547 int nReturn = -1; // assume error until success
548
549 QCBORDecode_Init(&DCtx, (UsefulBufC){pEncoded, nLen}, QCBOR_DECODE_MODE_NORMAL);
550
551 // Make sure the first thing is a map
552 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_ARRAY)
553 goto Done;
554
555 // First integer
556 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 | Item.uDataType != QCBOR_TYPE_INT64)
557 goto Done;
558 *pInt1 = Item.val.int64;
559
560 // Second integer
561 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_INT64)
562 goto Done;
563 *pInt2 = Item.val.int64;
564
565 // First string
566 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
567 goto Done;
568 *pBuf3 = Item.val.string.ptr;
569 *pBuf3Len = Item.val.string.len;
570
571 // Second string
572 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
573 goto Done;
574 *pBuf4 = Item.val.string.ptr;
575 *pBuf4Len = Item.val.string.len;
576
577 nReturn = 0;
578
579Done:
580 return(nReturn);
581}
582
583
584
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800585
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800586int SimpleArrayTest()
587{
588 uint8_t *pEncoded;
589 size_t nEncodedLen;
590
591 int64_t i1, i2;
592 size_t i3, i4;
593 const uint8_t *s3, *s4;
594
595
596 if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
597 return(-1);
598 }
599
600 ParseOrderedArray(pEncoded, nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
601
602 if(i1 != 23 ||
603 i2 != 6000 ||
604 i3 != 8 ||
605 i4 != 11 ||
Laurence Lundbladea44d5062018-10-17 18:45:12 +0530606 memcmp("galactic", s3, 8) !=0 ||
607 memcmp("haven token", s4, 11) !=0) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800608 printf("SimpleArraryTest Failed\n");
609 return(-1);
610 }
611
612 return(0);
613}
614
615
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800616
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800617static uint8_t s_pDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80};
618
619int ParseDeepArrayTest()
620{
621 QCBORDecodeContext DCtx;
622 int nReturn = 0;
623 int i;
624
625 QCBORDecode_Init(&DCtx, (UsefulBufC){s_pDeepArrays, sizeof(s_pDeepArrays)}, QCBOR_DECODE_MODE_NORMAL);
626
627 for(i = 0; i < 10; i++) {
628 QCBORItem Item;
629
630 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
631 Item.uDataType != QCBOR_TYPE_ARRAY ||
632 Item.uNestingLevel != i) {
633 nReturn = -1;
634 break;
635 }
636 }
637
638 return(nReturn);
639}
640
641
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800642static uint8_t s_pTooDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80};
643
644int ParseTooDeepArrayTest()
645{
646 QCBORDecodeContext DCtx;
647 int nReturn = 0;
648 int i;
649 QCBORItem Item;
650
651
652 QCBORDecode_Init(&DCtx, (UsefulBufC){s_pTooDeepArrays, sizeof(s_pTooDeepArrays)}, QCBOR_DECODE_MODE_NORMAL);
653
654 for(i = 0; i < 10; i++) {
655
656 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
657 Item.uDataType != QCBOR_TYPE_ARRAY ||
658 Item.uNestingLevel != i) {
659 nReturn = -1;
660 break;
661 }
662 }
663
664 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP)
665 nReturn = -1;
666
667 return(nReturn);
668}
669
670
671
672
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800673
674
675int ShortBufferParseTest()
676{
677 int nResult = 0;
678 QCBORDecodeContext DCtx;
679 int num;
680
681 for(num = sizeof(pExpectedEncodedInts)-1; num; num--) {
682 int n;
683
684 QCBORDecode_Init(&DCtx, (UsefulBufC){pExpectedEncodedInts, num}, QCBOR_DECODE_MODE_NORMAL);
685
686 n = IntegerValuesParseTestInternal(&DCtx);
687
688 //printf("Len %d, result: %d\n", num, n);
689
690 if(n != QCBOR_ERR_HIT_END) {
691 nResult = -1;
692 goto Done;
693 }
694 }
695Done:
696 return nResult;
697}
698
699
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800700
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800701int ShortBufferParseTest2()
702{
703 uint8_t *pEncoded;
704 int nReturn;
705 size_t nEncodedLen;
706
707 int64_t i1, i2;
708 size_t i3, i4;
709 const uint8_t *s3, *s4;
710
711 nReturn = 0;
712
713 if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
714 return(-1);
715 }
716
717 //printencoded(pEncoded, nEncodedLen);
718
719 for(nEncodedLen--; nEncodedLen; nEncodedLen--) {
720 int nResult = ParseOrderedArray(pEncoded, (uint32_t)nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
721 if(nResult == 0) {
722 nReturn = -1;
723 }
724 }
725
726 return(nReturn);
727}
728
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530729/*
730 Decode and thoroughly check a moderately complex
731 set of maps
732 */
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800733static int ParseMapTest1()
734{
735 QCBORDecodeContext DCtx;
736 QCBORItem Item;
737 int nCBORError;
738
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800739 QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
740
741 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
742 return nCBORError;
743 if(Item.uDataType != QCBOR_TYPE_MAP ||
744 Item.val.uCount != 3)
745 return -1;
746
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800747 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
748 return nCBORError;
749 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
750 Item.label.string.len != 13 ||
751 Item.uDataType != QCBOR_TYPE_INT64 ||
752 Item.val.int64 != 42 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530753 Item.uDataAlloc ||
754 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800755 memcmp(Item.label.string.ptr, "first integer", 13))
756 return -1;
757
758 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
759 return nCBORError;
760 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
761 Item.label.string.len != 23 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530762 Item.uDataAlloc ||
763 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800764 memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
765 Item.uDataType != QCBOR_TYPE_ARRAY ||
766 Item.val.uCount != 2)
767 return -1;
768
769 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
770 return nCBORError;
771 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
772 Item.val.string.len != 7 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530773 Item.uDataAlloc ||
774 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800775 memcmp(Item.val.string.ptr, "string1", 7))
776 return -1;
777
778 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
779 return nCBORError;
780 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
781 Item.val.string.len != 7 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530782 Item.uDataAlloc ||
783 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800784 memcmp(Item.val.string.ptr, "string2", 7))
785 return -1;
786
787 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
788 return nCBORError;
789 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
790 Item.label.string.len != 12 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530791 Item.uDataAlloc ||
792 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800793 memcmp(Item.label.string.ptr, "map in a map", 12) ||
794 Item.uDataType != QCBOR_TYPE_MAP ||
795 Item.val.uCount != 4)
796 return -1;
797
798 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
799 return nCBORError;
800 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
801 Item.label.string.len != 7 ||
802 memcmp(Item.label.string.ptr, "bytes 1", 7)||
803 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
804 Item.val.string.len != 4 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530805 Item.uDataAlloc ||
806 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800807 memcmp(Item.val.string.ptr, "xxxx", 4))
808 return -1;
809
810 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
811 return nCBORError;
812 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
813 Item.label.string.len != 7 ||
814 memcmp(Item.label.string.ptr, "bytes 2", 7) ||
815 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
816 Item.val.string.len != 4 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530817 Item.uDataAlloc ||
818 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800819 memcmp(Item.val.string.ptr, "yyyy", 4))
820 return -1;
821
822 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
823 return nCBORError;
824 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
825 Item.label.string.len != 11 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530826 Item.uDataAlloc ||
827 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800828 memcmp(Item.label.string.ptr, "another int", 11) ||
829 Item.uDataType != QCBOR_TYPE_INT64 ||
830 Item.val.int64 != 98)
831 return -1;
832
833 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
834 return nCBORError;
835 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
836 Item.label.string.len != 6 ||
837 memcmp(Item.label.string.ptr, "text 2", 6)||
838 Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
839 Item.val.string.len != 30 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530840 Item.uDataAlloc ||
841 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800842 memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
843 return -1;
844
845 return 0;
846}
847
848
849
850/*
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530851 Fully or partially decode pValidMapEncoded. When
852 partially decoding check for the right error code.
853 How much partial decoding depends on nLevel.
854
855 The partial decodes test error conditions of
856 incomplete encoded input.
857
858 This could be combined with the above test
859 and made prettier and maybe a little more
860 thorough.
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800861 */
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800862static int ExtraBytesTest(int nLevel)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800863{
864 QCBORDecodeContext DCtx;
865 QCBORItem Item;
866 int nCBORError;
867
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800868 QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
869
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800870 if(nLevel < 1) {
871 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
872 return -1;
873 } else {
874 return 0;
875 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800876 }
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530877
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800878
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800879 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
880 return nCBORError;
881 if(Item.uDataType != QCBOR_TYPE_MAP ||
882 Item.val.uCount != 3)
883 return -1;
884
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800885 if(nLevel < 2) {
886 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
887 return -1;
888 } else {
889 return 0;
890 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800891 }
892
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800893
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800894 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
895 return nCBORError;
896 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
897 Item.label.string.len != 13 ||
898 Item.uDataType != QCBOR_TYPE_INT64 ||
899 Item.val.uCount != 42 ||
900 memcmp(Item.label.string.ptr, "first integer", 13))
901 return -1;
902
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800903 if(nLevel < 3) {
904 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
905 return -1;
906 } else {
907 return 0;
908 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800909 }
910
911 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
912 return nCBORError;
913 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
914 Item.label.string.len != 23 ||
915 memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
916 Item.uDataType != QCBOR_TYPE_ARRAY ||
917 Item.val.uCount != 2)
918 return -1;
919
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800920
921 if(nLevel < 4) {
922 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
923 return -1;
924 } else {
925 return 0;
926 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800927 }
928
929
930 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
931 return nCBORError;
932 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
933 Item.val.string.len != 7 ||
934 memcmp(Item.val.string.ptr, "string1", 7))
935 return -1;
936
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800937 if(nLevel < 5) {
938 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
939 return -1;
940 } else {
941 return 0;
942 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800943 }
944
945 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
946 return nCBORError;
947 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
948 Item.val.string.len != 7 ||
949 memcmp(Item.val.string.ptr, "string2", 7))
950 return -1;
951
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800952 if(nLevel < 6) {
953 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
954 return -1;
955 } else {
956 return 0;
957 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800958 }
959
960 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
961 return nCBORError;
962 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
963 Item.label.string.len != 12 ||
964 memcmp(Item.label.string.ptr, "map in a map", 12) ||
965 Item.uDataType != QCBOR_TYPE_MAP ||
966 Item.val.uCount != 4)
967 return -1;
968
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800969 if(nLevel < 7) {
970 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
971 return -1;
972 } else {
973 return 0;
974 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800975 }
976
977 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
978 return nCBORError;
979 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
980 Item.label.string.len != 7 ||
981 memcmp(Item.label.string.ptr, "bytes 1", 7)||
982 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
983 Item.val.string.len != 4 ||
984 memcmp(Item.val.string.ptr, "xxxx", 4))
985 return -1;
986
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800987 if(nLevel < 8) {
988 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
989 return -1;
990 } else {
991 return 0;
992 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800993 }
994
995 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
996 return nCBORError;
997 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
998 Item.label.string.len != 7 ||
999 memcmp(Item.label.string.ptr, "bytes 2", 7) ||
1000 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
1001 Item.val.string.len != 4 ||
1002 memcmp(Item.val.string.ptr, "yyyy", 4))
1003 return -1;
1004
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +08001005 if(nLevel < 9) {
1006 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1007 return -1;
1008 } else {
1009 return 0;
1010 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001011 }
1012
1013 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1014 return nCBORError;
1015 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
1016 Item.label.string.len != 11 ||
1017 memcmp(Item.label.string.ptr, "another int", 11) ||
1018 Item.uDataType != QCBOR_TYPE_INT64 ||
1019 Item.val.int64 != 98)
1020 return -1;
1021
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +08001022 if(nLevel < 10) {
1023 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1024 return -1;
1025 } else {
1026 return 0;
1027 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001028 }
1029
1030 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1031 return nCBORError;
1032 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
1033 Item.label.string.len != 6 ||
1034 memcmp(Item.label.string.ptr, "text 2", 6)||
1035 Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1036 Item.val.string.len != 30 ||
1037 memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
1038 return -1;
1039
Laurence Lundbladefab1b522018-10-19 13:40:52 +05301040 if(QCBORDecode_Finish(&DCtx)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001041 return -1;
1042 }
1043
1044 return 0;
1045}
1046
1047
1048
1049
1050int ParseMapTest()
1051{
Laurence Lundbladefab1b522018-10-19 13:40:52 +05301052 // Parse a moderatly complex map structure very thoroughl
1053 int n = ParseMapTest1();
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001054
1055 if(!n) {
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +08001056 for(int i = 0; i < 10; i++) {
1057 n = ExtraBytesTest(i);
1058 if(n) {
1059 break;
1060 }
1061 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001062 }
1063
1064 return(n);
1065}
1066
1067
1068static uint8_t s_pSimpleValues[] = {0x8a, 0xf4, 0xf5, 0xf6, 0xf7, 0xff, 0xe0, 0xf3, 0xf8, 0x00, 0xf8, 0x13, 0xf8, 0x1f, 0xf8, 0x20, 0xf8, 0xff};
1069
1070int ParseSimpleTest()
1071{
1072 QCBORDecodeContext DCtx;
1073 QCBORItem Item;
1074 int nCBORError;
1075
1076
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301077 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_pSimpleValues), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001078
1079
1080 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1081 return nCBORError;
1082 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1083 Item.val.uCount != 10)
1084 return -1;
1085
1086 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1087 return nCBORError;
1088 if(Item.uDataType != QCBOR_TYPE_FALSE)
1089 return -1;
1090
1091 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1092 return nCBORError;
1093 if(Item.uDataType != QCBOR_TYPE_TRUE)
1094 return -1;
1095
1096 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1097 return nCBORError;
1098 if(Item.uDataType != QCBOR_TYPE_NULL)
1099 return -1;
1100
1101 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1102 return nCBORError;
1103 if(Item.uDataType != QCBOR_TYPE_UNDEF)
1104 return -1;
1105
1106 // A break
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001107 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_BAD_BREAK)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001108 return -1;
1109
1110 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1111 return nCBORError;
1112 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 0)
1113 return -1;
1114
1115 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1116 return nCBORError;
1117 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 19)
1118 return -1;
1119
1120 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
1121 return -1;
1122
1123 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
1124 return -1;
1125
1126 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
1127 return -1;
1128
1129 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1130 return nCBORError;
1131 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 32)
1132 return -1;
1133
1134 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1135 return nCBORError;
1136 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 255)
1137 return -1;
1138
1139 return 0;
1140
1141}
1142
1143
1144struct FailInput {
1145 UsefulBufC Input;
1146 int nError;
1147};
1148
1149
1150struct FailInput Failures[] = {
1151 { {(uint8_t[]){0x18}, 1}, QCBOR_ERR_HIT_END }, // 1 byte integer missing the byte
1152 { {(uint8_t[]){0x1c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1153 { {(uint8_t[]){0x1d}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 29
1154 { {(uint8_t[]){0x1e}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 30
1155 { {(uint8_t[]){0x1f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length integer
1156 { {(uint8_t[]){0x3c}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1157 { {(uint8_t[]){0x3d}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1158 { {(uint8_t[]){0x3e}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1159 { {(uint8_t[]){0x3f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length negative integer
1160 { {(uint8_t[]){0x41}, 1}, QCBOR_ERR_HIT_END }, // Short byte string
1161 { {(uint8_t[]){0x5c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1162 { {(uint8_t[]){0x5f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length byte string
1163 { {(uint8_t[]){0x61}, 1}, QCBOR_ERR_HIT_END }, // Short UTF-8 string
1164 { {(uint8_t[]){0x7c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1165 { {(uint8_t[]){0x7f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length UTF-8 string
1166 { {(uint8_t[]){0xff}, 1}, QCBOR_ERR_UNSUPPORTED } , // break
1167 { {(uint8_t[]){0xf8, 0x00}, 2}, QCBOR_ERR_INVALID_CBOR }, // An invalid encoding of a simple type
1168 { {(uint8_t[]){0xf8, 0x1f}, 2}, QCBOR_ERR_INVALID_CBOR }, // An invalid encoding of a simple type
1169 { {(uint8_t[]){0xc0, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG }, // Text-based date, with an integer
1170 { {(uint8_t[]){0xc1, 0x41, 0x33}, 3}, QCBOR_ERR_BAD_OPT_TAG }, // Epoch date, with an byte string
1171 { {(uint8_t[]){0xc1, 0xc0, 0x00}, 3}, QCBOR_ERR_BAD_OPT_TAG }, // tagged as both epoch and string dates
1172 { {(uint8_t[]){0xc2, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG } // big num tagged an int, not a byte string
1173
1174};
1175
1176
1177void Dump(UsefulBufC Input, int x)
1178{
1179 char label[10];
1180
1181 sprintf(label, "%d", x);
1182
1183 printencoded(label, Input.ptr, Input.len);
1184}
1185
1186
1187int FailureTests()
1188{
1189 int nResult = 0;
1190
1191 struct FailInput *pFEnd = &Failures[0] + sizeof(Failures)/sizeof(struct FailInput);
1192
1193 for(struct FailInput *pF = &Failures[0]; pF < pFEnd ;pF++) {
1194 QCBORDecodeContext DCtx;
1195 QCBORItem Item;
1196 int nCBORError;
1197
1198 QCBORDecode_Init(&DCtx, pF->Input, QCBOR_DECODE_MODE_NORMAL);
1199
1200 while(1) {
1201 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1202 if(QCBOR_ERR_HIT_END == nCBORError) {
1203 break;
1204 }
1205 if(nCBORError != pF->nError) {
1206 nResult = 1;
1207 // Dump(pF->Input, nCBORError);
1208 break;
1209 }
1210 }
1211 }
1212
1213 {
1214 QCBORDecodeContext DCtx;
1215 QCBORItem Item;
1216 int nCBORError;
1217
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301218 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_pSimpleValues), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001219
1220 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1221 return nCBORError;
1222 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1223 Item.val.uCount != 10)
1224 return -1;
1225
1226 DCtx.InBuf.magic = 0; // Corrupt the UsefulInputBuf
1227
1228 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1229 if(nCBORError != QCBOR_ERR_HIT_END)
1230 return -1;
1231 }
1232
1233
1234 return nResult;
1235}
1236
1237
1238
1239
1240static void Recurser(uint8_t *pBuf, int nLen, int nLenMax)
1241{
1242
1243 if(nLen >= nLenMax) {
1244 return;
1245 }
1246
1247 //printf("__%d__%d__\n", nLen, nLenMax);
1248
1249 for(int i = 0; i < 256; i++) {
1250 pBuf[nLen] = i;
1251
1252 QCBORDecodeContext DCtx;
1253 QCBORItem Item;
1254 int nCBORError;
1255
1256 UsefulBufC Input = {pBuf, nLen+1};
1257
1258 QCBORDecode_Init(&DCtx, Input, QCBOR_DECODE_MODE_NORMAL);
1259
1260 while(1) {
1261 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1262 if(QCBOR_ERR_HIT_END == nCBORError) {
1263 break;
1264 }
1265 if(nCBORError != QCBOR_SUCCESS) {
1266 if(nCBORError != QCBOR_ERR_UNSUPPORTED && nCBORError != QCBOR_ERR_HIT_END && nCBORError != QCBOR_ERR_INVALID_CBOR) {
1267 //Dump(Input, nCBORError);
1268 }
1269 break;
1270 }
1271 }
1272 //Dump(Input, -1);
1273
1274
1275 Recurser(pBuf, nLen+1, nLenMax);
1276 }
1277}
1278
1279
1280/*
1281 Runs all possible input strings of a given length. This is set to 3 to make the test
1282 run in reasonable time.
1283 Main point of this test is to not crash.
1284 */
1285
1286int ComprehensiveInputTest()
1287{
1288 uint8_t pBuf[3]; // 3 keeps it running in reasonable time. 4 takes tens of minutes.
1289
1290 Recurser(pBuf, 0, sizeof(pBuf));
1291
1292 return 0;
1293}
1294
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001295static uint8_t s_DateTestInput[] = {
1296 0xc0, // tag for string date
1297 0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
1298
1299 0xc1, // tag for epoch date
1300 0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
1301
1302 0xc1, 0xcf, 0xd8, 0xee, // Epoch date with extra tags
1303 0x1a, 0x53, 0x72, 0x4E, 0x01,
1304
1305 0xc1, // tag for epoch date
1306 0x1b, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // Too large integer
1307
1308 0xc1, // tag for epoch date
1309 0xfa, 0x3f, 0x8c, 0xcc, 0xcd, // double with value 1.1
1310
1311 0xc1, // tag for epoch date
1312 0xfa, 0x7f, 0x7f, 0xff, 0xff // 3.4028234663852886e+38 too large
1313
1314};
1315
1316
1317// have to check float expected only to within an epsilon
1318int CHECK_EXPECTED_DOUBLE(double val, double expected) {
1319
1320 double diff = val - expected;
1321
1322 diff = fabs(diff);
1323
1324 return diff > 0.0000001;
1325}
1326
1327
1328int DateParseTest()
1329{
1330 QCBORDecodeContext DCtx;
1331 QCBORItem Item;
1332 int nCBORError;
1333
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301334 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_DateTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001335
1336 // String date
1337 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1338 return -1;
1339 if(Item.uDataType != QCBOR_TYPE_DATE_STRING ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001340 UsefulBuf_Compare(Item.val.dateString, UsefulBuf_FromSZ("1985-04-12"))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001341 return -1;
1342 }
1343
1344 // Epoch date
1345 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1346 return -1;
1347 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1348 Item.val.epochDate.nSeconds != 1400000000 ||
1349 Item.val.epochDate.fSecondsFraction != 0 ) {
1350 return -1;
1351 }
1352
1353 // Epoch date with extra tags
1354 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1355 return -1;
1356 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1357 Item.val.epochDate.nSeconds != 1400000001 ||
1358 Item.val.epochDate.fSecondsFraction != 0 ||
1359 Item.uTagBits != (0x02 | (0x01 << 0x0f)) ||
1360 Item.uTag != 0xee) {
1361 return -1;
1362 }
1363
1364 // Epoch date that is too large for our representation
1365 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
1366 return -1;
1367 }
1368
1369 // Epoch date in float format with fractional seconds
1370 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1371 return -1;
1372 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1373 Item.val.epochDate.nSeconds != 1 ||
1374 CHECK_EXPECTED_DOUBLE(Item.val.epochDate.fSecondsFraction, 0.1 )) {
1375 return -1;
1376 }
1377
1378 // Epoch date float that is too large for our representation
1379 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
1380 return -1;
1381 }
1382
1383 // TODO: could use a few more tests with float, double, and half precsion and negative (but coverage is still pretty good)
1384
1385 return 0;
1386}
1387
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001388static uint8_t s_OptTestInput[] = {
1389 0xd9, 0xd9, 0xf7, // CBOR magic number
1390 0x81,
1391 0xd8, 62, // 62 is decimal intentionally
1392 0x00};
1393
1394int OptTagParseTest()
1395{
1396 QCBORDecodeContext DCtx;
1397 QCBORItem Item;
1398 int nCBORError;
1399
1400
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301401 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_OptTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001402
1403 //
1404 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1405 return -1;
1406 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1407 Item.uTagBits != QCBOR_TAGFLAG_CBOR_MAGIC) {
1408 return -1;
1409 }
1410
1411 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1412 return -1;
1413 if(Item.uDataType != QCBOR_TYPE_INT64 ||
1414 Item.uTagBits != (0x01LL << 62) ||
1415 Item.val.int64 != 0)
1416 return -1;
1417
1418 return 0;
1419}
1420
1421
1422
1423
1424static uint8_t s_BigNumInput[] = {
1425 0x83,
1426 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1427 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1428 0xA4,
1429 0x63, 0x42, 0x4E, 0x2B,
1430 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1431 0x18, 0x40,
1432 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1433 0x63, 0x42, 0x4E, 0x2D,
1434 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1435 0x38, 0x3F,
1436 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1437
1438
1439static uint8_t sBigNum[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1440
1441
1442int BignumParseTest()
1443{
1444 QCBORDecodeContext DCtx;
1445 QCBORItem Item;
1446 int nCBORError;
1447
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301448 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_BigNumInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001449
1450
1451 //
1452 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1453 return -1;
1454 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1455 return -1;
1456 }
1457
1458 //
1459 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1460 return -1;
1461 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301462 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001463 return -1;
1464 }
1465
1466 //
1467 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1468 return -1;
1469 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301470 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001471 return -1;
1472 }
1473
1474 //
1475 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1476 return -1;
1477 if(Item.uDataType != QCBOR_TYPE_MAP) {
1478 return -1;
1479 }
1480
1481 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1482 return -1;
1483 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1484 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301485 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001486 return -1;
1487 }
1488
1489 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1490 return -1;
1491 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1492 Item.uLabelType != QCBOR_TYPE_INT64 ||
1493 Item.label.int64 != 64 ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301494 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001495 return -1;
1496 }
1497
1498 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1499 return -1;
1500 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1501 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301502 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001503 return -1;
1504 }
1505
1506 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1507 return -1;
1508 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1509 Item.uLabelType != QCBOR_TYPE_INT64 ||
1510 Item.label.int64 != -64 ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301511 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001512 return -1;
1513 }
1514
1515 return 0;
1516}
1517
1518
1519
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301520static int CheckItemWithIntLabel(QCBORDecodeContext *pCtx, uint8_t uDataType, uint8_t uNestingLevel, uint8_t uNextNest, int64_t nLabel, QCBORItem *pItem)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001521{
1522 QCBORItem Item;
1523 int nCBORError;
1524
1525 if((nCBORError = QCBORDecode_GetNext(pCtx, &Item))) return -1;
1526 if(Item.uDataType != uDataType) return -1;
1527 if(uNestingLevel > 0) {
1528 if(Item.uLabelType != QCBOR_TYPE_INT64 && Item.uLabelType != QCBOR_TYPE_UINT64) return -1;
1529 if(Item.uLabelType == QCBOR_TYPE_INT64) {
1530 if(Item.label.int64 != nLabel) return -1;
1531 } else {
Laurence Lundblade570fab52018-10-13 18:28:27 +08001532 if(Item.label.uint64 != (uint64_t)nLabel) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001533 }
1534 }
1535 if(Item.uNestingLevel != uNestingLevel) return -1;
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301536 if(Item.uNextNestLevel != uNextNest) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001537
1538 if(pItem) {
1539 *pItem = Item;
1540 }
1541 return 0;
1542}
1543
1544
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001545// Same code checks definite and indefinite length versions of the map
1546static int CheckCSRMaps(QCBORDecodeContext *pDC)
1547{
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301548 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 0, 1, 0, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001549
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301550 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -23, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001551
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301552 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -20, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001553
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301554 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -18, NULL)) return -1;
1555 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -17, NULL)) return -1;
1556 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -15, NULL)) return -1;
1557 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -16, NULL)) return -1;
1558 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 2, -14, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001559
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301560 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -19, NULL)) return -1;
1561 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 3, 4, -11, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001562
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301563 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 4, 3, -9, NULL)) return -1;
1564 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_BYTE_STRING, 3, 1, -10, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001565
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301566 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -22, NULL)) return -1;
1567 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 2, 0, -5, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001568
1569 if(QCBORDecode_Finish(pDC)) return -2;
1570
1571 return 0;
1572}
1573
1574
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001575/*
1576// cbor.me decoded output
1577{
1578 -23: {
1579 -20: {
1580 -18: "Organization",
1581 -17: "SSG",
1582 -15: "Confusion",
1583 -16: "San Diego",
1584 -14: "US"
1585 },
1586 -19: {
1587 -11: {
1588 -9: -7
1589 },
1590 -10: '\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\n'
1591 }
1592 },
1593 -22: {
1594 -5: -3
1595 }
1596}
1597 */
1598
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001599
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001600static uint8_t s_CSRInput[] = {
1601 0xa2, 0x36, 0xa2, 0x33, 0xa5, 0x31, 0x6c, 0x4f,
1602 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1603 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1604 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1605 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1606 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1607 0x55, 0x53, 0x32, 0xa2, 0x2a, 0xa1, 0x28, 0x26,
1608 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1609 0x07, 0x08, 0x09, 0x0a, 0x35, 0xa1, 0x24, 0x22};
1610
1611int NestedMapTest()
1612{
1613 QCBORDecodeContext DCtx;
1614
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301615 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_CSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001616
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001617 return CheckCSRMaps(&DCtx);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001618}
1619
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001620// Same map as above, but using indefinite lengths
1621static uint8_t s_CSRInputIndefLen[] = {
1622 0xbf, 0x36, 0xbf, 0x33, 0xbf, 0x31, 0x6c, 0x4f,
1623 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1624 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1625 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1626 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1627 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1628 0x55, 0x53, 0xff, 0x32, 0xbf, 0x2a, 0xbf, 0x28, 0x26, 0xff,
1629 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1630 0x07, 0x08, 0x09, 0x0a, 0xff, 0xff, 0x35, 0xbf, 0x24, 0x22, 0xff, 0xff};
1631
1632int NestedMapTestIndefLen()
1633{
1634 QCBORDecodeContext DCtx;
1635
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301636 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_CSRInputIndefLen), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001637
1638 return CheckCSRMaps(&DCtx);
1639}
1640
1641
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001642
Laurence Lundblade17ede402018-10-13 11:43:07 +08001643static UsefulBufC make_nested_indefinite_arrays(int n, UsefulBuf Storage)
1644{
1645 UsefulOutBuf UOB;
1646 UsefulOutBuf_Init(&UOB, Storage);
1647
1648 int i;
1649 for(i = 0; i < n; i++) {
1650 UsefulOutBuf_AppendByte(&UOB, 0x9f);
1651 }
1652
1653 for(i = 0; i < n; i++) {
1654 UsefulOutBuf_AppendByte(&UOB, 0xff);
1655 }
1656 return UsefulOutBuf_OutUBuf(&UOB);
1657}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001658
1659
Laurence Lundblade17ede402018-10-13 11:43:07 +08001660static int parse_indeflen_nested(UsefulBufC Nested, int nNestLevel)
1661{
1662 QCBORDecodeContext DC;
1663 QCBORDecode_Init(&DC, Nested, 0);
1664
1665 int j;
1666 for(j = 0; j < nNestLevel; j++) {
1667 QCBORItem Item;
1668 int nReturn = QCBORDecode_GetNext(&DC, &Item);
1669 if(j >= QCBOR_MAX_ARRAY_NESTING) {
1670 // Should be in error
1671 if(nReturn != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP) {
1672 return -4;
1673 } else {
1674 return 0; // Decoding doesn't recover after an error
1675 }
1676 } else {
1677 // Should be no error
1678 if(nReturn) {
1679 return -9; // Should not have got an error
1680 }
1681 }
1682 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1683 return -7;
1684 }
1685 }
1686 int nReturn = QCBORDecode_Finish(&DC);
1687 if(nReturn) {
1688 return -3;
1689 }
1690 return 0;
1691}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001692
1693
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301694int IndefiniteLengthNestTest()
Laurence Lundblade17ede402018-10-13 11:43:07 +08001695{
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301696 UsefulBuf_MAKE_STACK_UB(Storage, 50);
Laurence Lundblade17ede402018-10-13 11:43:07 +08001697 int i;
Laurence Lundblade6de37062018-10-15 12:22:42 +05301698 for(i=1; i < QCBOR_MAX_ARRAY_NESTING+4; i++) {
Laurence Lundblade17ede402018-10-13 11:43:07 +08001699 UsefulBufC Nested = make_nested_indefinite_arrays(i, Storage);
1700 int nReturn = parse_indeflen_nested(Nested, i);
1701 if(nReturn) {
1702 return nReturn;
1703 }
1704 }
1705 return 0;
1706}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001707
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001708
Laurence Lundblade6de37062018-10-15 12:22:42 +05301709
1710static const uint8_t pIndefiniteArray[] = {0x9f, 0x01, 0x82, 0x02, 0x03, 0xff}; // [1, [2, 3]]
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001711static const uint8_t pIndefiniteArrayBad1[] = {0x9f}; // No closing break
1712static const uint8_t pIndefiniteArrayBad2[] = {0x9f, 0x9f, 0x02, 0xff}; // Not enough closing breaks
1713static const uint8_t pIndefiniteArrayBad3[] = {0x9f, 0x02, 0xff, 0xff}; // Too many closing breaks
Laurence Lundblade570fab52018-10-13 18:28:27 +08001714static const uint8_t pIndefiniteArrayBad4[] = {0x81, 0x9f}; // Unclosed indeflen inside def len
Laurence Lundblade6de37062018-10-15 12:22:42 +05301715static const uint8_t pIndefiniteArrayBad5[] = {0x9f, 0xc7, 0xff}; // confused tag
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001716
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301717int IndefiniteLengthArrayMapTest()
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001718{
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001719 int nResult;
1720 // --- first test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301721 UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArray);
Laurence Lundblade17ede402018-10-13 11:43:07 +08001722
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001723 // Decode it and see if it is OK
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301724 UsefulBuf_MAKE_STACK_UB(MemPool, 150);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001725 QCBORDecodeContext DC;
1726 QCBORItem Item;
1727 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1728
1729 QCBORDecode_SetMemPool(&DC, MemPool, false);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301730
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001731 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301732
1733 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1734 Item.uNestingLevel != 0 ||
1735 Item.uNextNestLevel != 1) {
1736 return -111;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001737 }
1738
1739 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301740 if(Item.uDataType != QCBOR_TYPE_INT64 ||
1741 Item.uNestingLevel != 1 ||
1742 Item.uNextNestLevel != 1) {
1743 return -2;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001744 }
1745
1746 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301747 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1748 Item.uNestingLevel != 1 ||
1749 Item.uNextNestLevel != 2) {
1750 return -3;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001751 }
1752
1753 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301754 if(Item.uDataType != QCBOR_TYPE_INT64 |
1755 Item.uNestingLevel != 2 ||
1756 Item.uNextNestLevel != 2) {
1757 return -4;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001758 }
1759
1760 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301761 if(Item.uDataType != QCBOR_TYPE_INT64 |
1762 Item.uNestingLevel != 2 ||
1763 Item.uNextNestLevel != 0) {
1764 return -5;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001765 }
1766
1767 if(QCBORDecode_Finish(&DC)) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301768 return -6;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001769 }
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001770
1771 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301772 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad1);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001773
1774 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1775
1776 QCBORDecode_SetMemPool(&DC, MemPool, false);
1777
1778 nResult = QCBORDecode_GetNext(&DC, &Item);
1779 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301780 return -7;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001781 }
1782
Laurence Lundblade570fab52018-10-13 18:28:27 +08001783 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301784 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1785 return -8;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001786 }
1787
1788
1789 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301790 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad2);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001791
1792 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1793
1794 QCBORDecode_SetMemPool(&DC, MemPool, false);
1795
1796 nResult = QCBORDecode_GetNext(&DC, &Item);
1797 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301798 return -9;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001799 }
1800
1801 nResult = QCBORDecode_GetNext(&DC, &Item);
1802 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301803 return -10;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001804 }
1805
1806 nResult = QCBORDecode_GetNext(&DC, &Item);
1807 if(nResult || Item.uDataType != QCBOR_TYPE_INT64) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301808 return -11;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001809 }
1810
1811 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301812 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1813 return -12;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001814 }
1815
1816
1817 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301818 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad3);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001819
1820 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1821
1822 QCBORDecode_SetMemPool(&DC, MemPool, false);
1823
1824 nResult = QCBORDecode_GetNext(&DC, &Item);
1825 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301826 return -13;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001827 }
1828
1829 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301830 if(nResult != QCBOR_ERR_BAD_BREAK) {
1831 return -14;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001832 }
Laurence Lundblade6de37062018-10-15 12:22:42 +05301833
Laurence Lundblade570fab52018-10-13 18:28:27 +08001834
1835 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301836 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad4);
Laurence Lundblade570fab52018-10-13 18:28:27 +08001837
1838 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1839
1840 QCBORDecode_SetMemPool(&DC, MemPool, false);
1841
1842 nResult = QCBORDecode_GetNext(&DC, &Item);
1843 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301844 return -15;
Laurence Lundblade570fab52018-10-13 18:28:27 +08001845 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301846
Laurence Lundblade570fab52018-10-13 18:28:27 +08001847 nResult = QCBORDecode_GetNext(&DC, &Item);
1848 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301849 return -16;
Laurence Lundblade570fab52018-10-13 18:28:27 +08001850 }
1851
1852 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301853 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1854 return -17;
Laurence Lundblade570fab52018-10-13 18:28:27 +08001855 }
1856
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301857 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301858 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad5);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301859
1860 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1861
1862 QCBORDecode_SetMemPool(&DC, MemPool, false);
1863
1864 nResult = QCBORDecode_GetNext(&DC, &Item);
1865 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301866 return -18;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301867 }
1868
1869 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301870 if(nResult != QCBOR_ERR_BAD_BREAK) {
1871 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301872 }
1873
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001874 return 0;
1875}
1876
Laurence Lundblade17ede402018-10-13 11:43:07 +08001877
1878static const uint8_t pIndefiniteLenString[] = {
1879 0x81, // Array of length one
1880 0x7f, // text string marked with indefinite length
1881 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
1882 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
1883 0xff // ending break
1884};
1885
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301886static const uint8_t pIndefiniteLenStringBad2[] = {
1887 0x81, // Array of length one
1888 0x7f, // text string marked with indefinite length
1889 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
1890 0x44, 0x6d, 0x69, 0x6e, 0x67, // second segment of wrong type
1891 0xff // ending break
1892};
1893
1894static const uint8_t pIndefiniteLenStringBad3[] = {
1895 0x81, // Array of length one
1896 0x7f, // text string marked with indefinite length
1897 0x01, 0x02, // Not a string
1898 0xff // ending break
1899};
1900
1901static const uint8_t pIndefiniteLenStringBad4[] = {
1902 0x81, // Array of length one
1903 0x7f, // text string marked with indefinite length
1904 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
1905 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
1906 // missing end of string
1907};
1908
1909static const uint8_t pIndefiniteLenStringLabel[] = {
1910 0xa1, // Array of length one
1911 0x7f, // text string marked with indefinite length
1912 0x65, 0x73, 0x74, 0x72, 0x75, 0x75, // first segment
1913 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
1914 0xff, // ending break
1915 0x01 // integer being labeled.
1916};
1917
1918static UsefulBufC MakeIndefiniteBigBstr(UsefulBuf Storage)
1919{
1920 UsefulOutBuf UOB;
1921
1922 UsefulOutBuf_Init(&UOB, Storage);
1923 UsefulOutBuf_AppendByte(&UOB, 0x81);
1924 UsefulOutBuf_AppendByte(&UOB, 0x5f);
1925
1926 int i = 0;
1927 for(int nChunkSize = 1; nChunkSize <= 128; nChunkSize *= 2) {
1928 UsefulOutBuf_AppendByte(&UOB, 0x58);
1929 UsefulOutBuf_AppendByte(&UOB, (uint8_t)nChunkSize);
1930 for(int j = 0; j < nChunkSize; j++ ) {
1931 UsefulOutBuf_AppendByte(&UOB, i);
1932 i++;
1933 }
1934 }
1935 UsefulOutBuf_AppendByte(&UOB, 0xff);
1936
1937 return UsefulOutBuf_OutUBuf(&UOB);
1938}
1939
1940static int CheckBigString(UsefulBufC BigString)
1941{
1942 if(BigString.len != 255) {
1943 return 1;
1944 }
1945
1946 for(uint8_t i = 0; i < 255; i++){
1947 if(((const uint8_t *)BigString.ptr)[i] != i) {
1948 return 1;
1949 }
1950 }
1951 return 0;
1952}
1953
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05301954
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301955int IndefiniteLengthStringTest()
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301956{
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301957 QCBORDecodeContext DC;
1958 QCBORItem Item;
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05301959 // big enough for MakeIndefiniteBigBstr() + MemPool overhead
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301960 UsefulBuf_MAKE_STACK_UB(MemPool, 320);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301961
1962 // --- Simple normal indefinite length string ------
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301963 UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenString);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301964 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001965
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05301966 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301967 return -1;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301968 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001969
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301970 if(QCBORDecode_GetNext(&DC, &Item)) {
1971 return -2;
1972 }
1973 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
1974 return -3;
1975 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001976
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301977 if(QCBORDecode_GetNext(&DC, &Item)) {
1978 return -4;
1979 }
1980 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING || !Item.uDataAlloc) {
1981 return -5;
1982 }
1983 if(QCBORDecode_Finish(&DC)) {
1984 return -6;
1985 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301986
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301987 // ----- types mismatch ---
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301988 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenStringBad2), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301989
1990 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
1991 return -7;
1992 }
1993
1994 if(QCBORDecode_GetNext(&DC, &Item)) {
1995 return -8;
1996 }
1997 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1998 return -9;
1999 }
2000
2001 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_SEG) {
2002 return -10;
2003 }
2004
2005 // ----- not a string ---
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302006 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenStringBad3), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302007
2008 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2009 return -11;
2010 }
2011
2012 if(QCBORDecode_GetNext(&DC, &Item)) {
2013 return -12;
2014 }
2015 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2016 return -13;
2017 }
2018
2019 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_SEG) {
2020 return -14;
2021 }
2022
2023 // ----- no end -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302024 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenStringBad4), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302025
2026 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2027 return -15;
2028 }
2029
2030 if(QCBORDecode_GetNext(&DC, &Item)) {
2031 return -16;
2032 }
2033 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2034 return -17;
2035 }
2036
2037 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_HIT_END) {
2038 return -18;
2039 }
2040
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302041 // ------ Don't set a string allocator and see an error -----
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302042 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2043
2044 QCBORDecode_GetNext(&DC, &Item);
2045 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302046 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302047 }
2048
2049 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_NO_STRING_ALLOCATOR) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302050 return -20;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302051 }
2052
2053 // ----- Mempool is way too small -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302054 UsefulBuf_MAKE_STACK_UB(MemPoolTooSmall, 20); // 20 is too small no matter what
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302055
2056 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2057 if(!QCBORDecode_SetMemPool(&DC, MemPoolTooSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302058 return -21;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302059 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302060
2061 // ----- Mempool is way too small -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302062 UsefulBuf_MAKE_STACK_UB(BigIndefBStrStorage, 290);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302063 UsefulBufC BigIndefBStr = MakeIndefiniteBigBstr(BigIndefBStrStorage);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302064
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302065 UsefulBuf_MAKE_STACK_UB(MemPoolSmall, 80); // 80 is big enough for MemPool overhead, but not BigIndefBStr
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302066
2067 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302068 if(QCBORDecode_SetMemPool(&DC, MemPoolSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302069 return -22;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302070 }
2071
2072 QCBORDecode_GetNext(&DC, &Item);
2073 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302074 return -23;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302075 }
2076 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_STRING_ALLOC) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302077 return -24;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302078 }
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302079
2080 // ---- big bstr -----
2081 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
2082
2083 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2084 return -25;
2085 }
2086
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302087 if(QCBORDecode_GetNext(&DC, &Item)) {
2088 return -26;
2089 }
2090 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302091 return -26;
2092 }
2093
2094 if(QCBORDecode_GetNext(&DC, &Item)) {
2095 return -27;
2096 }
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302097 if(Item.uDataType != QCBOR_TYPE_BYTE_STRING || !Item.uDataAlloc || Item.uNestingLevel != 1) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302098 return -28;
2099 }
2100 if(CheckBigString(Item.val.string)) {
2101 return -3;
2102 }
2103 if(QCBORDecode_Finish(&DC)) {
2104 return -29;
2105 }
2106
2107 // --- label is an indefinite length string ------
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302108 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenStringLabel), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302109
2110 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2111 return -30;
2112 }
2113
2114 QCBORDecode_GetNext(&DC, &Item);
2115 if(Item.uDataType != QCBOR_TYPE_MAP) {
2116 return -31;
2117 }
2118
2119 if(QCBORDecode_GetNext(&DC, &Item)){
2120 return -32;
2121 }
2122 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING || Item.uDataType != QCBOR_TYPE_INT64 ||
2123 Item.uDataAlloc || !Item.uLabelAlloc ||
2124 UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("struuming"))) {
2125 return -33;
2126 }
2127
2128 if(QCBORDecode_Finish(&DC)) {
2129 return -34;
2130 }
2131
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002132 return 0;
2133}
2134
2135
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302136int AllocAllStringsTest()
2137{
2138 QCBORDecodeContext DC;
2139
2140 // First test, use the "CSRMap" as easy input and checking
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302141 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_CSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302142
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302143 UsefulBuf_MAKE_STACK_UB(Pool, 300);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302144
2145 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2146
2147 if(CheckCSRMaps(&DC)) {
2148 return -1;
2149 }
2150
2151 // Next parse, save pointers to a few strings, destroy original and see all is OK.
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302152 UsefulBuf_MAKE_STACK_UB(CopyOfStorage, 160);
2153 UsefulBufC CopyOf = UsefulBuf_Copy(CopyOfStorage, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded));
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002154
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302155 QCBORDecode_Init(&DC, CopyOf, QCBOR_DECODE_MODE_NORMAL);
2156 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2157
2158 int nCBORError;
2159 QCBORItem Item1, Item2, Item3, Item4;
2160 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2161 return nCBORError;
2162 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2163 Item1.val.uCount != 3)
2164 return -1;
2165 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2166 return nCBORError;
2167 if((nCBORError = QCBORDecode_GetNext(&DC, &Item2)))
2168 return nCBORError;
2169 if((nCBORError = QCBORDecode_GetNext(&DC, &Item3)))
2170 return nCBORError;
2171 if((nCBORError = QCBORDecode_GetNext(&DC, &Item4)))
2172 return nCBORError;
2173
Laurence Lundblade05ec57b2018-10-21 01:50:03 +05302174 UsefulBuf_Set(CopyOfStorage, '_');
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302175
2176 if(Item1.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2177 Item1.label.string.len != 13 ||
2178 Item1.uDataType != QCBOR_TYPE_INT64 ||
2179 Item1.val.int64 != 42 ||
2180 memcmp(Item1.label.string.ptr, "first integer", 13))
2181 return -1;
2182
2183
2184 if(Item2.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2185 Item2.label.string.len != 23 ||
2186 memcmp(Item2.label.string.ptr, "an array of two strings", 23) ||
2187 Item2.uDataType != QCBOR_TYPE_ARRAY ||
2188 Item2.val.uCount != 2)
2189 return -1;
2190
2191 if(Item3.uDataType != QCBOR_TYPE_TEXT_STRING ||
2192 Item3.val.string.len != 7 ||
2193 memcmp(Item3.val.string.ptr, "string1", 7))
2194 return -1;
2195
2196 if(Item4.uDataType != QCBOR_TYPE_TEXT_STRING ||
2197 Item4.val.string.len != 7 ||
2198 memcmp(Item4.val.string.ptr, "string2", 7))
2199 return -1;
2200
2201 // Next parse with a pool that is too small
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302202 UsefulBuf_MAKE_STACK_UB(SmallPool, 80);
2203 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302204 QCBORDecode_SetMemPool(&DC, SmallPool, 1); // Turn on copying.
2205 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2206 return nCBORError;
2207 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2208 Item1.val.uCount != 3)
2209 return -1;
2210 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item1))){
2211 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item2))) {
2212 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item3))) {
2213 nCBORError = QCBORDecode_GetNext(&DC, &Item4);
2214 }
2215 }
2216 }
2217 if(nCBORError != QCBOR_ERR_STRING_ALLOC) {
2218 return -5;
2219 }
2220
2221 return 0;
2222}
2223
2224
2225int MemPoolTest(void)
Laurence Lundblade0155b622018-10-12 20:04:37 +08002226{
2227 QCBORDecodeContext DC;
2228
2229 const uint8_t pMinimalCBOR[] = {0xa0}; // One empty map
2230
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302231 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pMinimalCBOR),0);
Laurence Lundblade0155b622018-10-12 20:04:37 +08002232
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302233 UsefulBuf_MAKE_STACK_UB(Pool, 100);
Laurence Lundblade0155b622018-10-12 20:04:37 +08002234
2235 QCBORDecode_SetMemPool(&DC, Pool, 0);
2236
2237 // Cheat a little to get to the string allocator object
2238 // so we can call it directly to test it
2239 QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2240
2241 // Ask for too much in one go
2242 // 90 < 100, but there is some overhead taken out of the 100
2243 UsefulBuf Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 90);
2244 if(!UsefulBuf_IsNULL(Allocated)) {
2245 return -1;
2246 }
2247
2248
2249
2250 QCBORDecode_SetMemPool(&DC, Pool, 0);
2251
2252 // Cheat a little to get to the string allocator object
2253 // so we can call it directly to test it
2254 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2255
2256 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2257 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2258 return -1;
2259 }
2260 UsefulBuf Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2261 if(!UsefulBuf_IsNULL(Allocated2)) { // expected to fail
2262 return -1;
2263 }
2264 (*pAlloc->fFree)(pAlloc->pAllocaterContext, Allocated.ptr);
2265 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2266 if(UsefulBuf_IsNULL(Allocated)) { // succeed because of the free
2267 return -1;
2268 }
2269
2270
2271 QCBORDecode_SetMemPool(&DC, Pool, 0);
2272
2273 // Cheat a little to get to the string allocator object
2274 // so we can call it directly to test it
2275 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2276 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 20);
2277 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2278 return -1;
2279 }
2280 Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, 25);
2281 if(UsefulBuf_IsNULL(Allocated2)) { // expected to fail
2282 return -1;
2283 }
2284 if(Allocated2.ptr != Allocated.ptr || Allocated2.len != 25) {
2285 return -1;
2286 }
2287
Laurence Lundblade0155b622018-10-12 20:04:37 +08002288 return 0;
2289}
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002290
2291
2292
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08002293
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002294
2295