blob: bf48aa7436b02605d77945c9cfb63fdcc77afa6a [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
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
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301492static 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 +08001493{
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;
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301508 if(Item.uNextNestLevel != uNextNest) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001509
1510 if(pItem) {
1511 *pItem = Item;
1512 }
1513 return 0;
1514}
1515
1516
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001517// Same code checks definite and indefinite length versions of the map
1518static int CheckCSRMaps(QCBORDecodeContext *pDC)
1519{
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301520 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 0, 1, 0, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001521
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301522 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -23, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001523
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301524 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -20, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001525
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301526 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -18, NULL)) return -1;
1527 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -17, NULL)) return -1;
1528 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -15, NULL)) return -1;
1529 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -16, NULL)) return -1;
1530 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 2, -14, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001531
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301532 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -19, NULL)) return -1;
1533 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 3, 4, -11, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001534
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301535 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 4, 3, -9, NULL)) return -1;
1536 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_BYTE_STRING, 3, 1, -10, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001537
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301538 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -22, NULL)) return -1;
1539 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 2, 0, -5, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001540
1541 if(QCBORDecode_Finish(pDC)) return -2;
1542
1543 return 0;
1544}
1545
1546
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001547/*
1548// cbor.me decoded output
1549{
1550 -23: {
1551 -20: {
1552 -18: "Organization",
1553 -17: "SSG",
1554 -15: "Confusion",
1555 -16: "San Diego",
1556 -14: "US"
1557 },
1558 -19: {
1559 -11: {
1560 -9: -7
1561 },
1562 -10: '\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\n'
1563 }
1564 },
1565 -22: {
1566 -5: -3
1567 }
1568}
1569 */
1570
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001571
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001572static uint8_t s_CSRInput[] = {
1573 0xa2, 0x36, 0xa2, 0x33, 0xa5, 0x31, 0x6c, 0x4f,
1574 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1575 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1576 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1577 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1578 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1579 0x55, 0x53, 0x32, 0xa2, 0x2a, 0xa1, 0x28, 0x26,
1580 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1581 0x07, 0x08, 0x09, 0x0a, 0x35, 0xa1, 0x24, 0x22};
1582
1583int NestedMapTest()
1584{
1585 QCBORDecodeContext DCtx;
1586
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001587 QCBORDecode_Init(&DCtx, UsefulBuf_FromByteArrayLiteral(s_CSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001588
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001589 return CheckCSRMaps(&DCtx);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001590}
1591
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001592// Same map as above, but using indefinite lengths
1593static uint8_t s_CSRInputIndefLen[] = {
1594 0xbf, 0x36, 0xbf, 0x33, 0xbf, 0x31, 0x6c, 0x4f,
1595 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1596 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1597 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1598 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1599 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1600 0x55, 0x53, 0xff, 0x32, 0xbf, 0x2a, 0xbf, 0x28, 0x26, 0xff,
1601 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1602 0x07, 0x08, 0x09, 0x0a, 0xff, 0xff, 0x35, 0xbf, 0x24, 0x22, 0xff, 0xff};
1603
1604int NestedMapTestIndefLen()
1605{
1606 QCBORDecodeContext DCtx;
1607
1608 QCBORDecode_Init(&DCtx, UsefulBuf_FromByteArrayLiteral(s_CSRInputIndefLen), QCBOR_DECODE_MODE_NORMAL);
1609
1610 return CheckCSRMaps(&DCtx);
1611}
1612
1613
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001614
Laurence Lundblade17ede402018-10-13 11:43:07 +08001615static UsefulBufC make_nested_indefinite_arrays(int n, UsefulBuf Storage)
1616{
1617 UsefulOutBuf UOB;
1618 UsefulOutBuf_Init(&UOB, Storage);
1619
1620 int i;
1621 for(i = 0; i < n; i++) {
1622 UsefulOutBuf_AppendByte(&UOB, 0x9f);
1623 }
1624
1625 for(i = 0; i < n; i++) {
1626 UsefulOutBuf_AppendByte(&UOB, 0xff);
1627 }
1628 return UsefulOutBuf_OutUBuf(&UOB);
1629}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001630
1631
Laurence Lundblade17ede402018-10-13 11:43:07 +08001632static int parse_indeflen_nested(UsefulBufC Nested, int nNestLevel)
1633{
1634 QCBORDecodeContext DC;
1635 QCBORDecode_Init(&DC, Nested, 0);
1636
1637 int j;
1638 for(j = 0; j < nNestLevel; j++) {
1639 QCBORItem Item;
1640 int nReturn = QCBORDecode_GetNext(&DC, &Item);
1641 if(j >= QCBOR_MAX_ARRAY_NESTING) {
1642 // Should be in error
1643 if(nReturn != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP) {
1644 return -4;
1645 } else {
1646 return 0; // Decoding doesn't recover after an error
1647 }
1648 } else {
1649 // Should be no error
1650 if(nReturn) {
1651 return -9; // Should not have got an error
1652 }
1653 }
1654 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1655 return -7;
1656 }
1657 }
1658 int nReturn = QCBORDecode_Finish(&DC);
1659 if(nReturn) {
1660 return -3;
1661 }
1662 return 0;
1663}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001664
1665
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301666int IndefiniteLengthNestTest()
Laurence Lundblade17ede402018-10-13 11:43:07 +08001667{
1668 UsefulBuf_MakeStackUB(Storage, 50);
1669 int i;
Laurence Lundblade6de37062018-10-15 12:22:42 +05301670 for(i=1; i < QCBOR_MAX_ARRAY_NESTING+4; i++) {
Laurence Lundblade17ede402018-10-13 11:43:07 +08001671 UsefulBufC Nested = make_nested_indefinite_arrays(i, Storage);
1672 int nReturn = parse_indeflen_nested(Nested, i);
1673 if(nReturn) {
1674 return nReturn;
1675 }
1676 }
1677 return 0;
1678}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001679
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001680
Laurence Lundblade6de37062018-10-15 12:22:42 +05301681
1682static const uint8_t pIndefiniteArray[] = {0x9f, 0x01, 0x82, 0x02, 0x03, 0xff}; // [1, [2, 3]]
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001683static const uint8_t pIndefiniteArrayBad1[] = {0x9f}; // No closing break
1684static const uint8_t pIndefiniteArrayBad2[] = {0x9f, 0x9f, 0x02, 0xff}; // Not enough closing breaks
1685static const uint8_t pIndefiniteArrayBad3[] = {0x9f, 0x02, 0xff, 0xff}; // Too many closing breaks
Laurence Lundblade570fab52018-10-13 18:28:27 +08001686static const uint8_t pIndefiniteArrayBad4[] = {0x81, 0x9f}; // Unclosed indeflen inside def len
Laurence Lundblade6de37062018-10-15 12:22:42 +05301687static const uint8_t pIndefiniteArrayBad5[] = {0x9f, 0xc7, 0xff}; // confused tag
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001688
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301689int IndefiniteLengthArrayMapTest()
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001690{
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001691 int nResult;
1692 // --- first test -----
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001693 UsefulBufC IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArray);
Laurence Lundblade17ede402018-10-13 11:43:07 +08001694
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001695 // Decode it and see if it is OK
Laurence Lundblade6de37062018-10-15 12:22:42 +05301696 UsefulBuf_MakeStackUB(MemPool, 150);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001697 QCBORDecodeContext DC;
1698 QCBORItem Item;
1699 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1700
1701 QCBORDecode_SetMemPool(&DC, MemPool, false);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301702
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001703 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301704
1705 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1706 Item.uNestingLevel != 0 ||
1707 Item.uNextNestLevel != 1) {
1708 return -111;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001709 }
1710
1711 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301712 if(Item.uDataType != QCBOR_TYPE_INT64 ||
1713 Item.uNestingLevel != 1 ||
1714 Item.uNextNestLevel != 1) {
1715 return -2;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001716 }
1717
1718 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301719 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1720 Item.uNestingLevel != 1 ||
1721 Item.uNextNestLevel != 2) {
1722 return -3;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001723 }
1724
1725 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301726 if(Item.uDataType != QCBOR_TYPE_INT64 |
1727 Item.uNestingLevel != 2 ||
1728 Item.uNextNestLevel != 2) {
1729 return -4;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001730 }
1731
1732 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301733 if(Item.uDataType != QCBOR_TYPE_INT64 |
1734 Item.uNestingLevel != 2 ||
1735 Item.uNextNestLevel != 0) {
1736 return -5;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001737 }
1738
1739 if(QCBORDecode_Finish(&DC)) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301740 return -6;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001741 }
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001742
1743 // --- next test -----
1744 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad1);
1745
1746 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1747
1748 QCBORDecode_SetMemPool(&DC, MemPool, false);
1749
1750 nResult = QCBORDecode_GetNext(&DC, &Item);
1751 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301752 return -7;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001753 }
1754
Laurence Lundblade570fab52018-10-13 18:28:27 +08001755 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301756 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1757 return -8;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001758 }
1759
1760
1761 // --- next test -----
1762 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad2);
1763
1764 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1765
1766 QCBORDecode_SetMemPool(&DC, MemPool, false);
1767
1768 nResult = QCBORDecode_GetNext(&DC, &Item);
1769 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301770 return -9;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001771 }
1772
1773 nResult = QCBORDecode_GetNext(&DC, &Item);
1774 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301775 return -10;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001776 }
1777
1778 nResult = QCBORDecode_GetNext(&DC, &Item);
1779 if(nResult || Item.uDataType != QCBOR_TYPE_INT64) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301780 return -11;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001781 }
1782
1783 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301784 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1785 return -12;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001786 }
1787
1788
1789 // --- next test -----
1790 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad3);
1791
1792 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1793
1794 QCBORDecode_SetMemPool(&DC, MemPool, false);
1795
1796 nResult = QCBORDecode_GetNext(&DC, &Item);
1797 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301798 return -13;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001799 }
1800
1801 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301802 if(nResult != QCBOR_ERR_BAD_BREAK) {
1803 return -14;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001804 }
Laurence Lundblade6de37062018-10-15 12:22:42 +05301805
Laurence Lundblade570fab52018-10-13 18:28:27 +08001806
1807 // --- next test -----
1808 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad4);
1809
1810 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1811
1812 QCBORDecode_SetMemPool(&DC, MemPool, false);
1813
1814 nResult = QCBORDecode_GetNext(&DC, &Item);
1815 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301816 return -15;
Laurence Lundblade570fab52018-10-13 18:28:27 +08001817 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301818
Laurence Lundblade570fab52018-10-13 18:28:27 +08001819 nResult = QCBORDecode_GetNext(&DC, &Item);
1820 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301821 return -16;
Laurence Lundblade570fab52018-10-13 18:28:27 +08001822 }
1823
1824 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301825 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
1826 return -17;
Laurence Lundblade570fab52018-10-13 18:28:27 +08001827 }
1828
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301829 // --- next test -----
1830 IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArrayBad5);
1831
1832 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
1833
1834 QCBORDecode_SetMemPool(&DC, MemPool, false);
1835
1836 nResult = QCBORDecode_GetNext(&DC, &Item);
1837 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05301838 return -18;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301839 }
1840
1841 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05301842 if(nResult != QCBOR_ERR_BAD_BREAK) {
1843 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301844 }
1845
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001846 return 0;
1847}
1848
Laurence Lundblade17ede402018-10-13 11:43:07 +08001849
1850static const uint8_t pIndefiniteLenString[] = {
1851 0x81, // Array of length one
1852 0x7f, // text string marked with indefinite length
1853 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
1854 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
1855 0xff // ending break
1856};
1857
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301858static const uint8_t pIndefiniteLenStringBad2[] = {
1859 0x81, // Array of length one
1860 0x7f, // text string marked with indefinite length
1861 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
1862 0x44, 0x6d, 0x69, 0x6e, 0x67, // second segment of wrong type
1863 0xff // ending break
1864};
1865
1866static const uint8_t pIndefiniteLenStringBad3[] = {
1867 0x81, // Array of length one
1868 0x7f, // text string marked with indefinite length
1869 0x01, 0x02, // Not a string
1870 0xff // ending break
1871};
1872
1873static const uint8_t pIndefiniteLenStringBad4[] = {
1874 0x81, // Array of length one
1875 0x7f, // text string marked with indefinite length
1876 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
1877 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
1878 // missing end of string
1879};
1880
1881static const uint8_t pIndefiniteLenStringLabel[] = {
1882 0xa1, // Array of length one
1883 0x7f, // text string marked with indefinite length
1884 0x65, 0x73, 0x74, 0x72, 0x75, 0x75, // first segment
1885 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
1886 0xff, // ending break
1887 0x01 // integer being labeled.
1888};
1889
1890static UsefulBufC MakeIndefiniteBigBstr(UsefulBuf Storage)
1891{
1892 UsefulOutBuf UOB;
1893
1894 UsefulOutBuf_Init(&UOB, Storage);
1895 UsefulOutBuf_AppendByte(&UOB, 0x81);
1896 UsefulOutBuf_AppendByte(&UOB, 0x5f);
1897
1898 int i = 0;
1899 for(int nChunkSize = 1; nChunkSize <= 128; nChunkSize *= 2) {
1900 UsefulOutBuf_AppendByte(&UOB, 0x58);
1901 UsefulOutBuf_AppendByte(&UOB, (uint8_t)nChunkSize);
1902 for(int j = 0; j < nChunkSize; j++ ) {
1903 UsefulOutBuf_AppendByte(&UOB, i);
1904 i++;
1905 }
1906 }
1907 UsefulOutBuf_AppendByte(&UOB, 0xff);
1908
1909 return UsefulOutBuf_OutUBuf(&UOB);
1910}
1911
1912static int CheckBigString(UsefulBufC BigString)
1913{
1914 if(BigString.len != 255) {
1915 return 1;
1916 }
1917
1918 for(uint8_t i = 0; i < 255; i++){
1919 if(((const uint8_t *)BigString.ptr)[i] != i) {
1920 return 1;
1921 }
1922 }
1923 return 0;
1924}
1925
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05301926
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301927int IndefiniteLengthStringTest()
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301928{
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301929 QCBORDecodeContext DC;
1930 QCBORItem Item;
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05301931 // big enough for MakeIndefiniteBigBstr() + MemPool overhead
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301932 UsefulBuf_MakeStackUB(MemPool, 320);
1933
1934 // --- Simple normal indefinite length string ------
1935 UsefulBufC IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteLenString);
1936 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001937
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05301938 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301939 return -1;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301940 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001941
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301942 if(QCBORDecode_GetNext(&DC, &Item)) {
1943 return -2;
1944 }
1945 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
1946 return -3;
1947 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001948
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301949 if(QCBORDecode_GetNext(&DC, &Item)) {
1950 return -4;
1951 }
1952 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING || !Item.uDataAlloc) {
1953 return -5;
1954 }
1955 if(QCBORDecode_Finish(&DC)) {
1956 return -6;
1957 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05301958
Laurence Lundblade57dd1442018-10-15 20:26:28 +05301959 // ----- types mismatch ---
1960 QCBORDecode_Init(&DC, UsefulBuf_FromByteArrayLiteral(pIndefiniteLenStringBad2), QCBOR_DECODE_MODE_NORMAL);
1961
1962 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
1963 return -7;
1964 }
1965
1966 if(QCBORDecode_GetNext(&DC, &Item)) {
1967 return -8;
1968 }
1969 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1970 return -9;
1971 }
1972
1973 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_SEG) {
1974 return -10;
1975 }
1976
1977 // ----- not a string ---
1978 QCBORDecode_Init(&DC, UsefulBuf_FromByteArrayLiteral(pIndefiniteLenStringBad3), QCBOR_DECODE_MODE_NORMAL);
1979
1980 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
1981 return -11;
1982 }
1983
1984 if(QCBORDecode_GetNext(&DC, &Item)) {
1985 return -12;
1986 }
1987 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1988 return -13;
1989 }
1990
1991 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_SEG) {
1992 return -14;
1993 }
1994
1995 // ----- no end -----
1996 QCBORDecode_Init(&DC, UsefulBuf_FromByteArrayLiteral(pIndefiniteLenStringBad4), QCBOR_DECODE_MODE_NORMAL);
1997
1998 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
1999 return -15;
2000 }
2001
2002 if(QCBORDecode_GetNext(&DC, &Item)) {
2003 return -16;
2004 }
2005 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2006 return -17;
2007 }
2008
2009 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_HIT_END) {
2010 return -18;
2011 }
2012
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302013 // ------ Don't set a string allocator and see an error -----
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302014 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2015
2016 QCBORDecode_GetNext(&DC, &Item);
2017 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302018 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302019 }
2020
2021 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_NO_STRING_ALLOCATOR) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302022 return -20;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302023 }
2024
2025 // ----- Mempool is way too small -----
2026 UsefulBuf_MakeStackUB(MemPoolTooSmall, 20); // 20 is too small no matter what
2027
2028 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2029 if(!QCBORDecode_SetMemPool(&DC, MemPoolTooSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302030 return -21;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302031 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302032
2033 // ----- Mempool is way too small -----
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302034 UsefulBuf_MakeStackUB(BigIndefBStrStorage, 290);
2035 UsefulBufC BigIndefBStr = MakeIndefiniteBigBstr(BigIndefBStrStorage);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302036
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302037 UsefulBuf_MakeStackUB(MemPoolSmall, 80); // 80 is big enough for MemPool overhead, but not BigIndefBStr
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302038
2039 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302040 if(QCBORDecode_SetMemPool(&DC, MemPoolSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302041 return -22;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302042 }
2043
2044 QCBORDecode_GetNext(&DC, &Item);
2045 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302046 return -23;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302047 }
2048 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_STRING_ALLOC) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302049 return -24;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302050 }
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302051
2052 // ---- big bstr -----
2053 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
2054
2055 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2056 return -25;
2057 }
2058
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302059 if(QCBORDecode_GetNext(&DC, &Item)) {
2060 return -26;
2061 }
2062 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302063 return -26;
2064 }
2065
2066 if(QCBORDecode_GetNext(&DC, &Item)) {
2067 return -27;
2068 }
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302069 if(Item.uDataType != QCBOR_TYPE_BYTE_STRING || !Item.uDataAlloc || Item.uNestingLevel != 1) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302070 return -28;
2071 }
2072 if(CheckBigString(Item.val.string)) {
2073 return -3;
2074 }
2075 if(QCBORDecode_Finish(&DC)) {
2076 return -29;
2077 }
2078
2079 // --- label is an indefinite length string ------
2080 QCBORDecode_Init(&DC, UsefulBuf_FromByteArrayLiteral(pIndefiniteLenStringLabel), QCBOR_DECODE_MODE_NORMAL);
2081
2082 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2083 return -30;
2084 }
2085
2086 QCBORDecode_GetNext(&DC, &Item);
2087 if(Item.uDataType != QCBOR_TYPE_MAP) {
2088 return -31;
2089 }
2090
2091 if(QCBORDecode_GetNext(&DC, &Item)){
2092 return -32;
2093 }
2094 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING || Item.uDataType != QCBOR_TYPE_INT64 ||
2095 Item.uDataAlloc || !Item.uLabelAlloc ||
2096 UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("struuming"))) {
2097 return -33;
2098 }
2099
2100 if(QCBORDecode_Finish(&DC)) {
2101 return -34;
2102 }
2103
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002104 return 0;
2105}
2106
2107
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302108int AllocAllStringsTest()
2109{
2110 QCBORDecodeContext DC;
2111
2112 // First test, use the "CSRMap" as easy input and checking
2113 QCBORDecode_Init(&DC, UsefulBuf_FromByteArrayLiteral(s_CSRInput), QCBOR_DECODE_MODE_NORMAL);
2114
2115 UsefulBuf_MakeStackUB(Pool, 300);
2116
2117 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2118
2119 if(CheckCSRMaps(&DC)) {
2120 return -1;
2121 }
2122
2123 // Next parse, save pointers to a few strings, destroy original and see all is OK.
2124 MakeUsefulBufOnStack(CopyOfStorage, 160);
2125 UsefulBufC CopyOf = UsefulBuf_Copy(CopyOfStorage, UsefulBuf_FromByteArrayLiteral(pValidMapEncoded));
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002126
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302127 QCBORDecode_Init(&DC, CopyOf, QCBOR_DECODE_MODE_NORMAL);
2128 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2129
2130 int nCBORError;
2131 QCBORItem Item1, Item2, Item3, Item4;
2132 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2133 return nCBORError;
2134 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2135 Item1.val.uCount != 3)
2136 return -1;
2137 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2138 return nCBORError;
2139 if((nCBORError = QCBORDecode_GetNext(&DC, &Item2)))
2140 return nCBORError;
2141 if((nCBORError = QCBORDecode_GetNext(&DC, &Item3)))
2142 return nCBORError;
2143 if((nCBORError = QCBORDecode_GetNext(&DC, &Item4)))
2144 return nCBORError;
2145
2146 UsefulBuf_Set(&CopyOfStorage, '_');
2147
2148 if(Item1.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2149 Item1.label.string.len != 13 ||
2150 Item1.uDataType != QCBOR_TYPE_INT64 ||
2151 Item1.val.int64 != 42 ||
2152 memcmp(Item1.label.string.ptr, "first integer", 13))
2153 return -1;
2154
2155
2156 if(Item2.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2157 Item2.label.string.len != 23 ||
2158 memcmp(Item2.label.string.ptr, "an array of two strings", 23) ||
2159 Item2.uDataType != QCBOR_TYPE_ARRAY ||
2160 Item2.val.uCount != 2)
2161 return -1;
2162
2163 if(Item3.uDataType != QCBOR_TYPE_TEXT_STRING ||
2164 Item3.val.string.len != 7 ||
2165 memcmp(Item3.val.string.ptr, "string1", 7))
2166 return -1;
2167
2168 if(Item4.uDataType != QCBOR_TYPE_TEXT_STRING ||
2169 Item4.val.string.len != 7 ||
2170 memcmp(Item4.val.string.ptr, "string2", 7))
2171 return -1;
2172
2173 // Next parse with a pool that is too small
2174 UsefulBuf_MakeStackUB(SmallPool, 80);
2175 QCBORDecode_Init(&DC, UsefulBuf_FromByteArrayLiteral(pValidMapEncoded), QCBOR_DECODE_MODE_NORMAL);
2176 QCBORDecode_SetMemPool(&DC, SmallPool, 1); // Turn on copying.
2177 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2178 return nCBORError;
2179 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2180 Item1.val.uCount != 3)
2181 return -1;
2182 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item1))){
2183 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item2))) {
2184 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item3))) {
2185 nCBORError = QCBORDecode_GetNext(&DC, &Item4);
2186 }
2187 }
2188 }
2189 if(nCBORError != QCBOR_ERR_STRING_ALLOC) {
2190 return -5;
2191 }
2192
2193 return 0;
2194}
2195
2196
2197int MemPoolTest(void)
Laurence Lundblade0155b622018-10-12 20:04:37 +08002198{
2199 QCBORDecodeContext DC;
2200
2201 const uint8_t pMinimalCBOR[] = {0xa0}; // One empty map
2202
2203 QCBORDecode_Init(&DC, UsefulBuf_FromByteArrayLiteral(pMinimalCBOR),0);
2204
2205 UsefulBuf_MakeStackUB(Pool, 100);
2206
2207 QCBORDecode_SetMemPool(&DC, Pool, 0);
2208
2209 // Cheat a little to get to the string allocator object
2210 // so we can call it directly to test it
2211 QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2212
2213 // Ask for too much in one go
2214 // 90 < 100, but there is some overhead taken out of the 100
2215 UsefulBuf Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 90);
2216 if(!UsefulBuf_IsNULL(Allocated)) {
2217 return -1;
2218 }
2219
2220
2221
2222 QCBORDecode_SetMemPool(&DC, Pool, 0);
2223
2224 // Cheat a little to get to the string allocator object
2225 // so we can call it directly to test it
2226 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2227
2228 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2229 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2230 return -1;
2231 }
2232 UsefulBuf Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2233 if(!UsefulBuf_IsNULL(Allocated2)) { // expected to fail
2234 return -1;
2235 }
2236 (*pAlloc->fFree)(pAlloc->pAllocaterContext, Allocated.ptr);
2237 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2238 if(UsefulBuf_IsNULL(Allocated)) { // succeed because of the free
2239 return -1;
2240 }
2241
2242
2243 QCBORDecode_SetMemPool(&DC, Pool, 0);
2244
2245 // Cheat a little to get to the string allocator object
2246 // so we can call it directly to test it
2247 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2248 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 20);
2249 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2250 return -1;
2251 }
2252 Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, 25);
2253 if(UsefulBuf_IsNULL(Allocated2)) { // expected to fail
2254 return -1;
2255 }
2256 if(Allocated2.ptr != Allocated.ptr || Allocated2.len != 25) {
2257 return -1;
2258 }
2259
Laurence Lundblade0155b622018-10-12 20:04:37 +08002260 return 0;
2261}
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002262
2263
2264
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08002265
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002266
2267