blob: 0cbb51cfb53ae43e07c8e53ad5cd60a50a84d453 [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 ||
606 bcmp("galactic", s3, 8) !=0 ||
607 bcmp("haven token", s4, 11) !=0) {
608 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
729
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800730static int ParseMapTest1()
731{
732 QCBORDecodeContext DCtx;
733 QCBORItem Item;
734 int nCBORError;
735
736
737 QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
738
739 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
740 return nCBORError;
741 if(Item.uDataType != QCBOR_TYPE_MAP ||
742 Item.val.uCount != 3)
743 return -1;
744
745
746
747 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 ||
753 memcmp(Item.label.string.ptr, "first integer", 13))
754 return -1;
755
756 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
757 return nCBORError;
758 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
759 Item.label.string.len != 23 ||
760 memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
761 Item.uDataType != QCBOR_TYPE_ARRAY ||
762 Item.val.uCount != 2)
763 return -1;
764
765 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
766 return nCBORError;
767 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
768 Item.val.string.len != 7 ||
769 memcmp(Item.val.string.ptr, "string1", 7))
770 return -1;
771
772 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
773 return nCBORError;
774 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
775 Item.val.string.len != 7 ||
776 memcmp(Item.val.string.ptr, "string2", 7))
777 return -1;
778
779 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
780 return nCBORError;
781 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
782 Item.label.string.len != 12 ||
783 memcmp(Item.label.string.ptr, "map in a map", 12) ||
784 Item.uDataType != QCBOR_TYPE_MAP ||
785 Item.val.uCount != 4)
786 return -1;
787
788 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
789 return nCBORError;
790 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
791 Item.label.string.len != 7 ||
792 memcmp(Item.label.string.ptr, "bytes 1", 7)||
793 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
794 Item.val.string.len != 4 ||
795 memcmp(Item.val.string.ptr, "xxxx", 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 2", 7) ||
803 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
804 Item.val.string.len != 4 ||
805 memcmp(Item.val.string.ptr, "yyyy", 4))
806 return -1;
807
808 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
809 return nCBORError;
810 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
811 Item.label.string.len != 11 ||
812 memcmp(Item.label.string.ptr, "another int", 11) ||
813 Item.uDataType != QCBOR_TYPE_INT64 ||
814 Item.val.int64 != 98)
815 return -1;
816
817 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
818 return nCBORError;
819 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
820 Item.label.string.len != 6 ||
821 memcmp(Item.label.string.ptr, "text 2", 6)||
822 Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
823 Item.val.string.len != 30 ||
824 memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
825 return -1;
826
827 return 0;
828}
829
830
831
832/*
833 This test parses pValidMapEncoded and checks for extra bytes along the way
834 */
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800835static int ExtraBytesTest(int nLevel)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800836{
837 QCBORDecodeContext DCtx;
838 QCBORItem Item;
839 int nCBORError;
840
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800841 QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
842
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800843 if(nLevel < 1) {
844 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
845 return -1;
846 } else {
847 return 0;
848 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800849 }
850
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800851
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800852 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
853 return nCBORError;
854 if(Item.uDataType != QCBOR_TYPE_MAP ||
855 Item.val.uCount != 3)
856 return -1;
857
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800858 if(nLevel < 2) {
859 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
860 return -1;
861 } else {
862 return 0;
863 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800864 }
865
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800866
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800867 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
868 return nCBORError;
869 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
870 Item.label.string.len != 13 ||
871 Item.uDataType != QCBOR_TYPE_INT64 ||
872 Item.val.uCount != 42 ||
873 memcmp(Item.label.string.ptr, "first integer", 13))
874 return -1;
875
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800876 if(nLevel < 3) {
877 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
878 return -1;
879 } else {
880 return 0;
881 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800882 }
883
884 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
885 return nCBORError;
886 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
887 Item.label.string.len != 23 ||
888 memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
889 Item.uDataType != QCBOR_TYPE_ARRAY ||
890 Item.val.uCount != 2)
891 return -1;
892
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800893
894 if(nLevel < 4) {
895 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
896 return -1;
897 } else {
898 return 0;
899 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800900 }
901
902
903 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
904 return nCBORError;
905 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
906 Item.val.string.len != 7 ||
907 memcmp(Item.val.string.ptr, "string1", 7))
908 return -1;
909
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800910 if(nLevel < 5) {
911 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
912 return -1;
913 } else {
914 return 0;
915 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800916 }
917
918 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
919 return nCBORError;
920 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
921 Item.val.string.len != 7 ||
922 memcmp(Item.val.string.ptr, "string2", 7))
923 return -1;
924
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800925 if(nLevel < 6) {
926 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
927 return -1;
928 } else {
929 return 0;
930 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800931 }
932
933 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
934 return nCBORError;
935 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
936 Item.label.string.len != 12 ||
937 memcmp(Item.label.string.ptr, "map in a map", 12) ||
938 Item.uDataType != QCBOR_TYPE_MAP ||
939 Item.val.uCount != 4)
940 return -1;
941
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800942 if(nLevel < 7) {
943 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
944 return -1;
945 } else {
946 return 0;
947 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800948 }
949
950 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
951 return nCBORError;
952 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
953 Item.label.string.len != 7 ||
954 memcmp(Item.label.string.ptr, "bytes 1", 7)||
955 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
956 Item.val.string.len != 4 ||
957 memcmp(Item.val.string.ptr, "xxxx", 4))
958 return -1;
959
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800960 if(nLevel < 8) {
961 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
962 return -1;
963 } else {
964 return 0;
965 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800966 }
967
968 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
969 return nCBORError;
970 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
971 Item.label.string.len != 7 ||
972 memcmp(Item.label.string.ptr, "bytes 2", 7) ||
973 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
974 Item.val.string.len != 4 ||
975 memcmp(Item.val.string.ptr, "yyyy", 4))
976 return -1;
977
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800978 if(nLevel < 9) {
979 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
980 return -1;
981 } else {
982 return 0;
983 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800984 }
985
986 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
987 return nCBORError;
988 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
989 Item.label.string.len != 11 ||
990 memcmp(Item.label.string.ptr, "another int", 11) ||
991 Item.uDataType != QCBOR_TYPE_INT64 ||
992 Item.val.int64 != 98)
993 return -1;
994
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800995 if(nLevel < 10) {
996 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
997 return -1;
998 } else {
999 return 0;
1000 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001001 }
1002
1003 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1004 return nCBORError;
1005 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
1006 Item.label.string.len != 6 ||
1007 memcmp(Item.label.string.ptr, "text 2", 6)||
1008 Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1009 Item.val.string.len != 30 ||
1010 memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
1011 return -1;
1012
1013 if(QCBORDecode_Finish(&DCtx) == QCBOR_ERR_EXTRA_BYTES) {
1014 return -1;
1015 }
1016
1017 return 0;
1018}
1019
1020
1021
1022
1023int ParseMapTest()
1024{
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +08001025 int n = ParseMapTest1(); // TODO: review this test carefully
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001026
1027 if(!n) {
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +08001028 for(int i = 0; i < 10; i++) {
1029 n = ExtraBytesTest(i);
1030 if(n) {
1031 break;
1032 }
1033 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001034 }
1035
1036 return(n);
1037}
1038
1039
1040static uint8_t s_pSimpleValues[] = {0x8a, 0xf4, 0xf5, 0xf6, 0xf7, 0xff, 0xe0, 0xf3, 0xf8, 0x00, 0xf8, 0x13, 0xf8, 0x1f, 0xf8, 0x20, 0xf8, 0xff};
1041
1042int ParseSimpleTest()
1043{
1044 QCBORDecodeContext DCtx;
1045 QCBORItem Item;
1046 int nCBORError;
1047
1048
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001049 QCBORDecode_Init(&DCtx, UsefulBuf_FromByteArrayLiteral(s_pSimpleValues), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001050
1051
1052 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1053 return nCBORError;
1054 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1055 Item.val.uCount != 10)
1056 return -1;
1057
1058 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1059 return nCBORError;
1060 if(Item.uDataType != QCBOR_TYPE_FALSE)
1061 return -1;
1062
1063 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1064 return nCBORError;
1065 if(Item.uDataType != QCBOR_TYPE_TRUE)
1066 return -1;
1067
1068 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1069 return nCBORError;
1070 if(Item.uDataType != QCBOR_TYPE_NULL)
1071 return -1;
1072
1073 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1074 return nCBORError;
1075 if(Item.uDataType != QCBOR_TYPE_UNDEF)
1076 return -1;
1077
1078 // A break
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001079 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_BAD_BREAK)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001080 return -1;
1081
1082 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1083 return nCBORError;
1084 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 0)
1085 return -1;
1086
1087 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1088 return nCBORError;
1089 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 19)
1090 return -1;
1091
1092 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
1093 return -1;
1094
1095 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
1096 return -1;
1097
1098 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
1099 return -1;
1100
1101 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1102 return nCBORError;
1103 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 32)
1104 return -1;
1105
1106 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1107 return nCBORError;
1108 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 255)
1109 return -1;
1110
1111 return 0;
1112
1113}
1114
1115
1116struct FailInput {
1117 UsefulBufC Input;
1118 int nError;
1119};
1120
1121
1122struct FailInput Failures[] = {
1123 { {(uint8_t[]){0x18}, 1}, QCBOR_ERR_HIT_END }, // 1 byte integer missing the byte
1124 { {(uint8_t[]){0x1c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1125 { {(uint8_t[]){0x1d}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 29
1126 { {(uint8_t[]){0x1e}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 30
1127 { {(uint8_t[]){0x1f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length integer
1128 { {(uint8_t[]){0x3c}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1129 { {(uint8_t[]){0x3d}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1130 { {(uint8_t[]){0x3e}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1131 { {(uint8_t[]){0x3f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length negative integer
1132 { {(uint8_t[]){0x41}, 1}, QCBOR_ERR_HIT_END }, // Short byte string
1133 { {(uint8_t[]){0x5c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1134 { {(uint8_t[]){0x5f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length byte string
1135 { {(uint8_t[]){0x61}, 1}, QCBOR_ERR_HIT_END }, // Short UTF-8 string
1136 { {(uint8_t[]){0x7c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1137 { {(uint8_t[]){0x7f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length UTF-8 string
1138 { {(uint8_t[]){0xff}, 1}, QCBOR_ERR_UNSUPPORTED } , // break
1139 { {(uint8_t[]){0xf8, 0x00}, 2}, QCBOR_ERR_INVALID_CBOR }, // An invalid encoding of a simple type
1140 { {(uint8_t[]){0xf8, 0x1f}, 2}, QCBOR_ERR_INVALID_CBOR }, // An invalid encoding of a simple type
1141 { {(uint8_t[]){0xc0, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG }, // Text-based date, with an integer
1142 { {(uint8_t[]){0xc1, 0x41, 0x33}, 3}, QCBOR_ERR_BAD_OPT_TAG }, // Epoch date, with an byte string
1143 { {(uint8_t[]){0xc1, 0xc0, 0x00}, 3}, QCBOR_ERR_BAD_OPT_TAG }, // tagged as both epoch and string dates
1144 { {(uint8_t[]){0xc2, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG } // big num tagged an int, not a byte string
1145
1146};
1147
1148
1149void Dump(UsefulBufC Input, int x)
1150{
1151 char label[10];
1152
1153 sprintf(label, "%d", x);
1154
1155 printencoded(label, Input.ptr, Input.len);
1156}
1157
1158
1159int FailureTests()
1160{
1161 int nResult = 0;
1162
1163 struct FailInput *pFEnd = &Failures[0] + sizeof(Failures)/sizeof(struct FailInput);
1164
1165 for(struct FailInput *pF = &Failures[0]; pF < pFEnd ;pF++) {
1166 QCBORDecodeContext DCtx;
1167 QCBORItem Item;
1168 int nCBORError;
1169
1170 QCBORDecode_Init(&DCtx, pF->Input, QCBOR_DECODE_MODE_NORMAL);
1171
1172 while(1) {
1173 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1174 if(QCBOR_ERR_HIT_END == nCBORError) {
1175 break;
1176 }
1177 if(nCBORError != pF->nError) {
1178 nResult = 1;
1179 // Dump(pF->Input, nCBORError);
1180 break;
1181 }
1182 }
1183 }
1184
1185 {
1186 QCBORDecodeContext DCtx;
1187 QCBORItem Item;
1188 int nCBORError;
1189
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001190 QCBORDecode_Init(&DCtx, UsefulBuf_FromByteArrayLiteral(s_pSimpleValues), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001191
1192 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1193 return nCBORError;
1194 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1195 Item.val.uCount != 10)
1196 return -1;
1197
1198 DCtx.InBuf.magic = 0; // Corrupt the UsefulInputBuf
1199
1200 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1201 if(nCBORError != QCBOR_ERR_HIT_END)
1202 return -1;
1203 }
1204
1205
1206 return nResult;
1207}
1208
1209
1210
1211
1212static void Recurser(uint8_t *pBuf, int nLen, int nLenMax)
1213{
1214
1215 if(nLen >= nLenMax) {
1216 return;
1217 }
1218
1219 //printf("__%d__%d__\n", nLen, nLenMax);
1220
1221 for(int i = 0; i < 256; i++) {
1222 pBuf[nLen] = i;
1223
1224 QCBORDecodeContext DCtx;
1225 QCBORItem Item;
1226 int nCBORError;
1227
1228 UsefulBufC Input = {pBuf, nLen+1};
1229
1230 QCBORDecode_Init(&DCtx, Input, QCBOR_DECODE_MODE_NORMAL);
1231
1232 while(1) {
1233 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1234 if(QCBOR_ERR_HIT_END == nCBORError) {
1235 break;
1236 }
1237 if(nCBORError != QCBOR_SUCCESS) {
1238 if(nCBORError != QCBOR_ERR_UNSUPPORTED && nCBORError != QCBOR_ERR_HIT_END && nCBORError != QCBOR_ERR_INVALID_CBOR) {
1239 //Dump(Input, nCBORError);
1240 }
1241 break;
1242 }
1243 }
1244 //Dump(Input, -1);
1245
1246
1247 Recurser(pBuf, nLen+1, nLenMax);
1248 }
1249}
1250
1251
1252/*
1253 Runs all possible input strings of a given length. This is set to 3 to make the test
1254 run in reasonable time.
1255 Main point of this test is to not crash.
1256 */
1257
1258int ComprehensiveInputTest()
1259{
1260 uint8_t pBuf[3]; // 3 keeps it running in reasonable time. 4 takes tens of minutes.
1261
1262 Recurser(pBuf, 0, sizeof(pBuf));
1263
1264 return 0;
1265}
1266
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001267static uint8_t s_DateTestInput[] = {
1268 0xc0, // tag for string date
1269 0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
1270
1271 0xc1, // tag for epoch date
1272 0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
1273
1274 0xc1, 0xcf, 0xd8, 0xee, // Epoch date with extra tags
1275 0x1a, 0x53, 0x72, 0x4E, 0x01,
1276
1277 0xc1, // tag for epoch date
1278 0x1b, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // Too large integer
1279
1280 0xc1, // tag for epoch date
1281 0xfa, 0x3f, 0x8c, 0xcc, 0xcd, // double with value 1.1
1282
1283 0xc1, // tag for epoch date
1284 0xfa, 0x7f, 0x7f, 0xff, 0xff // 3.4028234663852886e+38 too large
1285
1286};
1287
1288
1289// have to check float expected only to within an epsilon
1290int CHECK_EXPECTED_DOUBLE(double val, double expected) {
1291
1292 double diff = val - expected;
1293
1294 diff = fabs(diff);
1295
1296 return diff > 0.0000001;
1297}
1298
1299
1300int DateParseTest()
1301{
1302 QCBORDecodeContext DCtx;
1303 QCBORItem Item;
1304 int nCBORError;
1305
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001306 QCBORDecode_Init(&DCtx, UsefulBuf_FromByteArrayLiteral(s_DateTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001307
1308 // String date
1309 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1310 return -1;
1311 if(Item.uDataType != QCBOR_TYPE_DATE_STRING ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001312 UsefulBuf_Compare(Item.val.dateString, UsefulBuf_FromSZ("1985-04-12"))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001313 return -1;
1314 }
1315
1316 // Epoch date
1317 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1318 return -1;
1319 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1320 Item.val.epochDate.nSeconds != 1400000000 ||
1321 Item.val.epochDate.fSecondsFraction != 0 ) {
1322 return -1;
1323 }
1324
1325 // Epoch date with extra tags
1326 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1327 return -1;
1328 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1329 Item.val.epochDate.nSeconds != 1400000001 ||
1330 Item.val.epochDate.fSecondsFraction != 0 ||
1331 Item.uTagBits != (0x02 | (0x01 << 0x0f)) ||
1332 Item.uTag != 0xee) {
1333 return -1;
1334 }
1335
1336 // Epoch date that is too large for our representation
1337 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
1338 return -1;
1339 }
1340
1341 // Epoch date in float format with fractional seconds
1342 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1343 return -1;
1344 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1345 Item.val.epochDate.nSeconds != 1 ||
1346 CHECK_EXPECTED_DOUBLE(Item.val.epochDate.fSecondsFraction, 0.1 )) {
1347 return -1;
1348 }
1349
1350 // Epoch date float that is too large for our representation
1351 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
1352 return -1;
1353 }
1354
1355 // TODO: could use a few more tests with float, double, and half precsion and negative (but coverage is still pretty good)
1356
1357 return 0;
1358}
1359
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001360static uint8_t s_OptTestInput[] = {
1361 0xd9, 0xd9, 0xf7, // CBOR magic number
1362 0x81,
1363 0xd8, 62, // 62 is decimal intentionally
1364 0x00};
1365
1366int OptTagParseTest()
1367{
1368 QCBORDecodeContext DCtx;
1369 QCBORItem Item;
1370 int nCBORError;
1371
1372
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001373 QCBORDecode_Init(&DCtx, UsefulBuf_FromByteArrayLiteral(s_OptTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001374
1375 //
1376 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1377 return -1;
1378 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1379 Item.uTagBits != QCBOR_TAGFLAG_CBOR_MAGIC) {
1380 return -1;
1381 }
1382
1383 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1384 return -1;
1385 if(Item.uDataType != QCBOR_TYPE_INT64 ||
1386 Item.uTagBits != (0x01LL << 62) ||
1387 Item.val.int64 != 0)
1388 return -1;
1389
1390 return 0;
1391}
1392
1393
1394
1395
1396static uint8_t s_BigNumInput[] = {
1397 0x83,
1398 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1399 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1400 0xA4,
1401 0x63, 0x42, 0x4E, 0x2B,
1402 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1403 0x18, 0x40,
1404 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1405 0x63, 0x42, 0x4E, 0x2D,
1406 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1407 0x38, 0x3F,
1408 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1409
1410
1411static uint8_t sBigNum[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1412
1413
1414int BignumParseTest()
1415{
1416 QCBORDecodeContext DCtx;
1417 QCBORItem Item;
1418 int nCBORError;
1419
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001420 QCBORDecode_Init(&DCtx, UsefulBuf_FromByteArrayLiteral(s_BigNumInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001421
1422
1423 //
1424 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1425 return -1;
1426 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1427 return -1;
1428 }
1429
1430 //
1431 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1432 return -1;
1433 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001434 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FromByteArrayLiteral(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001435 return -1;
1436 }
1437
1438 //
1439 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1440 return -1;
1441 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001442 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FromByteArrayLiteral(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001443 return -1;
1444 }
1445
1446 //
1447 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1448 return -1;
1449 if(Item.uDataType != QCBOR_TYPE_MAP) {
1450 return -1;
1451 }
1452
1453 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1454 return -1;
1455 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1456 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001457 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FromByteArrayLiteral(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001458 return -1;
1459 }
1460
1461 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1462 return -1;
1463 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1464 Item.uLabelType != QCBOR_TYPE_INT64 ||
1465 Item.label.int64 != 64 ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001466 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FromByteArrayLiteral(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001467 return -1;
1468 }
1469
1470 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1471 return -1;
1472 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1473 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001474 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FromByteArrayLiteral(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001475 return -1;
1476 }
1477
1478 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1479 return -1;
1480 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1481 Item.uLabelType != QCBOR_TYPE_INT64 ||
1482 Item.label.int64 != -64 ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001483 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FromByteArrayLiteral(sBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001484 return -1;
1485 }
1486
1487 return 0;
1488}
1489
1490
1491
1492static int CheckItemWithIntLabel(QCBORDecodeContext *pCtx, uint8_t uDataType, uint8_t uNestingLevel, int64_t nLabel, QCBORItem *pItem)
1493{
1494 QCBORItem Item;
1495 int nCBORError;
1496
1497 if((nCBORError = QCBORDecode_GetNext(pCtx, &Item))) return -1;
1498 if(Item.uDataType != uDataType) return -1;
1499 if(uNestingLevel > 0) {
1500 if(Item.uLabelType != QCBOR_TYPE_INT64 && Item.uLabelType != QCBOR_TYPE_UINT64) return -1;
1501 if(Item.uLabelType == QCBOR_TYPE_INT64) {
1502 if(Item.label.int64 != nLabel) return -1;
1503 } else {
Laurence Lundblade570fab52018-10-13 18:28:27 +08001504 if(Item.label.uint64 != (uint64_t)nLabel) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001505 }
1506 }
1507 if(Item.uNestingLevel != uNestingLevel) return -1;
1508
1509 if(pItem) {
1510 *pItem = Item;
1511 }
1512 return 0;
1513}
1514
1515
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001516// Same code checks definite and indefinite length versions of the map
1517static int CheckCSRMaps(QCBORDecodeContext *pDC)
1518{
1519 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 0, 0, NULL)) return -1;
1520
1521 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, -23, NULL)) return -1;
1522
1523 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, -20, NULL)) return -1;
1524
1525 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, -18, NULL)) return -1;
1526 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, -17, NULL)) return -1;
1527 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, -15, NULL)) return -1;
1528 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, -16, NULL)) return -1;
1529 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, -14, NULL)) return -1;
1530
1531 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, -19, NULL)) return -1;
1532 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 3, -11, NULL)) return -1;
1533
1534 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 4, -9, NULL)) return -1;
1535 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_BYTE_STRING, 3, -10, NULL)) return -1;
1536
1537 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, -22, NULL)) return -1;
1538 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 2, -5, NULL)) return -1;
1539
1540 if(QCBORDecode_Finish(pDC)) return -2;
1541
1542 return 0;
1543}
1544
1545
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001546/*
1547// cbor.me decoded output
1548{
1549 -23: {
1550 -20: {
1551 -18: "Organization",
1552 -17: "SSG",
1553 -15: "Confusion",
1554 -16: "San Diego",
1555 -14: "US"
1556 },
1557 -19: {
1558 -11: {
1559 -9: -7
1560 },
1561 -10: '\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\n'
1562 }
1563 },
1564 -22: {
1565 -5: -3
1566 }
1567}
1568 */
1569
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001570
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001571static uint8_t s_CSRInput[] = {
1572 0xa2, 0x36, 0xa2, 0x33, 0xa5, 0x31, 0x6c, 0x4f,
1573 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1574 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1575 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1576 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1577 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1578 0x55, 0x53, 0x32, 0xa2, 0x2a, 0xa1, 0x28, 0x26,
1579 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1580 0x07, 0x08, 0x09, 0x0a, 0x35, 0xa1, 0x24, 0x22};
1581
1582int NestedMapTest()
1583{
1584 QCBORDecodeContext DCtx;
1585
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001586 QCBORDecode_Init(&DCtx, UsefulBuf_FromByteArrayLiteral(s_CSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001587
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001588 return CheckCSRMaps(&DCtx);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001589}
1590
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001591// Same map as above, but using indefinite lengths
1592static uint8_t s_CSRInputIndefLen[] = {
1593 0xbf, 0x36, 0xbf, 0x33, 0xbf, 0x31, 0x6c, 0x4f,
1594 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1595 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1596 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1597 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1598 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1599 0x55, 0x53, 0xff, 0x32, 0xbf, 0x2a, 0xbf, 0x28, 0x26, 0xff,
1600 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1601 0x07, 0x08, 0x09, 0x0a, 0xff, 0xff, 0x35, 0xbf, 0x24, 0x22, 0xff, 0xff};
1602
1603int NestedMapTestIndefLen()
1604{
1605 QCBORDecodeContext DCtx;
1606
1607 QCBORDecode_Init(&DCtx, UsefulBuf_FromByteArrayLiteral(s_CSRInputIndefLen), QCBOR_DECODE_MODE_NORMAL);
1608
1609 return CheckCSRMaps(&DCtx);
1610}
1611
1612
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001613
Laurence Lundblade17ede402018-10-13 11:43:07 +08001614static UsefulBufC make_nested_indefinite_arrays(int n, UsefulBuf Storage)
1615{
1616 UsefulOutBuf UOB;
1617 UsefulOutBuf_Init(&UOB, Storage);
1618
1619 int i;
1620 for(i = 0; i < n; i++) {
1621 UsefulOutBuf_AppendByte(&UOB, 0x9f);
1622 }
1623
1624 for(i = 0; i < n; i++) {
1625 UsefulOutBuf_AppendByte(&UOB, 0xff);
1626 }
1627 return UsefulOutBuf_OutUBuf(&UOB);
1628}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001629
1630
Laurence Lundblade17ede402018-10-13 11:43:07 +08001631static int parse_indeflen_nested(UsefulBufC Nested, int nNestLevel)
1632{
1633 QCBORDecodeContext DC;
1634 QCBORDecode_Init(&DC, Nested, 0);
1635
1636 int j;
1637 for(j = 0; j < nNestLevel; j++) {
1638 QCBORItem Item;
1639 int nReturn = QCBORDecode_GetNext(&DC, &Item);
1640 if(j >= QCBOR_MAX_ARRAY_NESTING) {
1641 // Should be in error
1642 if(nReturn != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP) {
1643 return -4;
1644 } else {
1645 return 0; // Decoding doesn't recover after an error
1646 }
1647 } else {
1648 // Should be no error
1649 if(nReturn) {
1650 return -9; // Should not have got an error
1651 }
1652 }
1653 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1654 return -7;
1655 }
1656 }
1657 int nReturn = QCBORDecode_Finish(&DC);
1658 if(nReturn) {
1659 return -3;
1660 }
1661 return 0;
1662}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001663
1664
Laurence Lundblade17ede402018-10-13 11:43:07 +08001665int indeflen_nest_test()
1666{
1667 UsefulBuf_MakeStackUB(Storage, 50);
1668 int i;
Laurence Lundblade6de37062018-10-15 12:22:42 +05301669 for(i=1; i < QCBOR_MAX_ARRAY_NESTING+4; i++) {
Laurence Lundblade17ede402018-10-13 11:43:07 +08001670 UsefulBufC Nested = make_nested_indefinite_arrays(i, Storage);
1671 int nReturn = parse_indeflen_nested(Nested, i);
1672 if(nReturn) {
1673 return nReturn;
1674 }
1675 }
1676 return 0;
1677}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001678
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001679
Laurence Lundblade6de37062018-10-15 12:22:42 +05301680
1681static const uint8_t pIndefiniteArray[] = {0x9f, 0x01, 0x82, 0x02, 0x03, 0xff}; // [1, [2, 3]]
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001682static const uint8_t pIndefiniteArrayBad1[] = {0x9f}; // No closing break
1683static const uint8_t pIndefiniteArrayBad2[] = {0x9f, 0x9f, 0x02, 0xff}; // Not enough closing breaks
1684static const uint8_t pIndefiniteArrayBad3[] = {0x9f, 0x02, 0xff, 0xff}; // Too many closing breaks
Laurence Lundblade570fab52018-10-13 18:28:27 +08001685static const uint8_t pIndefiniteArrayBad4[] = {0x81, 0x9f}; // Unclosed indeflen inside def len
Laurence Lundblade6de37062018-10-15 12:22:42 +05301686static const uint8_t pIndefiniteArrayBad5[] = {0x9f, 0xc7, 0xff}; // confused tag
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001687
1688int indefinite_length_decode_test()
1689{
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001690 int nResult;
1691 // --- first test -----
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001692 UsefulBufC IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArray);
Laurence Lundblade17ede402018-10-13 11:43:07 +08001693
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001694 // Decode it and see if it is OK
Laurence Lundblade6de37062018-10-15 12:22:42 +05301695 UsefulBuf_MakeStackUB(MemPool, 150);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001696 QCBORDecodeContext DC;
1697 QCBORItem Item;
1698 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1699
1700 QCBORDecode_SetMemPool(&DC, MemPool, false);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301701
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001702 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301703
1704 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1705 Item.uNestingLevel != 0 ||
1706 Item.uNextNestLevel != 1) {
1707 return -111;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001708 }
1709
1710 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301711 if(Item.uDataType != QCBOR_TYPE_INT64 ||
1712 Item.uNestingLevel != 1 ||
1713 Item.uNextNestLevel != 1) {
1714 return -2;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001715 }
1716
1717 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301718 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1719 Item.uNestingLevel != 1 ||
1720 Item.uNextNestLevel != 2) {
1721 return -3;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001722 }
1723
1724 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301725 if(Item.uDataType != QCBOR_TYPE_INT64 |
1726 Item.uNestingLevel != 2 ||
1727 Item.uNextNestLevel != 2) {
1728 return -4;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001729 }
1730
1731 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301732 if(Item.uDataType != QCBOR_TYPE_INT64 |
1733 Item.uNestingLevel != 2 ||
1734 Item.uNextNestLevel != 0) {
1735 return -5;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001736 }
1737
1738 if(QCBORDecode_Finish(&DC)) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301739 return -6;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001740 }
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001741
1742 // --- next test -----
1743 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad1);
1744
1745 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1746
1747 QCBORDecode_SetMemPool(&DC, MemPool, false);
1748
1749 nResult = QCBORDecode_GetNext(&DC, &Item);
1750 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301751 return -7;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001752 }
1753
Laurence Lundblade570fab52018-10-13 18:28:27 +08001754 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301755 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1756 return -8;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001757 }
1758
1759
1760 // --- next test -----
1761 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad2);
1762
1763 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1764
1765 QCBORDecode_SetMemPool(&DC, MemPool, false);
1766
1767 nResult = QCBORDecode_GetNext(&DC, &Item);
1768 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301769 return -9;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001770 }
1771
1772 nResult = QCBORDecode_GetNext(&DC, &Item);
1773 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301774 return -10;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001775 }
1776
1777 nResult = QCBORDecode_GetNext(&DC, &Item);
1778 if(nResult || Item.uDataType != QCBOR_TYPE_INT64) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301779 return -11;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001780 }
1781
1782 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301783 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1784 return -12;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001785 }
1786
1787
1788 // --- next test -----
1789 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad3);
1790
1791 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1792
1793 QCBORDecode_SetMemPool(&DC, MemPool, false);
1794
1795 nResult = QCBORDecode_GetNext(&DC, &Item);
1796 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301797 return -13;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001798 }
1799
1800 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301801 if(nResult != QCBOR_ERR_BAD_BREAK) {
1802 return -14;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001803 }
Laurence Lundblade6de37062018-10-15 12:22:42 +05301804
Laurence Lundblade570fab52018-10-13 18:28:27 +08001805
1806 // --- next test -----
1807 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad4);
1808
1809 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1810
1811 QCBORDecode_SetMemPool(&DC, MemPool, false);
1812
1813 nResult = QCBORDecode_GetNext(&DC, &Item);
1814 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301815 return -15;
Laurence Lundblade570fab52018-10-13 18:28:27 +08001816 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301817
Laurence Lundblade570fab52018-10-13 18:28:27 +08001818 nResult = QCBORDecode_GetNext(&DC, &Item);
1819 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301820 return -16;
Laurence Lundblade570fab52018-10-13 18:28:27 +08001821 }
1822
1823 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301824 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1825 return -17;
Laurence Lundblade570fab52018-10-13 18:28:27 +08001826 }
1827
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301828 // --- next test -----
1829 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad5);
1830
1831 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1832
1833 QCBORDecode_SetMemPool(&DC, MemPool, false);
1834
1835 nResult = QCBORDecode_GetNext(&DC, &Item);
1836 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301837 return -18;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301838 }
1839
1840 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301841 if(nResult != QCBOR_ERR_BAD_BREAK) {
1842 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301843 }
1844
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001845 return 0;
1846}
1847
Laurence Lundblade17ede402018-10-13 11:43:07 +08001848
1849static const uint8_t pIndefiniteLenString[] = {
1850 0x81, // Array of length one
1851 0x7f, // text string marked with indefinite length
1852 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
1853 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
1854 0xff // ending break
1855};
1856
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301857int indefinite_length_decode_string_test()
1858{
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001859 UsefulBufC IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteLenString);
1860
1861
1862 // Decode it and see if it is OK
1863 QCBORDecodeContext DC;
1864 QCBORItem Item;
1865 UsefulBuf_MakeStackUB(MemPool, 200);
1866
1867 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1868
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301869 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
1870 return -4;
1871 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001872
1873
1874 QCBORDecode_GetNext(&DC, &Item);
1875 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1876 return -1;
1877 }
1878
1879 QCBORDecode_GetNext(&DC, &Item);
1880 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING) {
1881 return -1;
1882 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301883
1884 // ------ Don't set a string allocator and see an error
1885 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1886
1887 QCBORDecode_GetNext(&DC, &Item);
1888 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1889 return -1;
1890 }
1891
1892 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_NO_STRING_ALLOCATOR) {
1893 return -1;
1894 }
1895
1896 // ----- Mempool is way too small -----
1897 UsefulBuf_MakeStackUB(MemPoolTooSmall, 20); // 20 is too small no matter what
1898
1899 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1900 if(!QCBORDecode_SetMemPool(&DC, MemPoolTooSmall, false)) {
1901 return -8;
1902 }
1903
1904
1905
1906 // ----- Mempool is way too small -----
1907 UsefulBuf_MakeStackUB(MemPoolSmall, 60); // TODO: this tests needs some big strings to be CPU indepedent
1908
1909 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1910 if(QCBORDecode_SetMemPool(&DC, MemPoolSmall, false)) {
1911 return -8;
1912 }
1913
1914 QCBORDecode_GetNext(&DC, &Item);
1915 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1916 return -1;
1917 }
1918 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_STRING_ALLOC) {
1919 return -1;
1920 }
1921
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001922 return 0;
1923}
1924
1925
1926
Laurence Lundblade0155b622018-10-12 20:04:37 +08001927int mempool_test(void)
1928{
1929 QCBORDecodeContext DC;
1930
1931 const uint8_t pMinimalCBOR[] = {0xa0}; // One empty map
1932
1933 QCBORDecode_Init(&DC, UsefulBuf_FromByteArrayLiteral(pMinimalCBOR),0);
1934
1935 UsefulBuf_MakeStackUB(Pool, 100);
1936
1937 QCBORDecode_SetMemPool(&DC, Pool, 0);
1938
1939 // Cheat a little to get to the string allocator object
1940 // so we can call it directly to test it
1941 QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
1942
1943 // Ask for too much in one go
1944 // 90 < 100, but there is some overhead taken out of the 100
1945 UsefulBuf Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 90);
1946 if(!UsefulBuf_IsNULL(Allocated)) {
1947 return -1;
1948 }
1949
1950
1951
1952 QCBORDecode_SetMemPool(&DC, Pool, 0);
1953
1954 // Cheat a little to get to the string allocator object
1955 // so we can call it directly to test it
1956 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
1957
1958 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
1959 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
1960 return -1;
1961 }
1962 UsefulBuf Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
1963 if(!UsefulBuf_IsNULL(Allocated2)) { // expected to fail
1964 return -1;
1965 }
1966 (*pAlloc->fFree)(pAlloc->pAllocaterContext, Allocated.ptr);
1967 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
1968 if(UsefulBuf_IsNULL(Allocated)) { // succeed because of the free
1969 return -1;
1970 }
1971
1972
1973 QCBORDecode_SetMemPool(&DC, Pool, 0);
1974
1975 // Cheat a little to get to the string allocator object
1976 // so we can call it directly to test it
1977 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
1978 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 20);
1979 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
1980 return -1;
1981 }
1982 Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, 25);
1983 if(UsefulBuf_IsNULL(Allocated2)) { // expected to fail
1984 return -1;
1985 }
1986 if(Allocated2.ptr != Allocated.ptr || Allocated2.len != 25) {
1987 return -1;
1988 }
1989
1990
1991
1992
1993 return 0;
1994}
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001995
1996
1997
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001998
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001999
2000