blob: c6ab0ea35620f457ebd8b3fb9b710294d0996dad [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
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001302 // CBOR_TAG_B64
1303 0xc1, 0xcf, 0xd8, 0x22, // 0xee, // Epoch date with extra tags TODO: fix this test
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001304 0x1a, 0x53, 0x72, 0x4E, 0x01,
1305
1306 0xc1, // tag for epoch date
1307 0x1b, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // Too large integer
1308
1309 0xc1, // tag for epoch date
1310 0xfa, 0x3f, 0x8c, 0xcc, 0xcd, // double with value 1.1
1311
1312 0xc1, // tag for epoch date
1313 0xfa, 0x7f, 0x7f, 0xff, 0xff // 3.4028234663852886e+38 too large
1314
1315};
1316
1317
1318// have to check float expected only to within an epsilon
1319int CHECK_EXPECTED_DOUBLE(double val, double expected) {
1320
1321 double diff = val - expected;
1322
1323 diff = fabs(diff);
1324
1325 return diff > 0.0000001;
1326}
1327
1328
1329int DateParseTest()
1330{
1331 QCBORDecodeContext DCtx;
1332 QCBORItem Item;
1333 int nCBORError;
1334
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301335 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_DateTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001336
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001337 const uint64_t uTags[] = {15};
1338 QCBORTagListIn TagList = {1, uTags};
1339
1340 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
1341
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001342 // String date
1343 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1344 return -1;
1345 if(Item.uDataType != QCBOR_TYPE_DATE_STRING ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001346 UsefulBuf_Compare(Item.val.dateString, UsefulBuf_FromSZ("1985-04-12"))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001347 return -1;
1348 }
1349
1350 // Epoch date
1351 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1352 return -1;
1353 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1354 Item.val.epochDate.nSeconds != 1400000000 ||
1355 Item.val.epochDate.fSecondsFraction != 0 ) {
1356 return -1;
1357 }
1358
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001359 // Epoch date with extra CBOR_TAG_B64 tag that doesn't really mean anything
1360 // but want to be sure extra tag doesn't cause a problem
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001361 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1362 return -1;
1363 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1364 Item.val.epochDate.nSeconds != 1400000001 ||
1365 Item.val.epochDate.fSecondsFraction != 0 ||
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001366 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_B64)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001367 return -1;
1368 }
1369
1370 // Epoch date that is too large for our representation
1371 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
1372 return -1;
1373 }
1374
1375 // Epoch date in float format with fractional seconds
1376 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1377 return -1;
1378 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1379 Item.val.epochDate.nSeconds != 1 ||
1380 CHECK_EXPECTED_DOUBLE(Item.val.epochDate.fSecondsFraction, 0.1 )) {
1381 return -1;
1382 }
1383
1384 // Epoch date float that is too large for our representation
1385 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
1386 return -1;
1387 }
1388
1389 // TODO: could use a few more tests with float, double, and half precsion and negative (but coverage is still pretty good)
1390
1391 return 0;
1392}
1393
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001394// Really simple basic input for tagging test
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001395static uint8_t s_OptTestInput[] = {
1396 0xd9, 0xd9, 0xf7, // CBOR magic number
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001397 0x81, // Array of one
1398 0xd8, 0x04, // non-preferred serialization of tag 4
1399 0x82, 0x01, 0x03}; // fraction 1/3
1400
1401static uint8_t spEncodedLargeTag[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x80};
1402
1403// 0x9192939495969798, 0x88, 0x01, 0x04
1404static uint8_t spLotsOfTags[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0xd8, 0x88, 0xc5, 0xc4, 0x80};
1405
1406/*
1407 The cbor.me parse of this.
1408 55799(55799(55799({6(7(-23)): 5859837686836516696(7({7(-20): 11({17(-18): 17(17(17("Organization"))),
1409 9(-17): 773("SSG"), -15: 4(5(6(7(8(9(10(11(12(13(14(15("Confusion")))))))))))), 17(-16): 17("San Diego"),
1410 17(-14): 17("US")}), 23(-19): 19({-11: 9({-9: -7}),
1411 90599561(90599561(90599561(-10))): 12(h'0102030405060708090A')})})),
1412 16(-22): 23({11(8(7(-5))): 8(-3)})})))
1413 */
1414static uint8_t spCSRWithTags[] = {
1415 0xd9, 0xd9, 0xf7, 0xd9, 0xd9, 0xf7, 0xd9, 0xd9, 0xf7, 0xa2,
1416 0xc6, 0xc7, 0x36,
1417 0xdb, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0xc7, 0xa2,
1418 0xda, 0x00, 0x00, 0x00, 0x07, 0x33,
1419 0xcb, 0xa5,
1420 0xd1, 0x31,
1421 0xd1, 0xd1, 0xd1, 0x6c,
1422 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
1423 0xc9, 0x30,
1424 0xd9, 0x03, 0x05, 0x63,
1425 0x53, 0x53, 0x47,
1426 0x2e,
1427 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0x69,
1428 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x69, 0x6f, 0x6e,
1429 0xd1, 0x2f,
1430 0xd1, 0x69,
1431 0x53, 0x61, 0x6e, 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f,
1432 0xd1, 0x2d,
1433 0xd1, 0x62,
1434 0x55, 0x53,
1435 0xd7, 0x32,
1436 0xd3, 0xa2,
1437 0x2a,
1438 0xc9, 0xa1,
1439 0x28,
1440 0x26,
1441 0xda, 0x05, 0x66, 0x70, 0x89, 0xda, 0x05, 0x66, 0x70, 0x89, 0xda, 0x05, 0x66, 0x70, 0x89, 0x29,
1442 0xcc, 0x4a,
1443 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,0x07, 0x08, 0x09, 0x0a,
1444 0xd0, 0x35,
1445 0xd7, 0xa1,
1446 0xcb, 0xc8, 0xc7, 0x24,
1447 0xc8, 0x22};
1448
1449static int CheckCSRMaps(QCBORDecodeContext *pDC);
1450
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001451
1452int OptTagParseTest()
1453{
1454 QCBORDecodeContext DCtx;
1455 QCBORItem Item;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001456
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301457 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_OptTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001458
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001459 //-------------------------
1460 // This text matches the magic number tag and the fraction tag
1461 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1462 return -2;
1463 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001464 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001465 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC)) {
1466 return -3;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001467 }
1468
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001469 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1470 return -4;
1471 }
1472 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1473 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_FRACTION) ||
1474 Item.val.uCount != 2) {
1475 return -5;
1476 }
1477
1478 // --------------------------------
1479 // This test decodes the very large tag, but it is not in
1480 // any list so it is ignored.
1481 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
1482 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1483 return -6;
1484 }
1485 if(Item.uTagBits) {
1486 return -7;
1487 }
1488
1489 // ----------------------------------
1490 // This test sets up a caller-config list that includes the very large tage and then matches it.
1491 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
1492 const uint64_t puList[] = {0x9192939495969798, 257};
1493 const QCBORTagListIn TL = {2, puList};
1494 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TL);
1495
1496 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1497 return -8;
1498 }
1499 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1500 !QCBORDecode_IsTagged(&DCtx, &Item, 0x9192939495969798) ||
1501 QCBORDecode_IsTagged(&DCtx, &Item, 257) ||
1502 QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_BIGFLOAT) ||
1503 Item.val.uCount != 0) {
1504 return -9;
1505 }
1506
1507 //------------------------
1508 // This test sets up a caller-configured list, and looks up something not in it
1509 const uint64_t puLongList[17] = {1,2,1};
1510 const QCBORTagListIn TLLong = {17, puLongList};
1511 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
1512 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TLLong);
1513 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1514 return -11;
1515 }
1516
1517 // -----------------------
1518 // This tests retrievel of the full tag list
1519 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
1520 uint64_t puTags[16];
1521 QCBORTagListOut Out = {0, 4, puTags};
1522 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1523 return -12;
1524 }
1525 if(puTags[0] != 0x9192939495969798 ||
1526 puTags[1] != 0x88 ||
1527 puTags[2] != 0x05 ||
1528 puTags[3] != 0x04) {
1529 return -13;
1530 }
1531
1532 // ----------------------
1533 // This text if too small of an out list
1534 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
1535 QCBORTagListOut OutSmall = {0, 3, puTags};
1536 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &OutSmall) != QCBOR_ERR_TOO_MANY_TAGS) {
1537 return -14;
1538 }
1539
1540 // ---------------
1541 // Parse a version of the "CSR" that has had a ton of tags randomly inserted
1542 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
1543 int n = CheckCSRMaps(&DCtx);
1544 if(n) {
1545 return n-2000;
1546 }
1547
1548 Out = (QCBORTagListOut){0,16, puTags};
1549 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
1550
1551 const uint64_t puTagList[] = {773, 1, 90599561};
1552 const QCBORTagListIn TagList = {3, puTagList};
1553 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
1554
1555
1556 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1557 return -100;
1558 }
1559 if(Item.uDataType != QCBOR_TYPE_MAP ||
1560 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC) ||
1561 QCBORDecode_IsTagged(&DCtx, &Item, 90599561) ||
1562 QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_DATE_EPOCH) ||
1563 Item.val.uCount != 2 ||
1564 puTags[0] != CBOR_TAG_CBOR_MAGIC ||
1565 puTags[1] != CBOR_TAG_CBOR_MAGIC ||
1566 puTags[2] != CBOR_TAG_CBOR_MAGIC ||
1567 Out.uNumUsed != 3) {
1568 return -101;
1569 }
1570
1571 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1572 return -102;
1573 }
1574 if(Item.uDataType != QCBOR_TYPE_MAP ||
1575 QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC) ||
1576 QCBORDecode_IsTagged(&DCtx, &Item, 6) ||
1577 QCBORDecode_IsTagged(&DCtx, &Item, 7) || // item is tagged 7, but 7 is not configured to be recognized
1578 Item.val.uCount != 2 ||
1579 puTags[0] != 5859837686836516696 ||
1580 puTags[1] != 7 ||
1581 Out.uNumUsed != 2) {
1582 return -103;
1583 }
1584
1585 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1586 return -104;
1587 }
1588 if(Item.uDataType != QCBOR_TYPE_MAP ||
1589 Item.uTagBits ||
1590 Item.val.uCount != 5 ||
1591 puTags[0] != 0x0b ||
1592 Out.uNumUsed != 1) {
1593 return -105;
1594 }
1595
1596 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1597 return -106;
1598 }
1599 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1600 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_COSE_MAC0) ||
1601 Item.val.string.len != 12 ||
1602 puTags[0] != CBOR_TAG_COSE_MAC0 ||
1603 puTags[1] != CBOR_TAG_COSE_MAC0 ||
1604 puTags[2] != CBOR_TAG_COSE_MAC0 ||
1605 Out.uNumUsed != 3) {
1606 return -105;
1607 }
1608
1609 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1610 return -107;
1611 }
1612 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1613 !QCBORDecode_IsTagged(&DCtx, &Item, 773) ||
1614 Item.val.string.len != 3 ||
1615 puTags[0] != 773 ||
1616 Out.uNumUsed != 1) {
1617 return -108;
1618 }
1619
1620 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1621 return -109;
1622 }
1623 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1624 !QCBORDecode_IsTagged(&DCtx, &Item, 4) ||
1625 Item.val.string.len != 9 ||
1626 puTags[0] != 4 ||
1627 puTags[11] != 0x0f ||
1628 Out.uNumUsed != 12) {
1629 return -110;
1630 }
1631
1632 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1633 return -111;
1634 }
1635 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1636 !QCBORDecode_IsTagged(&DCtx, &Item, 17) ||
1637 Item.val.string.len != 9 ||
1638 puTags[0] != 17 ||
1639 Out.uNumUsed != 1) {
1640 return -112;
1641 }
1642
1643 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1644 return -111;
1645 }
1646 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1647 !QCBORDecode_IsTagged(&DCtx, &Item, 17) ||
1648 Item.val.string.len != 2 ||
1649 puTags[0] != 17 ||
1650 Out.uNumUsed != 1) {
1651 return -112;
1652 }
1653
1654 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1655 return -113;
1656 }
1657 if(Item.uDataType != QCBOR_TYPE_MAP ||
1658 QCBORDecode_IsTagged(&DCtx, &Item, 19) ||
1659 Item.val.uCount != 2 ||
1660 puTags[0] != 19 ||
1661 Out.uNumUsed != 1) {
1662 return -114;
1663 }
1664
1665 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1666 return -115;
1667 }
1668 if(Item.uDataType != QCBOR_TYPE_MAP ||
1669 QCBORDecode_IsTagged(&DCtx, &Item, 9) ||
1670 Item.uTagBits ||
1671 Item.val.uCount != 1 ||
1672 puTags[0] != 9 ||
1673 Out.uNumUsed != 1) {
1674 return -116;
1675 }
1676
1677 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1678 return -116;
1679 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001680 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001681 Item.val.int64 != -7 ||
1682 Item.uTagBits ||
1683 Out.uNumUsed != 0) {
1684 return -117;
1685 }
1686
1687 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1688 return -118;
1689 }
1690 if(Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
1691 Item.val.string.len != 10 ||
1692 Item.uTagBits ||
1693 puTags[0] != 12 ||
1694 Out.uNumUsed != 1) {
1695 return -119;
1696 }
1697
1698 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1699 return -120;
1700 }
1701 if(Item.uDataType != QCBOR_TYPE_MAP ||
1702 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_ENC_AS_B16) ||
1703 Item.val.uCount != 1 ||
1704 puTags[0] != 0x17 ||
1705 Out.uNumUsed != 1) {
1706 return -121;
1707 }
1708
1709 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1710 return -122;
1711 }
1712 if(Item.uDataType != QCBOR_TYPE_INT64 ||
1713 QCBORDecode_IsTagged(&DCtx, &Item, 8) ||
1714 Item.val.int64 != -3 ||
1715 puTags[0] != 8 ||
1716 Out.uNumUsed != 1) {
1717 return -123;
1718 }
1719
1720 if(QCBORDecode_Finish(&DCtx)) {
1721 return -124;
1722 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001723
1724 return 0;
1725}
1726
1727
1728
1729
1730static uint8_t s_BigNumInput[] = {
1731 0x83,
1732 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1733 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1734 0xA4,
1735 0x63, 0x42, 0x4E, 0x2B,
1736 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1737 0x18, 0x40,
1738 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1739 0x63, 0x42, 0x4E, 0x2D,
1740 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1741 0x38, 0x3F,
1742 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1743
1744
1745static uint8_t sBigNum[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1746
1747
1748int BignumParseTest()
1749{
1750 QCBORDecodeContext DCtx;
1751 QCBORItem Item;
1752 int nCBORError;
1753
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301754 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_BigNumInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001755
1756
1757 //
1758 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1759 return -1;
1760 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1761 return -1;
1762 }
1763
1764 //
1765 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1766 return -1;
1767 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301768 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001769 return -1;
1770 }
1771
1772 //
1773 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1774 return -1;
1775 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301776 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001777 return -1;
1778 }
1779
1780 //
1781 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1782 return -1;
1783 if(Item.uDataType != QCBOR_TYPE_MAP) {
1784 return -1;
1785 }
1786
1787 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1788 return -1;
1789 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1790 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301791 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001792 return -1;
1793 }
1794
1795 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1796 return -1;
1797 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1798 Item.uLabelType != QCBOR_TYPE_INT64 ||
1799 Item.label.int64 != 64 ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301800 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001801 return -1;
1802 }
1803
1804 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1805 return -1;
1806 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1807 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301808 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001809 return -1;
1810 }
1811
1812 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1813 return -1;
1814 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1815 Item.uLabelType != QCBOR_TYPE_INT64 ||
1816 Item.label.int64 != -64 ||
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301817 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001818 return -1;
1819 }
1820
1821 return 0;
1822}
1823
1824
1825
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301826static 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 +08001827{
1828 QCBORItem Item;
1829 int nCBORError;
1830
1831 if((nCBORError = QCBORDecode_GetNext(pCtx, &Item))) return -1;
1832 if(Item.uDataType != uDataType) return -1;
1833 if(uNestingLevel > 0) {
1834 if(Item.uLabelType != QCBOR_TYPE_INT64 && Item.uLabelType != QCBOR_TYPE_UINT64) return -1;
1835 if(Item.uLabelType == QCBOR_TYPE_INT64) {
1836 if(Item.label.int64 != nLabel) return -1;
1837 } else {
Laurence Lundblade570fab52018-10-13 18:28:27 +08001838 if(Item.label.uint64 != (uint64_t)nLabel) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001839 }
1840 }
1841 if(Item.uNestingLevel != uNestingLevel) return -1;
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301842 if(Item.uNextNestLevel != uNextNest) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001843
1844 if(pItem) {
1845 *pItem = Item;
1846 }
1847 return 0;
1848}
1849
1850
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001851// Same code checks definite and indefinite length versions of the map
1852static int CheckCSRMaps(QCBORDecodeContext *pDC)
1853{
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301854 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 0, 1, 0, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001855
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301856 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -23, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001857
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301858 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -20, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001859
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301860 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -18, NULL)) return -1;
1861 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -17, NULL)) return -1;
1862 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -15, NULL)) return -1;
1863 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -16, NULL)) return -1;
1864 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 2, -14, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001865
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301866 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -19, NULL)) return -1;
1867 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 3, 4, -11, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001868
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301869 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 4, 3, -9, NULL)) return -1;
1870 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_BYTE_STRING, 3, 1, -10, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001871
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301872 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -22, NULL)) return -1;
1873 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 2, 0, -5, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001874
1875 if(QCBORDecode_Finish(pDC)) return -2;
1876
1877 return 0;
1878}
1879
1880
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001881/*
1882// cbor.me decoded output
1883{
1884 -23: {
1885 -20: {
1886 -18: "Organization",
1887 -17: "SSG",
1888 -15: "Confusion",
1889 -16: "San Diego",
1890 -14: "US"
1891 },
1892 -19: {
1893 -11: {
1894 -9: -7
1895 },
1896 -10: '\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\n'
1897 }
1898 },
1899 -22: {
1900 -5: -3
1901 }
1902}
1903 */
1904
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001905
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001906static uint8_t s_CSRInput[] = {
1907 0xa2, 0x36, 0xa2, 0x33, 0xa5, 0x31, 0x6c, 0x4f,
1908 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1909 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1910 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1911 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1912 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1913 0x55, 0x53, 0x32, 0xa2, 0x2a, 0xa1, 0x28, 0x26,
1914 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1915 0x07, 0x08, 0x09, 0x0a, 0x35, 0xa1, 0x24, 0x22};
1916
1917int NestedMapTest()
1918{
1919 QCBORDecodeContext DCtx;
1920
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301921 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_CSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001922
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001923 return CheckCSRMaps(&DCtx);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001924}
1925
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001926// Same map as above, but using indefinite lengths
1927static uint8_t s_CSRInputIndefLen[] = {
1928 0xbf, 0x36, 0xbf, 0x33, 0xbf, 0x31, 0x6c, 0x4f,
1929 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1930 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1931 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1932 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1933 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1934 0x55, 0x53, 0xff, 0x32, 0xbf, 0x2a, 0xbf, 0x28, 0x26, 0xff,
1935 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1936 0x07, 0x08, 0x09, 0x0a, 0xff, 0xff, 0x35, 0xbf, 0x24, 0x22, 0xff, 0xff};
1937
1938int NestedMapTestIndefLen()
1939{
1940 QCBORDecodeContext DCtx;
1941
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301942 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_CSRInputIndefLen), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001943
1944 return CheckCSRMaps(&DCtx);
1945}
1946
1947
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001948
Laurence Lundblade17ede402018-10-13 11:43:07 +08001949static UsefulBufC make_nested_indefinite_arrays(int n, UsefulBuf Storage)
1950{
1951 UsefulOutBuf UOB;
1952 UsefulOutBuf_Init(&UOB, Storage);
1953
1954 int i;
1955 for(i = 0; i < n; i++) {
1956 UsefulOutBuf_AppendByte(&UOB, 0x9f);
1957 }
1958
1959 for(i = 0; i < n; i++) {
1960 UsefulOutBuf_AppendByte(&UOB, 0xff);
1961 }
1962 return UsefulOutBuf_OutUBuf(&UOB);
1963}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001964
1965
Laurence Lundblade17ede402018-10-13 11:43:07 +08001966static int parse_indeflen_nested(UsefulBufC Nested, int nNestLevel)
1967{
1968 QCBORDecodeContext DC;
1969 QCBORDecode_Init(&DC, Nested, 0);
1970
1971 int j;
1972 for(j = 0; j < nNestLevel; j++) {
1973 QCBORItem Item;
1974 int nReturn = QCBORDecode_GetNext(&DC, &Item);
1975 if(j >= QCBOR_MAX_ARRAY_NESTING) {
1976 // Should be in error
1977 if(nReturn != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP) {
1978 return -4;
1979 } else {
1980 return 0; // Decoding doesn't recover after an error
1981 }
1982 } else {
1983 // Should be no error
1984 if(nReturn) {
1985 return -9; // Should not have got an error
1986 }
1987 }
1988 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1989 return -7;
1990 }
1991 }
1992 int nReturn = QCBORDecode_Finish(&DC);
1993 if(nReturn) {
1994 return -3;
1995 }
1996 return 0;
1997}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001998
1999
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302000int IndefiniteLengthNestTest()
Laurence Lundblade17ede402018-10-13 11:43:07 +08002001{
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302002 UsefulBuf_MAKE_STACK_UB(Storage, 50);
Laurence Lundblade17ede402018-10-13 11:43:07 +08002003 int i;
Laurence Lundblade6de37062018-10-15 12:22:42 +05302004 for(i=1; i < QCBOR_MAX_ARRAY_NESTING+4; i++) {
Laurence Lundblade17ede402018-10-13 11:43:07 +08002005 UsefulBufC Nested = make_nested_indefinite_arrays(i, Storage);
2006 int nReturn = parse_indeflen_nested(Nested, i);
2007 if(nReturn) {
2008 return nReturn;
2009 }
2010 }
2011 return 0;
2012}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002013
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002014
Laurence Lundblade6de37062018-10-15 12:22:42 +05302015
2016static const uint8_t pIndefiniteArray[] = {0x9f, 0x01, 0x82, 0x02, 0x03, 0xff}; // [1, [2, 3]]
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002017static const uint8_t pIndefiniteArrayBad1[] = {0x9f}; // No closing break
2018static const uint8_t pIndefiniteArrayBad2[] = {0x9f, 0x9f, 0x02, 0xff}; // Not enough closing breaks
2019static const uint8_t pIndefiniteArrayBad3[] = {0x9f, 0x02, 0xff, 0xff}; // Too many closing breaks
Laurence Lundblade570fab52018-10-13 18:28:27 +08002020static const uint8_t pIndefiniteArrayBad4[] = {0x81, 0x9f}; // Unclosed indeflen inside def len
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07002021static const uint8_t pIndefiniteArrayBad5[] = {0x9f, 0xd1, 0xff}; // confused tag
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002022
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302023int IndefiniteLengthArrayMapTest()
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002024{
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002025 int nResult;
2026 // --- first test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302027 UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArray);
Laurence Lundblade17ede402018-10-13 11:43:07 +08002028
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002029 // Decode it and see if it is OK
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302030 UsefulBuf_MAKE_STACK_UB(MemPool, 150);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002031 QCBORDecodeContext DC;
2032 QCBORItem Item;
2033 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2034
2035 QCBORDecode_SetMemPool(&DC, MemPool, false);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302036
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002037 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302038
2039 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
2040 Item.uNestingLevel != 0 ||
2041 Item.uNextNestLevel != 1) {
2042 return -111;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002043 }
2044
2045 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302046 if(Item.uDataType != QCBOR_TYPE_INT64 ||
2047 Item.uNestingLevel != 1 ||
2048 Item.uNextNestLevel != 1) {
2049 return -2;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002050 }
2051
2052 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302053 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
2054 Item.uNestingLevel != 1 ||
2055 Item.uNextNestLevel != 2) {
2056 return -3;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002057 }
2058
2059 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302060 if(Item.uDataType != QCBOR_TYPE_INT64 |
2061 Item.uNestingLevel != 2 ||
2062 Item.uNextNestLevel != 2) {
2063 return -4;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002064 }
2065
2066 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302067 if(Item.uDataType != QCBOR_TYPE_INT64 |
2068 Item.uNestingLevel != 2 ||
2069 Item.uNextNestLevel != 0) {
2070 return -5;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002071 }
2072
2073 if(QCBORDecode_Finish(&DC)) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302074 return -6;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002075 }
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002076
2077 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302078 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad1);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002079
2080 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2081
2082 QCBORDecode_SetMemPool(&DC, MemPool, false);
2083
2084 nResult = QCBORDecode_GetNext(&DC, &Item);
2085 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302086 return -7;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002087 }
2088
Laurence Lundblade570fab52018-10-13 18:28:27 +08002089 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302090 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
2091 return -8;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002092 }
2093
2094
2095 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302096 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad2);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002097
2098 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2099
2100 QCBORDecode_SetMemPool(&DC, MemPool, false);
2101
2102 nResult = QCBORDecode_GetNext(&DC, &Item);
2103 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302104 return -9;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002105 }
2106
2107 nResult = QCBORDecode_GetNext(&DC, &Item);
2108 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302109 return -10;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002110 }
2111
2112 nResult = QCBORDecode_GetNext(&DC, &Item);
2113 if(nResult || Item.uDataType != QCBOR_TYPE_INT64) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302114 return -11;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002115 }
2116
2117 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302118 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
2119 return -12;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002120 }
2121
2122
2123 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302124 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad3);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002125
2126 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2127
2128 QCBORDecode_SetMemPool(&DC, MemPool, false);
2129
2130 nResult = QCBORDecode_GetNext(&DC, &Item);
2131 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302132 return -13;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002133 }
2134
2135 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302136 if(nResult != QCBOR_ERR_BAD_BREAK) {
2137 return -14;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002138 }
Laurence Lundblade6de37062018-10-15 12:22:42 +05302139
Laurence Lundblade570fab52018-10-13 18:28:27 +08002140
2141 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302142 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad4);
Laurence Lundblade570fab52018-10-13 18:28:27 +08002143
2144 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2145
2146 QCBORDecode_SetMemPool(&DC, MemPool, false);
2147
2148 nResult = QCBORDecode_GetNext(&DC, &Item);
2149 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302150 return -15;
Laurence Lundblade570fab52018-10-13 18:28:27 +08002151 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302152
Laurence Lundblade570fab52018-10-13 18:28:27 +08002153 nResult = QCBORDecode_GetNext(&DC, &Item);
2154 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302155 return -16;
Laurence Lundblade570fab52018-10-13 18:28:27 +08002156 }
2157
2158 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302159 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
2160 return -17;
Laurence Lundblade570fab52018-10-13 18:28:27 +08002161 }
2162
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302163 // --- next test -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302164 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteArrayBad5);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302165
2166 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2167
2168 QCBORDecode_SetMemPool(&DC, MemPool, false);
2169
2170 nResult = QCBORDecode_GetNext(&DC, &Item);
2171 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302172 return -18;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302173 }
2174
2175 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302176 if(nResult != QCBOR_ERR_BAD_BREAK) {
2177 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302178 }
2179
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002180 return 0;
2181}
2182
Laurence Lundblade17ede402018-10-13 11:43:07 +08002183
2184static const uint8_t pIndefiniteLenString[] = {
2185 0x81, // Array of length one
2186 0x7f, // text string marked with indefinite length
2187 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
2188 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
2189 0xff // ending break
2190};
2191
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302192static const uint8_t pIndefiniteLenStringBad2[] = {
2193 0x81, // Array of length one
2194 0x7f, // text string marked with indefinite length
2195 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
2196 0x44, 0x6d, 0x69, 0x6e, 0x67, // second segment of wrong type
2197 0xff // ending break
2198};
2199
2200static const uint8_t pIndefiniteLenStringBad3[] = {
2201 0x81, // Array of length one
2202 0x7f, // text string marked with indefinite length
2203 0x01, 0x02, // Not a string
2204 0xff // ending break
2205};
2206
2207static const uint8_t pIndefiniteLenStringBad4[] = {
2208 0x81, // Array of length one
2209 0x7f, // text string marked with indefinite length
2210 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
2211 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
2212 // missing end of string
2213};
2214
2215static const uint8_t pIndefiniteLenStringLabel[] = {
2216 0xa1, // Array of length one
2217 0x7f, // text string marked with indefinite length
2218 0x65, 0x73, 0x74, 0x72, 0x75, 0x75, // first segment
2219 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
2220 0xff, // ending break
2221 0x01 // integer being labeled.
2222};
2223
2224static UsefulBufC MakeIndefiniteBigBstr(UsefulBuf Storage)
2225{
2226 UsefulOutBuf UOB;
2227
2228 UsefulOutBuf_Init(&UOB, Storage);
2229 UsefulOutBuf_AppendByte(&UOB, 0x81);
2230 UsefulOutBuf_AppendByte(&UOB, 0x5f);
2231
2232 int i = 0;
2233 for(int nChunkSize = 1; nChunkSize <= 128; nChunkSize *= 2) {
2234 UsefulOutBuf_AppendByte(&UOB, 0x58);
2235 UsefulOutBuf_AppendByte(&UOB, (uint8_t)nChunkSize);
2236 for(int j = 0; j < nChunkSize; j++ ) {
2237 UsefulOutBuf_AppendByte(&UOB, i);
2238 i++;
2239 }
2240 }
2241 UsefulOutBuf_AppendByte(&UOB, 0xff);
2242
2243 return UsefulOutBuf_OutUBuf(&UOB);
2244}
2245
2246static int CheckBigString(UsefulBufC BigString)
2247{
2248 if(BigString.len != 255) {
2249 return 1;
2250 }
2251
2252 for(uint8_t i = 0; i < 255; i++){
2253 if(((const uint8_t *)BigString.ptr)[i] != i) {
2254 return 1;
2255 }
2256 }
2257 return 0;
2258}
2259
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302260
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302261int IndefiniteLengthStringTest()
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302262{
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302263 QCBORDecodeContext DC;
2264 QCBORItem Item;
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302265 // big enough for MakeIndefiniteBigBstr() + MemPool overhead
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302266 UsefulBuf_MAKE_STACK_UB(MemPool, 320);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302267
2268 // --- Simple normal indefinite length string ------
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302269 UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenString);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302270 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002271
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302272 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302273 return -1;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302274 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002275
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302276 if(QCBORDecode_GetNext(&DC, &Item)) {
2277 return -2;
2278 }
2279 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
2280 return -3;
2281 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002282
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302283 if(QCBORDecode_GetNext(&DC, &Item)) {
2284 return -4;
2285 }
2286 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING || !Item.uDataAlloc) {
2287 return -5;
2288 }
2289 if(QCBORDecode_Finish(&DC)) {
2290 return -6;
2291 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302292
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302293 // ----- types mismatch ---
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302294 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenStringBad2), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302295
2296 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2297 return -7;
2298 }
2299
2300 if(QCBORDecode_GetNext(&DC, &Item)) {
2301 return -8;
2302 }
2303 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2304 return -9;
2305 }
2306
2307 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_SEG) {
2308 return -10;
2309 }
2310
2311 // ----- not a string ---
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302312 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenStringBad3), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302313
2314 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2315 return -11;
2316 }
2317
2318 if(QCBORDecode_GetNext(&DC, &Item)) {
2319 return -12;
2320 }
2321 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2322 return -13;
2323 }
2324
2325 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_SEG) {
2326 return -14;
2327 }
2328
2329 // ----- no end -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302330 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenStringBad4), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302331
2332 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2333 return -15;
2334 }
2335
2336 if(QCBORDecode_GetNext(&DC, &Item)) {
2337 return -16;
2338 }
2339 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2340 return -17;
2341 }
2342
2343 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_HIT_END) {
2344 return -18;
2345 }
2346
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302347 // ------ Don't set a string allocator and see an error -----
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302348 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2349
2350 QCBORDecode_GetNext(&DC, &Item);
2351 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302352 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302353 }
2354
2355 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_NO_STRING_ALLOCATOR) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302356 return -20;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302357 }
2358
2359 // ----- Mempool is way too small -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302360 UsefulBuf_MAKE_STACK_UB(MemPoolTooSmall, 20); // 20 is too small no matter what
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302361
2362 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2363 if(!QCBORDecode_SetMemPool(&DC, MemPoolTooSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302364 return -21;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302365 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302366
2367 // ----- Mempool is way too small -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302368 UsefulBuf_MAKE_STACK_UB(BigIndefBStrStorage, 290);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302369 UsefulBufC BigIndefBStr = MakeIndefiniteBigBstr(BigIndefBStrStorage);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302370
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302371 UsefulBuf_MAKE_STACK_UB(MemPoolSmall, 80); // 80 is big enough for MemPool overhead, but not BigIndefBStr
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302372
2373 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302374 if(QCBORDecode_SetMemPool(&DC, MemPoolSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302375 return -22;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302376 }
2377
2378 QCBORDecode_GetNext(&DC, &Item);
2379 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302380 return -23;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302381 }
2382 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_STRING_ALLOC) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302383 return -24;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302384 }
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302385
2386 // ---- big bstr -----
2387 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
2388
2389 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2390 return -25;
2391 }
2392
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302393 if(QCBORDecode_GetNext(&DC, &Item)) {
2394 return -26;
2395 }
2396 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302397 return -26;
2398 }
2399
2400 if(QCBORDecode_GetNext(&DC, &Item)) {
2401 return -27;
2402 }
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302403 if(Item.uDataType != QCBOR_TYPE_BYTE_STRING || !Item.uDataAlloc || Item.uNestingLevel != 1) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302404 return -28;
2405 }
2406 if(CheckBigString(Item.val.string)) {
2407 return -3;
2408 }
2409 if(QCBORDecode_Finish(&DC)) {
2410 return -29;
2411 }
2412
2413 // --- label is an indefinite length string ------
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302414 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pIndefiniteLenStringLabel), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302415
2416 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2417 return -30;
2418 }
2419
2420 QCBORDecode_GetNext(&DC, &Item);
2421 if(Item.uDataType != QCBOR_TYPE_MAP) {
2422 return -31;
2423 }
2424
2425 if(QCBORDecode_GetNext(&DC, &Item)){
2426 return -32;
2427 }
2428 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING || Item.uDataType != QCBOR_TYPE_INT64 ||
2429 Item.uDataAlloc || !Item.uLabelAlloc ||
2430 UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("struuming"))) {
2431 return -33;
2432 }
2433
2434 if(QCBORDecode_Finish(&DC)) {
2435 return -34;
2436 }
2437
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002438 return 0;
2439}
2440
2441
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302442int AllocAllStringsTest()
2443{
2444 QCBORDecodeContext DC;
2445
2446 // First test, use the "CSRMap" as easy input and checking
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302447 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(s_CSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302448
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302449 UsefulBuf_MAKE_STACK_UB(Pool, 300);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302450
2451 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2452
2453 if(CheckCSRMaps(&DC)) {
2454 return -1;
2455 }
2456
2457 // Next parse, save pointers to a few strings, destroy original and see all is OK.
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302458 UsefulBuf_MAKE_STACK_UB(CopyOfStorage, 160);
2459 UsefulBufC CopyOf = UsefulBuf_Copy(CopyOfStorage, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded));
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002460
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302461 QCBORDecode_Init(&DC, CopyOf, QCBOR_DECODE_MODE_NORMAL);
2462 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2463
2464 int nCBORError;
2465 QCBORItem Item1, Item2, Item3, Item4;
2466 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2467 return nCBORError;
2468 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2469 Item1.val.uCount != 3)
2470 return -1;
2471 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2472 return nCBORError;
2473 if((nCBORError = QCBORDecode_GetNext(&DC, &Item2)))
2474 return nCBORError;
2475 if((nCBORError = QCBORDecode_GetNext(&DC, &Item3)))
2476 return nCBORError;
2477 if((nCBORError = QCBORDecode_GetNext(&DC, &Item4)))
2478 return nCBORError;
2479
Laurence Lundblade05ec57b2018-10-21 01:50:03 +05302480 UsefulBuf_Set(CopyOfStorage, '_');
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302481
2482 if(Item1.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2483 Item1.label.string.len != 13 ||
2484 Item1.uDataType != QCBOR_TYPE_INT64 ||
2485 Item1.val.int64 != 42 ||
2486 memcmp(Item1.label.string.ptr, "first integer", 13))
2487 return -1;
2488
2489
2490 if(Item2.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2491 Item2.label.string.len != 23 ||
2492 memcmp(Item2.label.string.ptr, "an array of two strings", 23) ||
2493 Item2.uDataType != QCBOR_TYPE_ARRAY ||
2494 Item2.val.uCount != 2)
2495 return -1;
2496
2497 if(Item3.uDataType != QCBOR_TYPE_TEXT_STRING ||
2498 Item3.val.string.len != 7 ||
2499 memcmp(Item3.val.string.ptr, "string1", 7))
2500 return -1;
2501
2502 if(Item4.uDataType != QCBOR_TYPE_TEXT_STRING ||
2503 Item4.val.string.len != 7 ||
2504 memcmp(Item4.val.string.ptr, "string2", 7))
2505 return -1;
2506
2507 // Next parse with a pool that is too small
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302508 UsefulBuf_MAKE_STACK_UB(SmallPool, 80);
2509 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302510 QCBORDecode_SetMemPool(&DC, SmallPool, 1); // Turn on copying.
2511 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2512 return nCBORError;
2513 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2514 Item1.val.uCount != 3)
2515 return -1;
2516 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item1))){
2517 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item2))) {
2518 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item3))) {
2519 nCBORError = QCBORDecode_GetNext(&DC, &Item4);
2520 }
2521 }
2522 }
2523 if(nCBORError != QCBOR_ERR_STRING_ALLOC) {
2524 return -5;
2525 }
2526
2527 return 0;
2528}
2529
2530
2531int MemPoolTest(void)
Laurence Lundblade0155b622018-10-12 20:04:37 +08002532{
2533 QCBORDecodeContext DC;
2534
2535 const uint8_t pMinimalCBOR[] = {0xa0}; // One empty map
2536
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302537 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pMinimalCBOR),0);
Laurence Lundblade0155b622018-10-12 20:04:37 +08002538
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302539 UsefulBuf_MAKE_STACK_UB(Pool, 100);
Laurence Lundblade0155b622018-10-12 20:04:37 +08002540
2541 QCBORDecode_SetMemPool(&DC, Pool, 0);
2542
2543 // Cheat a little to get to the string allocator object
2544 // so we can call it directly to test it
2545 QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2546
2547 // Ask for too much in one go
2548 // 90 < 100, but there is some overhead taken out of the 100
2549 UsefulBuf Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 90);
2550 if(!UsefulBuf_IsNULL(Allocated)) {
2551 return -1;
2552 }
2553
2554
2555
2556 QCBORDecode_SetMemPool(&DC, Pool, 0);
2557
2558 // Cheat a little to get to the string allocator object
2559 // so we can call it directly to test it
2560 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2561
2562 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2563 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2564 return -1;
2565 }
2566 UsefulBuf Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2567 if(!UsefulBuf_IsNULL(Allocated2)) { // expected to fail
2568 return -1;
2569 }
2570 (*pAlloc->fFree)(pAlloc->pAllocaterContext, Allocated.ptr);
2571 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2572 if(UsefulBuf_IsNULL(Allocated)) { // succeed because of the free
2573 return -1;
2574 }
2575
2576
2577 QCBORDecode_SetMemPool(&DC, Pool, 0);
2578
2579 // Cheat a little to get to the string allocator object
2580 // so we can call it directly to test it
2581 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2582 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 20);
2583 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2584 return -1;
2585 }
2586 Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, 25);
2587 if(UsefulBuf_IsNULL(Allocated2)) { // expected to fail
2588 return -1;
2589 }
2590 if(Allocated2.ptr != Allocated.ptr || Allocated2.len != 25) {
2591 return -1;
2592 }
2593
Laurence Lundblade0155b622018-10-12 20:04:37 +08002594 return 0;
2595}
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002596
2597
2598
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08002599
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002600
2601