blob: 2ae641c01d546fb70b9561fdcce7fcb2d262c6d5 [file] [log] [blame]
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001/*==============================================================================
Laurence Lundbladed92a6162018-11-01 11:38:35 +07002 Copyright (c) 2016-2018, The Linux Foundation.
3 Copyright (c) 2018, Laurence Lundblade.
4 All rights reserved.
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08005
Laurence Lundblade0dbc9172018-11-01 14:17:21 +07006Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are
8met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15 * Neither the name of The Linux Foundation nor the names of its
16 contributors, nor the name "Laurence Lundblade" may be used to
17 endorse or promote products derived from this software without
18 specific prior written permission.
Laurence Lundblade9e3651c2018-10-10 11:49:55 +080019
Laurence Lundblade0dbc9172018-11-01 14:17:21 +070020THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Laurence Lundblade9e3651c2018-10-10 11:49:55 +080031 ==============================================================================*/
32
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080033#include "qcbor.h"
34#include "qcbor_decode_tests.h"
35#include <stdio.h>
36#include <strings.h>
Laurence Lundblade9e3651c2018-10-10 11:49:55 +080037#include <math.h> // for fabs()
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080038#include <stdlib.h>
39
40
41// TODO: test other than the normal decoder mode
42
43static void printencoded(const char *szLabel, const uint8_t *pEncoded, size_t nLen)
44{
45 if(szLabel) {
46 printf("%s ", szLabel);
47 }
48
Laurence Lundblade570fab52018-10-13 18:28:27 +080049 size_t i;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080050 for(i = 0; i < nLen; i++) {
51 uint8_t Z = pEncoded[i];
52 printf("%02x ", Z);
53 }
54 printf("\n");
55
56 fflush(stdout);
57}
58
59
60// TODO: -- add a test for counting the top level items and adding it back in with AddRaw()
61
62
Laurence Lundbladeb836efb2018-10-28 20:09:58 +070063static const uint8_t spExpectedEncodedInts[] = {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080064 0x98, 0x2f, 0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff,
65 0xff, 0xff, 0xff, 0x3b, 0x00, 0x00, 0x00, 0x01,
66 0x00, 0x00, 0x00, 0x00, 0x3a, 0xff, 0xff, 0xff,
67 0xff, 0x3a, 0xff, 0xff, 0xff, 0xfe, 0x3a, 0xff,
68 0xff, 0xff, 0xfd, 0x3a, 0x7f, 0xff, 0xff, 0xff,
69 0x3a, 0x7f, 0xff, 0xff, 0xfe, 0x3a, 0x00, 0x01,
70 0x00, 0x01, 0x3a, 0x00, 0x01, 0x00, 0x00, 0x39,
71 0xff, 0xff, 0x39, 0xff, 0xfe, 0x39, 0xff, 0xfd,
72 0x39, 0x01, 0x00, 0x38, 0xff, 0x38, 0xfe, 0x38,
73 0xfd, 0x38, 0x18, 0x37, 0x36, 0x20, 0x00, 0x00,
74 0x01, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19, 0x18,
75 0x1a, 0x18, 0xfe, 0x18, 0xff, 0x19, 0x01, 0x00,
76 0x19, 0x01, 0x01, 0x19, 0xff, 0xfe, 0x19, 0xff,
77 0xff, 0x1a, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x00,
78 0x01, 0x00, 0x01, 0x1a, 0x00, 0x01, 0x00, 0x02,
79 0x1a, 0x7f, 0xff, 0xff, 0xff, 0x1a, 0x7f, 0xff,
80 0xff, 0xff, 0x1a, 0x80, 0x00, 0x00, 0x00, 0x1a,
81 0x80, 0x00, 0x00, 0x01, 0x1a, 0xff, 0xff, 0xff,
82 0xfe, 0x1a, 0xff, 0xff, 0xff, 0xff, 0x1b, 0x00,
83 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
84 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
85 0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
86 0xff, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
87 0xff, 0xff};
88
89
Laurence Lundblade2ded3d92018-10-09 21:36:11 +080090// return CBOR error or -1 if type of value doesn't match
91
92static int IntegerValuesParseTestInternal(QCBORDecodeContext *pDCtx)
93{
94 QCBORItem Item;
95 int nCBORError;
96
97 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
98 return nCBORError;
99 if(Item.uDataType != QCBOR_TYPE_ARRAY)
100 return -1;
101
102 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
103 return nCBORError;
104 if(Item.uDataType != QCBOR_TYPE_INT64 || // Todo; fix this for 32-bit machines
Laurence Lundblade570fab52018-10-13 18:28:27 +0800105 Item.val.int64 != -9223372036854775807LL - 1)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800106 return -1;
107
108 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
109 return nCBORError;
110 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundblade570fab52018-10-13 18:28:27 +0800111 Item.val.int64 != -4294967297)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800112 return -1;
113
114 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
115 return nCBORError;
116 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundblade570fab52018-10-13 18:28:27 +0800117 Item.val.int64 != -4294967296)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800118 return -1;
119
120 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
121 return nCBORError;
122 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundblade570fab52018-10-13 18:28:27 +0800123 Item.val.int64 != -4294967295)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800124 return -1;
125
126 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
127 return nCBORError;
128 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundblade570fab52018-10-13 18:28:27 +0800129 Item.val.int64 != -4294967294)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800130 return -1;
131
132
133 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
134 return nCBORError;
135 if(Item.uDataType != QCBOR_TYPE_INT64 ||
136 Item.val.int64 != -2147483648)
137 return -1;
138
139 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
140 return nCBORError;
141 if(Item.uDataType != QCBOR_TYPE_INT64 ||
142 Item.val.int64 != -2147483647)
143 return -1;
144
145 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
146 return nCBORError;
147 if(Item.uDataType != QCBOR_TYPE_INT64 ||
148 Item.val.int64 != -65538)
149 return -1;
150
151 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
152 return nCBORError;
153 if(Item.uDataType != QCBOR_TYPE_INT64 ||
154 Item.val.int64 != -65537)
155 return -1;
156
157 if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
158 return nCBORError;
159 if(Item.uDataType != QCBOR_TYPE_INT64 ||
160 Item.val.int64 != -65536)
161 return -1;
162
163
164 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
165 return nCBORError;
166 if(Item.uDataType != QCBOR_TYPE_INT64 ||
167 Item.val.int64 != -65535)
168 return -1;
169
170
171 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
172 return nCBORError;
173 if(Item.uDataType != QCBOR_TYPE_INT64 ||
174 Item.val.int64 != -65534)
175 return -1;
176
177
178 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
179 return nCBORError;
180 if(Item.uDataType != QCBOR_TYPE_INT64 ||
181 Item.val.int64 != -257)
182 return -1;
183
184 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
185 return nCBORError;
186 if(Item.uDataType != QCBOR_TYPE_INT64 ||
187 Item.val.int64 != -256)
188 return -1;
189
190 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
191 return nCBORError;
192 if(Item.uDataType != QCBOR_TYPE_INT64 ||
193 Item.val.int64 != -255)
194 return -1;
195
196 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
197 return nCBORError;
198 if(Item.uDataType != QCBOR_TYPE_INT64 ||
199 Item.val.int64 != -254)
200 return -1;
201
202
203 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
204 return nCBORError;
205 if(Item.uDataType != QCBOR_TYPE_INT64 ||
206 Item.val.int64 != -25)
207 return -1;
208
209
210 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
211 return nCBORError;
212 if(Item.uDataType != QCBOR_TYPE_INT64 ||
213 Item.val.int64 != -24)
214 return -1;
215
216
217 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
218 return nCBORError;
219 if(Item.uDataType != QCBOR_TYPE_INT64 ||
220 Item.val.int64 != -23)
221 return -1;
222
223
224 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
225 return nCBORError;
226 if(Item.uDataType != QCBOR_TYPE_INT64 ||
227 Item.val.int64 != -1)
228 return -1;
229
230
231 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
232 return nCBORError;
233 if(Item.uDataType != QCBOR_TYPE_INT64 ||
234 Item.val.int64 != 0)
235 return -1;
236
237
238 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
239 return nCBORError;
240 if(Item.uDataType != QCBOR_TYPE_INT64 ||
241 Item.val.int64 != 0)
242 return -1;
243
244 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
245 return nCBORError;
246 if(Item.uDataType != QCBOR_TYPE_INT64 ||
247 Item.val.int64 != 1)
248 return -1;
249
250
251 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
252 return nCBORError;
253 if(Item.uDataType != QCBOR_TYPE_INT64 ||
254 Item.val.int64 != 22)
255 return -1;
256
257
258 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
259 return nCBORError;
260 if(Item.uDataType != QCBOR_TYPE_INT64 ||
261 Item.val.int64 != 23)
262 return -1;
263
264
265 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
266 return nCBORError;
267 if(Item.uDataType != QCBOR_TYPE_INT64 ||
268 Item.val.int64 != 24)
269 return -1;
270
271
272 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
273 return nCBORError;
274 if(Item.uDataType != QCBOR_TYPE_INT64 ||
275 Item.val.int64 != 25)
276 return -1;
277
278 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
279 return nCBORError;
280 if(Item.uDataType != QCBOR_TYPE_INT64 ||
281 Item.val.int64 != 26)
282 return -1;
283
284
285 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
286 return nCBORError;
287 if(Item.uDataType != QCBOR_TYPE_INT64 ||
288 Item.val.int64 != 254)
289 return -1;
290
291
292 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
293 return nCBORError;
294 if(Item.uDataType != QCBOR_TYPE_INT64 ||
295 Item.val.int64 != 255)
296 return -1;
297
298
299 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
300 return nCBORError;
301 if(Item.uDataType != QCBOR_TYPE_INT64 ||
302 Item.val.int64 != 256)
303 return -1;
304
305
306 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
307 return nCBORError;
308 if(Item.uDataType != QCBOR_TYPE_INT64 ||
309 Item.val.int64 != 257)
310 return -1;
311
312 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
313 return nCBORError;
314 if(Item.uDataType != QCBOR_TYPE_INT64 ||
315 Item.val.int64 != 65534)
316 return -1;
317
318
319 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
320 return nCBORError;
321 if(Item.uDataType != QCBOR_TYPE_INT64 ||
322 Item.val.int64 != 65535)
323 return -1;
324
325
326 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
327 return nCBORError;
328 if(Item.uDataType != QCBOR_TYPE_INT64 ||
329 Item.val.int64 != 65536)
330 return -1;
331
332 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
333 return nCBORError;
334 if(Item.uDataType != QCBOR_TYPE_INT64 ||
335 Item.val.int64 != 65537)
336 return -1;
337
338 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
339 return nCBORError;
340 if(Item.uDataType != QCBOR_TYPE_INT64 ||
341 Item.val.int64 != 65538)
342 return -1;
343
344 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
345 return nCBORError;
346 if(Item.uDataType != QCBOR_TYPE_INT64 ||
347 Item.val.int64 != 2147483647)
348 return -1;
349
350 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
351 return nCBORError;
352 if(Item.uDataType != QCBOR_TYPE_INT64 ||
353 Item.val.int64 != 2147483647)
354 return -1;
355
356 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
357 return nCBORError;
358 if(Item.uDataType != QCBOR_TYPE_INT64 ||
359 Item.val.int64 != 2147483648)
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 != 2147483649)
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 != 4294967294)
372 return -1;
373
374
375 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
376 return nCBORError;
377 if(Item.uDataType != QCBOR_TYPE_INT64 ||
378 Item.val.int64 != 4294967295)
379 return -1;
380
381
382 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
383 return nCBORError;
384 if(Item.uDataType != QCBOR_TYPE_INT64 ||
385 Item.val.int64 != 4294967296)
386 return -1;
387
388
389 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
390 return nCBORError;
391 if(Item.uDataType != QCBOR_TYPE_INT64 ||
392 Item.val.int64 != 4294967297)
393 return -1;
394
395
396
397 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
398 return nCBORError;
399 if(Item.uDataType != QCBOR_TYPE_INT64 ||
400 Item.val.int64 != 9223372036854775807LL)
401 return -1;
402
403
404 if(( nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
405 return nCBORError;
406 if(Item.uDataType != QCBOR_TYPE_UINT64 ||
407 Item.val.uint64 != 18446744073709551615ULL)
408 return -1;
409
410
411 if(QCBORDecode_Finish(pDCtx) != QCBOR_SUCCESS) {
412 return -1;
413 }
414
415 return 0;
416}
417
418
419/*
420 Tests the decoding of lots of different integers sizes
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800421 and values.
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800422 */
423
424int IntegerValuesParseTest()
425{
426 int n;
427 QCBORDecodeContext DCtx;
428
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700429 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedEncodedInts), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800430
431 n = IntegerValuesParseTestInternal(&DCtx);
432
433 return(n);
434}
435
436
437/*
438 Creates a simple CBOR array and returns it in *pEncoded. The array is malloced
439 and needs to be freed. This is used by several tests.
440
441 Two of the inputs can be set. Two other items in the array are fixed.
442
443 */
444
445static int CreateSimpleArray(int nInt1, int nInt2, uint8_t **pEncoded, size_t *pEncodedLen)
446{
447 QCBOREncodeContext ECtx;
448 int nReturn = -1;
449
450 *pEncoded = NULL;
451 *pEncodedLen = INT32_MAX;
452
453 // loop runs CBOR encoding twice. First with no buffer to
454 // calucate the length so buffer can be allocated correctly,
455 // and last with the buffer to do the actual encoding
456 do {
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800457 QCBOREncode_Init(&ECtx, (UsefulBuf){*pEncoded, *pEncodedLen});
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800458 QCBOREncode_OpenArray(&ECtx);
459 QCBOREncode_AddInt64(&ECtx, nInt1);
460 QCBOREncode_AddInt64(&ECtx, nInt2);
461 QCBOREncode_AddBytes(&ECtx, ((UsefulBufC) {"galactic", 8}));
462 QCBOREncode_AddBytes(&ECtx, ((UsefulBufC) {"haven token", 11}));
463 QCBOREncode_CloseArray(&ECtx);
464
465 if(QCBOREncode_Finish(&ECtx, pEncodedLen))
466 goto Done;
467
468 if(*pEncoded != NULL) {
469 nReturn = 0;
470 goto Done;
471 }
472 *pEncoded = malloc(*pEncodedLen);
473 if(*pEncoded == NULL) {
474 nReturn = -1;
475 goto Done;
476 }
477
478 } while(1);
479Done:
480 return (nReturn);
481
482}
483
484
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800485/*
486 {"first integer": 42,
487 "an array of two strings": ["string1", "string2"],
488 "map in a map": {
489 "bytes 1": h'78787878',
490 "bytes 2": h'79797979',
491 "another int": 98, "text 2":
492 "lies, damn lies and statistics"}
493 }
494 */
495
496static uint8_t pValidMapEncoded[] = {
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700497 0xa3, 0x6d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x69, 0x6e,
498 0x74, 0x65, 0x67, 0x65, 0x72, 0x18, 0x2a, 0x77, 0x61, 0x6e,
499 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20,
500 0x74, 0x77, 0x6f, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
501 0x73, 0x82, 0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31,
502 0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x6c, 0x6d,
503 0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x6d, 0x61,
504 0x70, 0xa4, 0x67, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x31,
505 0x44, 0x78, 0x78, 0x78, 0x78, 0x67, 0x62, 0x79, 0x74, 0x65,
506 0x73, 0x20, 0x32, 0x44, 0x79, 0x79, 0x79, 0x79, 0x6b, 0x61,
507 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x74,
508 0x18, 0x62, 0x66, 0x74, 0x65, 0x78, 0x74, 0x20, 0x32, 0x78,
509 0x1e, 0x6c, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x64, 0x61, 0x6d,
510 0x6e, 0x20, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64,
511 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
512 0x73 } ;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800513
514static 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)
515{
516 QCBORDecodeContext DCtx;
517 QCBORItem Item;
518 int nReturn = -1; // assume error until success
519
520 QCBORDecode_Init(&DCtx, (UsefulBufC){pEncoded, nLen}, QCBOR_DECODE_MODE_NORMAL);
521
522 // Make sure the first thing is a map
523 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_ARRAY)
524 goto Done;
525
526 // First integer
527 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 | Item.uDataType != QCBOR_TYPE_INT64)
528 goto Done;
529 *pInt1 = Item.val.int64;
530
531 // Second integer
532 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_INT64)
533 goto Done;
534 *pInt2 = Item.val.int64;
535
536 // First string
537 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
538 goto Done;
539 *pBuf3 = Item.val.string.ptr;
540 *pBuf3Len = Item.val.string.len;
541
542 // Second string
543 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
544 goto Done;
545 *pBuf4 = Item.val.string.ptr;
546 *pBuf4Len = Item.val.string.len;
547
548 nReturn = 0;
549
550Done:
551 return(nReturn);
552}
553
554
555
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800556
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800557int SimpleArrayTest()
558{
559 uint8_t *pEncoded;
560 size_t nEncodedLen;
561
562 int64_t i1, i2;
563 size_t i3, i4;
564 const uint8_t *s3, *s4;
565
566
567 if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
568 return(-1);
569 }
570
571 ParseOrderedArray(pEncoded, nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
572
573 if(i1 != 23 ||
574 i2 != 6000 ||
575 i3 != 8 ||
576 i4 != 11 ||
Laurence Lundbladea44d5062018-10-17 18:45:12 +0530577 memcmp("galactic", s3, 8) !=0 ||
578 memcmp("haven token", s4, 11) !=0) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800579 printf("SimpleArraryTest Failed\n");
580 return(-1);
581 }
582
583 return(0);
584}
585
586
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800587
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700588static uint8_t spDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80};
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800589
590int ParseDeepArrayTest()
591{
592 QCBORDecodeContext DCtx;
593 int nReturn = 0;
594 int i;
595
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700596 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDeepArrays), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800597
598 for(i = 0; i < 10; i++) {
599 QCBORItem Item;
600
601 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
602 Item.uDataType != QCBOR_TYPE_ARRAY ||
603 Item.uNestingLevel != i) {
604 nReturn = -1;
605 break;
606 }
607 }
608
609 return(nReturn);
610}
611
612
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700613static uint8_t spTooDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80};
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800614
615int ParseTooDeepArrayTest()
616{
617 QCBORDecodeContext DCtx;
618 int nReturn = 0;
619 int i;
620 QCBORItem Item;
621
622
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700623 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooDeepArrays), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800624
625 for(i = 0; i < 10; i++) {
626
627 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
628 Item.uDataType != QCBOR_TYPE_ARRAY ||
629 Item.uNestingLevel != i) {
630 nReturn = -1;
631 break;
632 }
633 }
634
635 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP)
636 nReturn = -1;
637
638 return(nReturn);
639}
640
641
642
643
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800644int ShortBufferParseTest()
645{
646 int nResult = 0;
647 QCBORDecodeContext DCtx;
648 int num;
649
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700650 for(num = sizeof(spExpectedEncodedInts)-1; num; num--) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800651 int n;
652
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700653 QCBORDecode_Init(&DCtx, (UsefulBufC){spExpectedEncodedInts, num}, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800654
655 n = IntegerValuesParseTestInternal(&DCtx);
656
657 //printf("Len %d, result: %d\n", num, n);
658
659 if(n != QCBOR_ERR_HIT_END) {
660 nResult = -1;
661 goto Done;
662 }
663 }
664Done:
665 return nResult;
666}
667
668
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800669
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800670int ShortBufferParseTest2()
671{
672 uint8_t *pEncoded;
673 int nReturn;
674 size_t nEncodedLen;
675
676 int64_t i1, i2;
677 size_t i3, i4;
678 const uint8_t *s3, *s4;
679
680 nReturn = 0;
681
682 if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
683 return(-1);
684 }
685
686 //printencoded(pEncoded, nEncodedLen);
687
688 for(nEncodedLen--; nEncodedLen; nEncodedLen--) {
689 int nResult = ParseOrderedArray(pEncoded, (uint32_t)nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
690 if(nResult == 0) {
691 nReturn = -1;
692 }
693 }
694
695 return(nReturn);
696}
697
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530698/*
699 Decode and thoroughly check a moderately complex
700 set of maps
701 */
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800702static int ParseMapTest1()
703{
704 QCBORDecodeContext DCtx;
705 QCBORItem Item;
706 int nCBORError;
707
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800708 QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
709
710 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
711 return nCBORError;
712 if(Item.uDataType != QCBOR_TYPE_MAP ||
713 Item.val.uCount != 3)
714 return -1;
715
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800716 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
717 return nCBORError;
718 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
719 Item.label.string.len != 13 ||
720 Item.uDataType != QCBOR_TYPE_INT64 ||
721 Item.val.int64 != 42 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530722 Item.uDataAlloc ||
723 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800724 memcmp(Item.label.string.ptr, "first integer", 13))
725 return -1;
726
727 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
728 return nCBORError;
729 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
730 Item.label.string.len != 23 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530731 Item.uDataAlloc ||
732 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800733 memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
734 Item.uDataType != QCBOR_TYPE_ARRAY ||
735 Item.val.uCount != 2)
736 return -1;
737
738 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
739 return nCBORError;
740 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
741 Item.val.string.len != 7 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530742 Item.uDataAlloc ||
743 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800744 memcmp(Item.val.string.ptr, "string1", 7))
745 return -1;
746
747 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
748 return nCBORError;
749 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
750 Item.val.string.len != 7 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530751 Item.uDataAlloc ||
752 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800753 memcmp(Item.val.string.ptr, "string2", 7))
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 != 12 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530760 Item.uDataAlloc ||
761 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800762 memcmp(Item.label.string.ptr, "map in a map", 12) ||
763 Item.uDataType != QCBOR_TYPE_MAP ||
764 Item.val.uCount != 4)
765 return -1;
766
767 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
768 return nCBORError;
769 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
770 Item.label.string.len != 7 ||
771 memcmp(Item.label.string.ptr, "bytes 1", 7)||
772 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
773 Item.val.string.len != 4 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530774 Item.uDataAlloc ||
775 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800776 memcmp(Item.val.string.ptr, "xxxx", 4))
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 != 7 ||
783 memcmp(Item.label.string.ptr, "bytes 2", 7) ||
784 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
785 Item.val.string.len != 4 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530786 Item.uDataAlloc ||
787 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800788 memcmp(Item.val.string.ptr, "yyyy", 4))
789 return -1;
790
791 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
792 return nCBORError;
793 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
794 Item.label.string.len != 11 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530795 Item.uDataAlloc ||
796 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800797 memcmp(Item.label.string.ptr, "another int", 11) ||
798 Item.uDataType != QCBOR_TYPE_INT64 ||
799 Item.val.int64 != 98)
800 return -1;
801
802 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
803 return nCBORError;
804 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
805 Item.label.string.len != 6 ||
806 memcmp(Item.label.string.ptr, "text 2", 6)||
807 Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
808 Item.val.string.len != 30 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530809 Item.uDataAlloc ||
810 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800811 memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
812 return -1;
813
814 return 0;
815}
816
817
818
819/*
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530820 Fully or partially decode pValidMapEncoded. When
821 partially decoding check for the right error code.
822 How much partial decoding depends on nLevel.
823
824 The partial decodes test error conditions of
825 incomplete encoded input.
826
827 This could be combined with the above test
828 and made prettier and maybe a little more
829 thorough.
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800830 */
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800831static int ExtraBytesTest(int nLevel)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800832{
833 QCBORDecodeContext DCtx;
834 QCBORItem Item;
835 int nCBORError;
836
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800837 QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
838
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800839 if(nLevel < 1) {
840 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
841 return -1;
842 } else {
843 return 0;
844 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800845 }
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530846
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800847
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800848 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
849 return nCBORError;
850 if(Item.uDataType != QCBOR_TYPE_MAP ||
851 Item.val.uCount != 3)
852 return -1;
853
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800854 if(nLevel < 2) {
855 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
856 return -1;
857 } else {
858 return 0;
859 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800860 }
861
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800862
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800863 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
864 return nCBORError;
865 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
866 Item.label.string.len != 13 ||
867 Item.uDataType != QCBOR_TYPE_INT64 ||
868 Item.val.uCount != 42 ||
869 memcmp(Item.label.string.ptr, "first integer", 13))
870 return -1;
871
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800872 if(nLevel < 3) {
873 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
874 return -1;
875 } else {
876 return 0;
877 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800878 }
879
880 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
881 return nCBORError;
882 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
883 Item.label.string.len != 23 ||
884 memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
885 Item.uDataType != QCBOR_TYPE_ARRAY ||
886 Item.val.uCount != 2)
887 return -1;
888
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800889
890 if(nLevel < 4) {
891 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
892 return -1;
893 } else {
894 return 0;
895 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800896 }
897
898
899 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
900 return nCBORError;
901 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
902 Item.val.string.len != 7 ||
903 memcmp(Item.val.string.ptr, "string1", 7))
904 return -1;
905
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800906 if(nLevel < 5) {
907 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
908 return -1;
909 } else {
910 return 0;
911 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800912 }
913
914 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
915 return nCBORError;
916 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
917 Item.val.string.len != 7 ||
918 memcmp(Item.val.string.ptr, "string2", 7))
919 return -1;
920
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800921 if(nLevel < 6) {
922 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
923 return -1;
924 } else {
925 return 0;
926 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800927 }
928
929 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
930 return nCBORError;
931 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
932 Item.label.string.len != 12 ||
933 memcmp(Item.label.string.ptr, "map in a map", 12) ||
934 Item.uDataType != QCBOR_TYPE_MAP ||
935 Item.val.uCount != 4)
936 return -1;
937
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800938 if(nLevel < 7) {
939 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
940 return -1;
941 } else {
942 return 0;
943 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800944 }
945
946 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
947 return nCBORError;
948 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
949 Item.label.string.len != 7 ||
950 memcmp(Item.label.string.ptr, "bytes 1", 7)||
951 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
952 Item.val.string.len != 4 ||
953 memcmp(Item.val.string.ptr, "xxxx", 4))
954 return -1;
955
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800956 if(nLevel < 8) {
957 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
958 return -1;
959 } else {
960 return 0;
961 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800962 }
963
964 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
965 return nCBORError;
966 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
967 Item.label.string.len != 7 ||
968 memcmp(Item.label.string.ptr, "bytes 2", 7) ||
969 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
970 Item.val.string.len != 4 ||
971 memcmp(Item.val.string.ptr, "yyyy", 4))
972 return -1;
973
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800974 if(nLevel < 9) {
975 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
976 return -1;
977 } else {
978 return 0;
979 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800980 }
981
982 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
983 return nCBORError;
984 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
985 Item.label.string.len != 11 ||
986 memcmp(Item.label.string.ptr, "another int", 11) ||
987 Item.uDataType != QCBOR_TYPE_INT64 ||
988 Item.val.int64 != 98)
989 return -1;
990
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800991 if(nLevel < 10) {
992 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
993 return -1;
994 } else {
995 return 0;
996 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800997 }
998
999 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1000 return nCBORError;
1001 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
1002 Item.label.string.len != 6 ||
1003 memcmp(Item.label.string.ptr, "text 2", 6)||
1004 Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1005 Item.val.string.len != 30 ||
1006 memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
1007 return -1;
1008
Laurence Lundbladefab1b522018-10-19 13:40:52 +05301009 if(QCBORDecode_Finish(&DCtx)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001010 return -1;
1011 }
1012
1013 return 0;
1014}
1015
1016
1017
1018
1019int ParseMapTest()
1020{
Laurence Lundbladefab1b522018-10-19 13:40:52 +05301021 // Parse a moderatly complex map structure very thoroughl
1022 int n = ParseMapTest1();
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001023
1024 if(!n) {
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +08001025 for(int i = 0; i < 10; i++) {
1026 n = ExtraBytesTest(i);
1027 if(n) {
1028 break;
1029 }
1030 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001031 }
1032
1033 return(n);
1034}
1035
1036
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001037static uint8_t spSimpleValues[] = {0x8a, 0xf4, 0xf5, 0xf6, 0xf7, 0xff, 0xe0, 0xf3, 0xf8, 0x00, 0xf8, 0x13, 0xf8, 0x1f, 0xf8, 0x20, 0xf8, 0xff};
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001038
1039int ParseSimpleTest()
1040{
1041 QCBORDecodeContext DCtx;
1042 QCBORItem Item;
1043 int nCBORError;
1044
1045
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001046 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSimpleValues), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001047
1048
1049 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1050 return nCBORError;
1051 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1052 Item.val.uCount != 10)
1053 return -1;
1054
1055 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1056 return nCBORError;
1057 if(Item.uDataType != QCBOR_TYPE_FALSE)
1058 return -1;
1059
1060 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1061 return nCBORError;
1062 if(Item.uDataType != QCBOR_TYPE_TRUE)
1063 return -1;
1064
1065 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1066 return nCBORError;
1067 if(Item.uDataType != QCBOR_TYPE_NULL)
1068 return -1;
1069
1070 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1071 return nCBORError;
1072 if(Item.uDataType != QCBOR_TYPE_UNDEF)
1073 return -1;
1074
1075 // A break
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001076 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_BAD_BREAK)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001077 return -1;
1078
1079 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1080 return nCBORError;
1081 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 0)
1082 return -1;
1083
1084 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1085 return nCBORError;
1086 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 19)
1087 return -1;
1088
1089 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
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((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1099 return nCBORError;
1100 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 32)
1101 return -1;
1102
1103 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1104 return nCBORError;
1105 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 255)
1106 return -1;
1107
1108 return 0;
1109
1110}
1111
1112
1113struct FailInput {
1114 UsefulBufC Input;
1115 int nError;
1116};
1117
1118
1119struct FailInput Failures[] = {
1120 { {(uint8_t[]){0x18}, 1}, QCBOR_ERR_HIT_END }, // 1 byte integer missing the byte
1121 { {(uint8_t[]){0x1c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1122 { {(uint8_t[]){0x1d}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 29
1123 { {(uint8_t[]){0x1e}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 30
1124 { {(uint8_t[]){0x1f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length integer
1125 { {(uint8_t[]){0x3c}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1126 { {(uint8_t[]){0x3d}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1127 { {(uint8_t[]){0x3e}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1128 { {(uint8_t[]){0x3f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length negative integer
1129 { {(uint8_t[]){0x41}, 1}, QCBOR_ERR_HIT_END }, // Short byte string
1130 { {(uint8_t[]){0x5c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1131 { {(uint8_t[]){0x5f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length byte string
1132 { {(uint8_t[]){0x61}, 1}, QCBOR_ERR_HIT_END }, // Short UTF-8 string
1133 { {(uint8_t[]){0x7c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1134 { {(uint8_t[]){0x7f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length UTF-8 string
1135 { {(uint8_t[]){0xff}, 1}, QCBOR_ERR_UNSUPPORTED } , // break
1136 { {(uint8_t[]){0xf8, 0x00}, 2}, QCBOR_ERR_INVALID_CBOR }, // An invalid encoding of a simple type
1137 { {(uint8_t[]){0xf8, 0x1f}, 2}, QCBOR_ERR_INVALID_CBOR }, // An invalid encoding of a simple type
1138 { {(uint8_t[]){0xc0, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG }, // Text-based date, with an integer
1139 { {(uint8_t[]){0xc1, 0x41, 0x33}, 3}, QCBOR_ERR_BAD_OPT_TAG }, // Epoch date, with an byte string
1140 { {(uint8_t[]){0xc1, 0xc0, 0x00}, 3}, QCBOR_ERR_BAD_OPT_TAG }, // tagged as both epoch and string dates
1141 { {(uint8_t[]){0xc2, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG } // big num tagged an int, not a byte string
1142
1143};
1144
1145
1146void Dump(UsefulBufC Input, int x)
1147{
1148 char label[10];
1149
1150 sprintf(label, "%d", x);
1151
1152 printencoded(label, Input.ptr, Input.len);
1153}
1154
1155
1156int FailureTests()
1157{
1158 int nResult = 0;
1159
1160 struct FailInput *pFEnd = &Failures[0] + sizeof(Failures)/sizeof(struct FailInput);
1161
1162 for(struct FailInput *pF = &Failures[0]; pF < pFEnd ;pF++) {
1163 QCBORDecodeContext DCtx;
1164 QCBORItem Item;
1165 int nCBORError;
1166
1167 QCBORDecode_Init(&DCtx, pF->Input, QCBOR_DECODE_MODE_NORMAL);
1168
1169 while(1) {
1170 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1171 if(QCBOR_ERR_HIT_END == nCBORError) {
1172 break;
1173 }
1174 if(nCBORError != pF->nError) {
1175 nResult = 1;
1176 // Dump(pF->Input, nCBORError);
1177 break;
1178 }
1179 }
1180 }
1181
1182 {
1183 QCBORDecodeContext DCtx;
1184 QCBORItem Item;
1185 int nCBORError;
1186
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001187 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSimpleValues), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001188
1189 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1190 return nCBORError;
1191 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1192 Item.val.uCount != 10)
1193 return -1;
1194
1195 DCtx.InBuf.magic = 0; // Corrupt the UsefulInputBuf
1196
1197 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1198 if(nCBORError != QCBOR_ERR_HIT_END)
1199 return -1;
1200 }
1201
1202
1203 return nResult;
1204}
1205
1206
1207
1208
1209static void Recurser(uint8_t *pBuf, int nLen, int nLenMax)
1210{
1211
1212 if(nLen >= nLenMax) {
1213 return;
1214 }
1215
1216 //printf("__%d__%d__\n", nLen, nLenMax);
1217
1218 for(int i = 0; i < 256; i++) {
1219 pBuf[nLen] = i;
1220
1221 QCBORDecodeContext DCtx;
1222 QCBORItem Item;
1223 int nCBORError;
1224
1225 UsefulBufC Input = {pBuf, nLen+1};
1226
1227 QCBORDecode_Init(&DCtx, Input, QCBOR_DECODE_MODE_NORMAL);
1228
1229 while(1) {
1230 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1231 if(QCBOR_ERR_HIT_END == nCBORError) {
1232 break;
1233 }
1234 if(nCBORError != QCBOR_SUCCESS) {
1235 if(nCBORError != QCBOR_ERR_UNSUPPORTED && nCBORError != QCBOR_ERR_HIT_END && nCBORError != QCBOR_ERR_INVALID_CBOR) {
1236 //Dump(Input, nCBORError);
1237 }
1238 break;
1239 }
1240 }
1241 //Dump(Input, -1);
1242
1243
1244 Recurser(pBuf, nLen+1, nLenMax);
1245 }
1246}
1247
1248
1249/*
1250 Runs all possible input strings of a given length. This is set to 3 to make the test
1251 run in reasonable time.
1252 Main point of this test is to not crash.
1253 */
1254
1255int ComprehensiveInputTest()
1256{
1257 uint8_t pBuf[3]; // 3 keeps it running in reasonable time. 4 takes tens of minutes.
1258
1259 Recurser(pBuf, 0, sizeof(pBuf));
1260
1261 return 0;
1262}
1263
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001264static uint8_t spDateTestInput[] = {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001265 0xc0, // tag for string date
1266 0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
1267
1268 0xc1, // tag for epoch date
1269 0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
1270
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001271 // CBOR_TAG_B64
1272 0xc1, 0xcf, 0xd8, 0x22, // 0xee, // Epoch date with extra tags TODO: fix this test
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001273 0x1a, 0x53, 0x72, 0x4E, 0x01,
1274
1275 0xc1, // tag for epoch date
1276 0x1b, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // Too large integer
1277
1278 0xc1, // tag for epoch date
1279 0xfa, 0x3f, 0x8c, 0xcc, 0xcd, // double with value 1.1
1280
1281 0xc1, // tag for epoch date
1282 0xfa, 0x7f, 0x7f, 0xff, 0xff // 3.4028234663852886e+38 too large
1283
1284};
1285
1286
1287// have to check float expected only to within an epsilon
1288int CHECK_EXPECTED_DOUBLE(double val, double expected) {
1289
1290 double diff = val - expected;
1291
1292 diff = fabs(diff);
1293
1294 return diff > 0.0000001;
1295}
1296
1297
1298int DateParseTest()
1299{
1300 QCBORDecodeContext DCtx;
1301 QCBORItem Item;
1302 int nCBORError;
1303
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001304 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001305
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001306 const uint64_t uTags[] = {15};
1307 QCBORTagListIn TagList = {1, uTags};
1308
1309 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
1310
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001311 // String date
1312 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1313 return -1;
1314 if(Item.uDataType != QCBOR_TYPE_DATE_STRING ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001315 UsefulBuf_Compare(Item.val.dateString, UsefulBuf_FromSZ("1985-04-12"))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001316 return -1;
1317 }
1318
1319 // Epoch date
1320 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1321 return -1;
1322 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1323 Item.val.epochDate.nSeconds != 1400000000 ||
1324 Item.val.epochDate.fSecondsFraction != 0 ) {
1325 return -1;
1326 }
1327
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001328 // Epoch date with extra CBOR_TAG_B64 tag that doesn't really mean anything
1329 // but want to be sure extra tag doesn't cause a problem
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001330 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1331 return -1;
1332 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1333 Item.val.epochDate.nSeconds != 1400000001 ||
1334 Item.val.epochDate.fSecondsFraction != 0 ||
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001335 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_B64)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001336 return -1;
1337 }
1338
1339 // Epoch date that is too large for our representation
1340 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
1341 return -1;
1342 }
1343
1344 // Epoch date in float format with fractional seconds
1345 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1346 return -1;
1347 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1348 Item.val.epochDate.nSeconds != 1 ||
1349 CHECK_EXPECTED_DOUBLE(Item.val.epochDate.fSecondsFraction, 0.1 )) {
1350 return -1;
1351 }
1352
1353 // Epoch date float that is too large for our representation
1354 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
1355 return -1;
1356 }
1357
1358 // TODO: could use a few more tests with float, double, and half precsion and negative (but coverage is still pretty good)
1359
1360 return 0;
1361}
1362
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001363// Really simple basic input for tagging test
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001364static uint8_t spOptTestInput[] = {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001365 0xd9, 0xd9, 0xf7, // CBOR magic number
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001366 0x81, // Array of one
1367 0xd8, 0x04, // non-preferred serialization of tag 4
1368 0x82, 0x01, 0x03}; // fraction 1/3
1369
1370static uint8_t spEncodedLargeTag[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x80};
1371
1372// 0x9192939495969798, 0x88, 0x01, 0x04
1373static uint8_t spLotsOfTags[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0xd8, 0x88, 0xc5, 0xc4, 0x80};
1374
1375/*
1376 The cbor.me parse of this.
1377 55799(55799(55799({6(7(-23)): 5859837686836516696(7({7(-20): 11({17(-18): 17(17(17("Organization"))),
1378 9(-17): 773("SSG"), -15: 4(5(6(7(8(9(10(11(12(13(14(15("Confusion")))))))))))), 17(-16): 17("San Diego"),
1379 17(-14): 17("US")}), 23(-19): 19({-11: 9({-9: -7}),
1380 90599561(90599561(90599561(-10))): 12(h'0102030405060708090A')})})),
1381 16(-22): 23({11(8(7(-5))): 8(-3)})})))
1382 */
1383static uint8_t spCSRWithTags[] = {
1384 0xd9, 0xd9, 0xf7, 0xd9, 0xd9, 0xf7, 0xd9, 0xd9, 0xf7, 0xa2,
1385 0xc6, 0xc7, 0x36,
1386 0xdb, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0xc7, 0xa2,
1387 0xda, 0x00, 0x00, 0x00, 0x07, 0x33,
1388 0xcb, 0xa5,
1389 0xd1, 0x31,
1390 0xd1, 0xd1, 0xd1, 0x6c,
1391 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
1392 0xc9, 0x30,
1393 0xd9, 0x03, 0x05, 0x63,
1394 0x53, 0x53, 0x47,
1395 0x2e,
1396 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0x69,
1397 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x69, 0x6f, 0x6e,
1398 0xd1, 0x2f,
1399 0xd1, 0x69,
1400 0x53, 0x61, 0x6e, 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f,
1401 0xd1, 0x2d,
1402 0xd1, 0x62,
1403 0x55, 0x53,
1404 0xd7, 0x32,
1405 0xd3, 0xa2,
1406 0x2a,
1407 0xc9, 0xa1,
1408 0x28,
1409 0x26,
1410 0xda, 0x05, 0x66, 0x70, 0x89, 0xda, 0x05, 0x66, 0x70, 0x89, 0xda, 0x05, 0x66, 0x70, 0x89, 0x29,
1411 0xcc, 0x4a,
1412 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,0x07, 0x08, 0x09, 0x0a,
1413 0xd0, 0x35,
1414 0xd7, 0xa1,
1415 0xcb, 0xc8, 0xc7, 0x24,
1416 0xc8, 0x22};
1417
1418static int CheckCSRMaps(QCBORDecodeContext *pDC);
1419
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001420
1421int OptTagParseTest()
1422{
1423 QCBORDecodeContext DCtx;
1424 QCBORItem Item;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001425
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001426 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spOptTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001427
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001428 //-------------------------
1429 // This text matches the magic number tag and the fraction tag
1430 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1431 return -2;
1432 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001433 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001434 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC)) {
1435 return -3;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001436 }
1437
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001438 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1439 return -4;
1440 }
1441 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1442 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_FRACTION) ||
1443 Item.val.uCount != 2) {
1444 return -5;
1445 }
1446
1447 // --------------------------------
1448 // This test decodes the very large tag, but it is not in
1449 // any list so it is ignored.
1450 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
1451 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1452 return -6;
1453 }
1454 if(Item.uTagBits) {
1455 return -7;
1456 }
1457
1458 // ----------------------------------
1459 // This test sets up a caller-config list that includes the very large tage and then matches it.
1460 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
1461 const uint64_t puList[] = {0x9192939495969798, 257};
1462 const QCBORTagListIn TL = {2, puList};
1463 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TL);
1464
1465 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1466 return -8;
1467 }
1468 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1469 !QCBORDecode_IsTagged(&DCtx, &Item, 0x9192939495969798) ||
1470 QCBORDecode_IsTagged(&DCtx, &Item, 257) ||
1471 QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_BIGFLOAT) ||
1472 Item.val.uCount != 0) {
1473 return -9;
1474 }
1475
1476 //------------------------
1477 // This test sets up a caller-configured list, and looks up something not in it
1478 const uint64_t puLongList[17] = {1,2,1};
1479 const QCBORTagListIn TLLong = {17, puLongList};
1480 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
1481 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TLLong);
1482 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1483 return -11;
1484 }
1485
1486 // -----------------------
1487 // This tests retrievel of the full tag list
1488 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
1489 uint64_t puTags[16];
1490 QCBORTagListOut Out = {0, 4, puTags};
1491 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1492 return -12;
1493 }
1494 if(puTags[0] != 0x9192939495969798 ||
1495 puTags[1] != 0x88 ||
1496 puTags[2] != 0x05 ||
1497 puTags[3] != 0x04) {
1498 return -13;
1499 }
1500
1501 // ----------------------
1502 // This text if too small of an out list
1503 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
1504 QCBORTagListOut OutSmall = {0, 3, puTags};
1505 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &OutSmall) != QCBOR_ERR_TOO_MANY_TAGS) {
1506 return -14;
1507 }
1508
1509 // ---------------
1510 // Parse a version of the "CSR" that has had a ton of tags randomly inserted
1511 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
1512 int n = CheckCSRMaps(&DCtx);
1513 if(n) {
1514 return n-2000;
1515 }
1516
1517 Out = (QCBORTagListOut){0,16, puTags};
1518 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
1519
1520 const uint64_t puTagList[] = {773, 1, 90599561};
1521 const QCBORTagListIn TagList = {3, puTagList};
1522 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
1523
1524
1525 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1526 return -100;
1527 }
1528 if(Item.uDataType != QCBOR_TYPE_MAP ||
1529 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC) ||
1530 QCBORDecode_IsTagged(&DCtx, &Item, 90599561) ||
1531 QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_DATE_EPOCH) ||
1532 Item.val.uCount != 2 ||
1533 puTags[0] != CBOR_TAG_CBOR_MAGIC ||
1534 puTags[1] != CBOR_TAG_CBOR_MAGIC ||
1535 puTags[2] != CBOR_TAG_CBOR_MAGIC ||
1536 Out.uNumUsed != 3) {
1537 return -101;
1538 }
1539
1540 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1541 return -102;
1542 }
1543 if(Item.uDataType != QCBOR_TYPE_MAP ||
1544 QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC) ||
1545 QCBORDecode_IsTagged(&DCtx, &Item, 6) ||
1546 QCBORDecode_IsTagged(&DCtx, &Item, 7) || // item is tagged 7, but 7 is not configured to be recognized
1547 Item.val.uCount != 2 ||
1548 puTags[0] != 5859837686836516696 ||
1549 puTags[1] != 7 ||
1550 Out.uNumUsed != 2) {
1551 return -103;
1552 }
1553
1554 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1555 return -104;
1556 }
1557 if(Item.uDataType != QCBOR_TYPE_MAP ||
1558 Item.uTagBits ||
1559 Item.val.uCount != 5 ||
1560 puTags[0] != 0x0b ||
1561 Out.uNumUsed != 1) {
1562 return -105;
1563 }
1564
1565 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1566 return -106;
1567 }
1568 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1569 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_COSE_MAC0) ||
1570 Item.val.string.len != 12 ||
1571 puTags[0] != CBOR_TAG_COSE_MAC0 ||
1572 puTags[1] != CBOR_TAG_COSE_MAC0 ||
1573 puTags[2] != CBOR_TAG_COSE_MAC0 ||
1574 Out.uNumUsed != 3) {
1575 return -105;
1576 }
1577
1578 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1579 return -107;
1580 }
1581 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1582 !QCBORDecode_IsTagged(&DCtx, &Item, 773) ||
1583 Item.val.string.len != 3 ||
1584 puTags[0] != 773 ||
1585 Out.uNumUsed != 1) {
1586 return -108;
1587 }
1588
1589 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1590 return -109;
1591 }
1592 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1593 !QCBORDecode_IsTagged(&DCtx, &Item, 4) ||
1594 Item.val.string.len != 9 ||
1595 puTags[0] != 4 ||
1596 puTags[11] != 0x0f ||
1597 Out.uNumUsed != 12) {
1598 return -110;
1599 }
1600
1601 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1602 return -111;
1603 }
1604 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1605 !QCBORDecode_IsTagged(&DCtx, &Item, 17) ||
1606 Item.val.string.len != 9 ||
1607 puTags[0] != 17 ||
1608 Out.uNumUsed != 1) {
1609 return -112;
1610 }
1611
1612 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1613 return -111;
1614 }
1615 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1616 !QCBORDecode_IsTagged(&DCtx, &Item, 17) ||
1617 Item.val.string.len != 2 ||
1618 puTags[0] != 17 ||
1619 Out.uNumUsed != 1) {
1620 return -112;
1621 }
1622
1623 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1624 return -113;
1625 }
1626 if(Item.uDataType != QCBOR_TYPE_MAP ||
1627 QCBORDecode_IsTagged(&DCtx, &Item, 19) ||
1628 Item.val.uCount != 2 ||
1629 puTags[0] != 19 ||
1630 Out.uNumUsed != 1) {
1631 return -114;
1632 }
1633
1634 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1635 return -115;
1636 }
1637 if(Item.uDataType != QCBOR_TYPE_MAP ||
1638 QCBORDecode_IsTagged(&DCtx, &Item, 9) ||
1639 Item.uTagBits ||
1640 Item.val.uCount != 1 ||
1641 puTags[0] != 9 ||
1642 Out.uNumUsed != 1) {
1643 return -116;
1644 }
1645
1646 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1647 return -116;
1648 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001649 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001650 Item.val.int64 != -7 ||
1651 Item.uTagBits ||
1652 Out.uNumUsed != 0) {
1653 return -117;
1654 }
1655
1656 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1657 return -118;
1658 }
1659 if(Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
1660 Item.val.string.len != 10 ||
1661 Item.uTagBits ||
1662 puTags[0] != 12 ||
1663 Out.uNumUsed != 1) {
1664 return -119;
1665 }
1666
1667 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1668 return -120;
1669 }
1670 if(Item.uDataType != QCBOR_TYPE_MAP ||
1671 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_ENC_AS_B16) ||
1672 Item.val.uCount != 1 ||
1673 puTags[0] != 0x17 ||
1674 Out.uNumUsed != 1) {
1675 return -121;
1676 }
1677
1678 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1679 return -122;
1680 }
1681 if(Item.uDataType != QCBOR_TYPE_INT64 ||
1682 QCBORDecode_IsTagged(&DCtx, &Item, 8) ||
1683 Item.val.int64 != -3 ||
1684 puTags[0] != 8 ||
1685 Out.uNumUsed != 1) {
1686 return -123;
1687 }
1688
1689 if(QCBORDecode_Finish(&DCtx)) {
1690 return -124;
1691 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001692
1693 return 0;
1694}
1695
1696
1697
1698
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001699static uint8_t spBigNumInput[] = {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001700 0x83,
1701 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1702 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1703 0xA4,
1704 0x63, 0x42, 0x4E, 0x2B,
1705 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1706 0x18, 0x40,
1707 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1708 0x63, 0x42, 0x4E, 0x2D,
1709 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1710 0x38, 0x3F,
1711 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1712
1713
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001714static uint8_t spBigNum[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001715
1716
1717int BignumParseTest()
1718{
1719 QCBORDecodeContext DCtx;
1720 QCBORItem Item;
1721 int nCBORError;
1722
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001723 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNumInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001724
1725
1726 //
1727 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1728 return -1;
1729 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1730 return -1;
1731 }
1732
1733 //
1734 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1735 return -1;
1736 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001737 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001738 return -1;
1739 }
1740
1741 //
1742 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1743 return -1;
1744 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001745 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001746 return -1;
1747 }
1748
1749 //
1750 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1751 return -1;
1752 if(Item.uDataType != QCBOR_TYPE_MAP) {
1753 return -1;
1754 }
1755
1756 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1757 return -1;
1758 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1759 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001760 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001761 return -1;
1762 }
1763
1764 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1765 return -1;
1766 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1767 Item.uLabelType != QCBOR_TYPE_INT64 ||
1768 Item.label.int64 != 64 ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001769 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001770 return -1;
1771 }
1772
1773 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1774 return -1;
1775 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1776 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001777 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001778 return -1;
1779 }
1780
1781 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1782 return -1;
1783 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1784 Item.uLabelType != QCBOR_TYPE_INT64 ||
1785 Item.label.int64 != -64 ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001786 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001787 return -1;
1788 }
1789
1790 return 0;
1791}
1792
1793
1794
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301795static 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 +08001796{
1797 QCBORItem Item;
1798 int nCBORError;
1799
1800 if((nCBORError = QCBORDecode_GetNext(pCtx, &Item))) return -1;
1801 if(Item.uDataType != uDataType) return -1;
1802 if(uNestingLevel > 0) {
1803 if(Item.uLabelType != QCBOR_TYPE_INT64 && Item.uLabelType != QCBOR_TYPE_UINT64) return -1;
1804 if(Item.uLabelType == QCBOR_TYPE_INT64) {
1805 if(Item.label.int64 != nLabel) return -1;
1806 } else {
Laurence Lundblade570fab52018-10-13 18:28:27 +08001807 if(Item.label.uint64 != (uint64_t)nLabel) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001808 }
1809 }
1810 if(Item.uNestingLevel != uNestingLevel) return -1;
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301811 if(Item.uNextNestLevel != uNextNest) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001812
1813 if(pItem) {
1814 *pItem = Item;
1815 }
1816 return 0;
1817}
1818
1819
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001820// Same code checks definite and indefinite length versions of the map
1821static int CheckCSRMaps(QCBORDecodeContext *pDC)
1822{
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301823 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 0, 1, 0, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001824
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301825 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -23, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001826
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301827 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -20, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001828
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301829 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -18, NULL)) return -1;
1830 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -17, NULL)) return -1;
1831 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -15, NULL)) return -1;
1832 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -16, NULL)) return -1;
1833 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 2, -14, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001834
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301835 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -19, NULL)) return -1;
1836 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 3, 4, -11, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001837
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301838 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 4, 3, -9, NULL)) return -1;
1839 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_BYTE_STRING, 3, 1, -10, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001840
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301841 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -22, NULL)) return -1;
1842 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 2, 0, -5, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001843
1844 if(QCBORDecode_Finish(pDC)) return -2;
1845
1846 return 0;
1847}
1848
1849
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001850/*
1851// cbor.me decoded output
1852{
1853 -23: {
1854 -20: {
1855 -18: "Organization",
1856 -17: "SSG",
1857 -15: "Confusion",
1858 -16: "San Diego",
1859 -14: "US"
1860 },
1861 -19: {
1862 -11: {
1863 -9: -7
1864 },
1865 -10: '\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\n'
1866 }
1867 },
1868 -22: {
1869 -5: -3
1870 }
1871}
1872 */
1873
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001874
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001875static uint8_t spCSRInput[] = {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001876 0xa2, 0x36, 0xa2, 0x33, 0xa5, 0x31, 0x6c, 0x4f,
1877 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1878 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1879 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1880 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1881 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1882 0x55, 0x53, 0x32, 0xa2, 0x2a, 0xa1, 0x28, 0x26,
1883 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1884 0x07, 0x08, 0x09, 0x0a, 0x35, 0xa1, 0x24, 0x22};
1885
1886int NestedMapTest()
1887{
1888 QCBORDecodeContext DCtx;
1889
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001890 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001891
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001892 return CheckCSRMaps(&DCtx);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001893}
1894
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001895// Same map as above, but using indefinite lengths
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001896static uint8_t spCSRInputIndefLen[] = {
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001897 0xbf, 0x36, 0xbf, 0x33, 0xbf, 0x31, 0x6c, 0x4f,
1898 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1899 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1900 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1901 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1902 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001903 0x55, 0x53, 0xff, 0x32, 0xbf, 0x2a, 0xbf, 0x28,
1904 0x26, 0xff, 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04,
1905 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0xff, 0xff,
1906 0x35, 0xbf, 0x24, 0x22, 0xff, 0xff};
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001907
1908int NestedMapTestIndefLen()
1909{
1910 QCBORDecodeContext DCtx;
1911
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001912 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInputIndefLen), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001913
1914 return CheckCSRMaps(&DCtx);
1915}
1916
1917
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001918
Laurence Lundblade17ede402018-10-13 11:43:07 +08001919static UsefulBufC make_nested_indefinite_arrays(int n, UsefulBuf Storage)
1920{
1921 UsefulOutBuf UOB;
1922 UsefulOutBuf_Init(&UOB, Storage);
1923
1924 int i;
1925 for(i = 0; i < n; i++) {
1926 UsefulOutBuf_AppendByte(&UOB, 0x9f);
1927 }
1928
1929 for(i = 0; i < n; i++) {
1930 UsefulOutBuf_AppendByte(&UOB, 0xff);
1931 }
1932 return UsefulOutBuf_OutUBuf(&UOB);
1933}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001934
1935
Laurence Lundblade17ede402018-10-13 11:43:07 +08001936static int parse_indeflen_nested(UsefulBufC Nested, int nNestLevel)
1937{
1938 QCBORDecodeContext DC;
1939 QCBORDecode_Init(&DC, Nested, 0);
1940
1941 int j;
1942 for(j = 0; j < nNestLevel; j++) {
1943 QCBORItem Item;
1944 int nReturn = QCBORDecode_GetNext(&DC, &Item);
1945 if(j >= QCBOR_MAX_ARRAY_NESTING) {
1946 // Should be in error
1947 if(nReturn != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP) {
1948 return -4;
1949 } else {
1950 return 0; // Decoding doesn't recover after an error
1951 }
1952 } else {
1953 // Should be no error
1954 if(nReturn) {
1955 return -9; // Should not have got an error
1956 }
1957 }
1958 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1959 return -7;
1960 }
1961 }
1962 int nReturn = QCBORDecode_Finish(&DC);
1963 if(nReturn) {
1964 return -3;
1965 }
1966 return 0;
1967}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001968
1969
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301970int IndefiniteLengthNestTest()
Laurence Lundblade17ede402018-10-13 11:43:07 +08001971{
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301972 UsefulBuf_MAKE_STACK_UB(Storage, 50);
Laurence Lundblade17ede402018-10-13 11:43:07 +08001973 int i;
Laurence Lundblade6de37062018-10-15 12:22:42 +05301974 for(i=1; i < QCBOR_MAX_ARRAY_NESTING+4; i++) {
Laurence Lundblade17ede402018-10-13 11:43:07 +08001975 UsefulBufC Nested = make_nested_indefinite_arrays(i, Storage);
1976 int nReturn = parse_indeflen_nested(Nested, i);
1977 if(nReturn) {
1978 return nReturn;
1979 }
1980 }
1981 return 0;
1982}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001983
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001984
Laurence Lundblade6de37062018-10-15 12:22:42 +05301985
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001986static const uint8_t spIndefiniteArray[] = {0x9f, 0x01, 0x82, 0x02, 0x03, 0xff}; // [1, [2, 3]]
1987static const uint8_t spIndefiniteArrayBad1[] = {0x9f}; // No closing break
1988static const uint8_t spIndefiniteArrayBad2[] = {0x9f, 0x9f, 0x02, 0xff}; // Not enough closing breaks
1989static const uint8_t spIndefiniteArrayBad3[] = {0x9f, 0x02, 0xff, 0xff}; // Too many closing breaks
1990static const uint8_t spIndefiniteArrayBad4[] = {0x81, 0x9f}; // Unclosed indeflen inside def len
1991static const uint8_t spIndefiniteArrayBad5[] = {0x9f, 0xd1, 0xff}; // confused tag
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001992
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301993int IndefiniteLengthArrayMapTest()
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001994{
Laurence Lundblade19e0c802018-10-13 12:19:55 +08001995 int nResult;
1996 // --- first test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001997 UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArray);
Laurence Lundblade17ede402018-10-13 11:43:07 +08001998
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001999 // Decode it and see if it is OK
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302000 UsefulBuf_MAKE_STACK_UB(MemPool, 150);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002001 QCBORDecodeContext DC;
2002 QCBORItem Item;
2003 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2004
2005 QCBORDecode_SetMemPool(&DC, MemPool, false);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302006
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002007 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302008
2009 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
2010 Item.uNestingLevel != 0 ||
2011 Item.uNextNestLevel != 1) {
2012 return -111;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002013 }
2014
2015 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302016 if(Item.uDataType != QCBOR_TYPE_INT64 ||
2017 Item.uNestingLevel != 1 ||
2018 Item.uNextNestLevel != 1) {
2019 return -2;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002020 }
2021
2022 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302023 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
2024 Item.uNestingLevel != 1 ||
2025 Item.uNextNestLevel != 2) {
2026 return -3;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002027 }
2028
2029 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302030 if(Item.uDataType != QCBOR_TYPE_INT64 |
2031 Item.uNestingLevel != 2 ||
2032 Item.uNextNestLevel != 2) {
2033 return -4;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002034 }
2035
2036 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302037 if(Item.uDataType != QCBOR_TYPE_INT64 |
2038 Item.uNestingLevel != 2 ||
2039 Item.uNextNestLevel != 0) {
2040 return -5;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002041 }
2042
2043 if(QCBORDecode_Finish(&DC)) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302044 return -6;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002045 }
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002046
2047 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002048 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad1);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002049
2050 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2051
2052 QCBORDecode_SetMemPool(&DC, MemPool, false);
2053
2054 nResult = QCBORDecode_GetNext(&DC, &Item);
2055 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302056 return -7;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002057 }
2058
Laurence Lundblade570fab52018-10-13 18:28:27 +08002059 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302060 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
2061 return -8;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002062 }
2063
2064
2065 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002066 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad2);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002067
2068 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2069
2070 QCBORDecode_SetMemPool(&DC, MemPool, false);
2071
2072 nResult = QCBORDecode_GetNext(&DC, &Item);
2073 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302074 return -9;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002075 }
2076
2077 nResult = QCBORDecode_GetNext(&DC, &Item);
2078 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302079 return -10;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002080 }
2081
2082 nResult = QCBORDecode_GetNext(&DC, &Item);
2083 if(nResult || Item.uDataType != QCBOR_TYPE_INT64) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302084 return -11;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002085 }
2086
2087 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302088 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
2089 return -12;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002090 }
2091
2092
2093 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002094 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad3);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002095
2096 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2097
2098 QCBORDecode_SetMemPool(&DC, MemPool, false);
2099
2100 nResult = QCBORDecode_GetNext(&DC, &Item);
2101 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302102 return -13;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002103 }
2104
2105 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302106 if(nResult != QCBOR_ERR_BAD_BREAK) {
2107 return -14;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002108 }
Laurence Lundblade6de37062018-10-15 12:22:42 +05302109
Laurence Lundblade570fab52018-10-13 18:28:27 +08002110
2111 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002112 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad4);
Laurence Lundblade570fab52018-10-13 18:28:27 +08002113
2114 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2115
2116 QCBORDecode_SetMemPool(&DC, MemPool, false);
2117
2118 nResult = QCBORDecode_GetNext(&DC, &Item);
2119 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302120 return -15;
Laurence Lundblade570fab52018-10-13 18:28:27 +08002121 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302122
Laurence Lundblade570fab52018-10-13 18:28:27 +08002123 nResult = QCBORDecode_GetNext(&DC, &Item);
2124 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302125 return -16;
Laurence Lundblade570fab52018-10-13 18:28:27 +08002126 }
2127
2128 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302129 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
2130 return -17;
Laurence Lundblade570fab52018-10-13 18:28:27 +08002131 }
2132
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302133 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002134 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad5);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302135
2136 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2137
2138 QCBORDecode_SetMemPool(&DC, MemPool, false);
2139
2140 nResult = QCBORDecode_GetNext(&DC, &Item);
2141 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302142 return -18;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302143 }
2144
2145 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302146 if(nResult != QCBOR_ERR_BAD_BREAK) {
2147 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302148 }
2149
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002150 return 0;
2151}
2152
Laurence Lundblade17ede402018-10-13 11:43:07 +08002153
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002154static const uint8_t spIndefiniteLenString[] = {
Laurence Lundblade17ede402018-10-13 11:43:07 +08002155 0x81, // Array of length one
2156 0x7f, // text string marked with indefinite length
2157 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
2158 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
2159 0xff // ending break
2160};
2161
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002162static const uint8_t spIndefiniteLenStringBad2[] = {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302163 0x81, // Array of length one
2164 0x7f, // text string marked with indefinite length
2165 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
2166 0x44, 0x6d, 0x69, 0x6e, 0x67, // second segment of wrong type
2167 0xff // ending break
2168};
2169
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002170static const uint8_t spIndefiniteLenStringBad3[] = {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302171 0x81, // Array of length one
2172 0x7f, // text string marked with indefinite length
2173 0x01, 0x02, // Not a string
2174 0xff // ending break
2175};
2176
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002177static const uint8_t spIndefiniteLenStringBad4[] = {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302178 0x81, // Array of length one
2179 0x7f, // text string marked with indefinite length
2180 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
2181 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
2182 // missing end of string
2183};
2184
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002185static const uint8_t spIndefiniteLenStringLabel[] = {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302186 0xa1, // Array of length one
2187 0x7f, // text string marked with indefinite length
2188 0x65, 0x73, 0x74, 0x72, 0x75, 0x75, // first segment
2189 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
2190 0xff, // ending break
2191 0x01 // integer being labeled.
2192};
2193
2194static UsefulBufC MakeIndefiniteBigBstr(UsefulBuf Storage)
2195{
2196 UsefulOutBuf UOB;
2197
2198 UsefulOutBuf_Init(&UOB, Storage);
2199 UsefulOutBuf_AppendByte(&UOB, 0x81);
2200 UsefulOutBuf_AppendByte(&UOB, 0x5f);
2201
2202 int i = 0;
2203 for(int nChunkSize = 1; nChunkSize <= 128; nChunkSize *= 2) {
2204 UsefulOutBuf_AppendByte(&UOB, 0x58);
2205 UsefulOutBuf_AppendByte(&UOB, (uint8_t)nChunkSize);
2206 for(int j = 0; j < nChunkSize; j++ ) {
2207 UsefulOutBuf_AppendByte(&UOB, i);
2208 i++;
2209 }
2210 }
2211 UsefulOutBuf_AppendByte(&UOB, 0xff);
2212
2213 return UsefulOutBuf_OutUBuf(&UOB);
2214}
2215
2216static int CheckBigString(UsefulBufC BigString)
2217{
2218 if(BigString.len != 255) {
2219 return 1;
2220 }
2221
2222 for(uint8_t i = 0; i < 255; i++){
2223 if(((const uint8_t *)BigString.ptr)[i] != i) {
2224 return 1;
2225 }
2226 }
2227 return 0;
2228}
2229
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302230
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302231int IndefiniteLengthStringTest()
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302232{
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302233 QCBORDecodeContext DC;
2234 QCBORItem Item;
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302235 // big enough for MakeIndefiniteBigBstr() + MemPool overhead
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302236 UsefulBuf_MAKE_STACK_UB(MemPool, 320);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302237
2238 // --- Simple normal indefinite length string ------
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002239 UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenString);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302240 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002241
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302242 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302243 return -1;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302244 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002245
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302246 if(QCBORDecode_GetNext(&DC, &Item)) {
2247 return -2;
2248 }
2249 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
2250 return -3;
2251 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002252
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302253 if(QCBORDecode_GetNext(&DC, &Item)) {
2254 return -4;
2255 }
2256 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING || !Item.uDataAlloc) {
2257 return -5;
2258 }
2259 if(QCBORDecode_Finish(&DC)) {
2260 return -6;
2261 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302262
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302263 // ----- types mismatch ---
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002264 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad2), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302265
2266 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2267 return -7;
2268 }
2269
2270 if(QCBORDecode_GetNext(&DC, &Item)) {
2271 return -8;
2272 }
2273 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2274 return -9;
2275 }
2276
2277 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_SEG) {
2278 return -10;
2279 }
2280
2281 // ----- not a string ---
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002282 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad3), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302283
2284 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2285 return -11;
2286 }
2287
2288 if(QCBORDecode_GetNext(&DC, &Item)) {
2289 return -12;
2290 }
2291 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2292 return -13;
2293 }
2294
2295 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_SEG) {
2296 return -14;
2297 }
2298
2299 // ----- no end -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002300 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad4), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302301
2302 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2303 return -15;
2304 }
2305
2306 if(QCBORDecode_GetNext(&DC, &Item)) {
2307 return -16;
2308 }
2309 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2310 return -17;
2311 }
2312
2313 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_HIT_END) {
2314 return -18;
2315 }
2316
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302317 // ------ Don't set a string allocator and see an error -----
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302318 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2319
2320 QCBORDecode_GetNext(&DC, &Item);
2321 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302322 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302323 }
2324
2325 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_NO_STRING_ALLOCATOR) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302326 return -20;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302327 }
2328
2329 // ----- Mempool is way too small -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302330 UsefulBuf_MAKE_STACK_UB(MemPoolTooSmall, 20); // 20 is too small no matter what
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302331
2332 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2333 if(!QCBORDecode_SetMemPool(&DC, MemPoolTooSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302334 return -21;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302335 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302336
2337 // ----- Mempool is way too small -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302338 UsefulBuf_MAKE_STACK_UB(BigIndefBStrStorage, 290);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302339 UsefulBufC BigIndefBStr = MakeIndefiniteBigBstr(BigIndefBStrStorage);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302340
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302341 UsefulBuf_MAKE_STACK_UB(MemPoolSmall, 80); // 80 is big enough for MemPool overhead, but not BigIndefBStr
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302342
2343 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302344 if(QCBORDecode_SetMemPool(&DC, MemPoolSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302345 return -22;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302346 }
2347
2348 QCBORDecode_GetNext(&DC, &Item);
2349 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302350 return -23;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302351 }
2352 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_STRING_ALLOC) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302353 return -24;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302354 }
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302355
2356 // ---- big bstr -----
2357 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
2358
2359 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2360 return -25;
2361 }
2362
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302363 if(QCBORDecode_GetNext(&DC, &Item)) {
2364 return -26;
2365 }
2366 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302367 return -26;
2368 }
2369
2370 if(QCBORDecode_GetNext(&DC, &Item)) {
2371 return -27;
2372 }
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302373 if(Item.uDataType != QCBOR_TYPE_BYTE_STRING || !Item.uDataAlloc || Item.uNestingLevel != 1) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302374 return -28;
2375 }
2376 if(CheckBigString(Item.val.string)) {
2377 return -3;
2378 }
2379 if(QCBORDecode_Finish(&DC)) {
2380 return -29;
2381 }
2382
2383 // --- label is an indefinite length string ------
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002384 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringLabel), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302385
2386 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2387 return -30;
2388 }
2389
2390 QCBORDecode_GetNext(&DC, &Item);
2391 if(Item.uDataType != QCBOR_TYPE_MAP) {
2392 return -31;
2393 }
2394
2395 if(QCBORDecode_GetNext(&DC, &Item)){
2396 return -32;
2397 }
2398 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING || Item.uDataType != QCBOR_TYPE_INT64 ||
2399 Item.uDataAlloc || !Item.uLabelAlloc ||
2400 UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("struuming"))) {
2401 return -33;
2402 }
2403
2404 if(QCBORDecode_Finish(&DC)) {
2405 return -34;
2406 }
2407
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002408 return 0;
2409}
2410
2411
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302412int AllocAllStringsTest()
2413{
2414 QCBORDecodeContext DC;
2415
2416 // First test, use the "CSRMap" as easy input and checking
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002417 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302418
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302419 UsefulBuf_MAKE_STACK_UB(Pool, 300);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302420
2421 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2422
2423 if(CheckCSRMaps(&DC)) {
2424 return -1;
2425 }
2426
2427 // Next parse, save pointers to a few strings, destroy original and see all is OK.
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302428 UsefulBuf_MAKE_STACK_UB(CopyOfStorage, 160);
2429 UsefulBufC CopyOf = UsefulBuf_Copy(CopyOfStorage, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded));
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002430
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302431 QCBORDecode_Init(&DC, CopyOf, QCBOR_DECODE_MODE_NORMAL);
2432 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2433
2434 int nCBORError;
2435 QCBORItem Item1, Item2, Item3, Item4;
2436 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2437 return nCBORError;
2438 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2439 Item1.val.uCount != 3)
2440 return -1;
2441 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2442 return nCBORError;
2443 if((nCBORError = QCBORDecode_GetNext(&DC, &Item2)))
2444 return nCBORError;
2445 if((nCBORError = QCBORDecode_GetNext(&DC, &Item3)))
2446 return nCBORError;
2447 if((nCBORError = QCBORDecode_GetNext(&DC, &Item4)))
2448 return nCBORError;
2449
Laurence Lundblade05ec57b2018-10-21 01:50:03 +05302450 UsefulBuf_Set(CopyOfStorage, '_');
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302451
2452 if(Item1.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2453 Item1.label.string.len != 13 ||
2454 Item1.uDataType != QCBOR_TYPE_INT64 ||
2455 Item1.val.int64 != 42 ||
2456 memcmp(Item1.label.string.ptr, "first integer", 13))
2457 return -1;
2458
2459
2460 if(Item2.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2461 Item2.label.string.len != 23 ||
2462 memcmp(Item2.label.string.ptr, "an array of two strings", 23) ||
2463 Item2.uDataType != QCBOR_TYPE_ARRAY ||
2464 Item2.val.uCount != 2)
2465 return -1;
2466
2467 if(Item3.uDataType != QCBOR_TYPE_TEXT_STRING ||
2468 Item3.val.string.len != 7 ||
2469 memcmp(Item3.val.string.ptr, "string1", 7))
2470 return -1;
2471
2472 if(Item4.uDataType != QCBOR_TYPE_TEXT_STRING ||
2473 Item4.val.string.len != 7 ||
2474 memcmp(Item4.val.string.ptr, "string2", 7))
2475 return -1;
2476
2477 // Next parse with a pool that is too small
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302478 UsefulBuf_MAKE_STACK_UB(SmallPool, 80);
2479 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302480 QCBORDecode_SetMemPool(&DC, SmallPool, 1); // Turn on copying.
2481 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2482 return nCBORError;
2483 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2484 Item1.val.uCount != 3)
2485 return -1;
2486 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item1))){
2487 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item2))) {
2488 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item3))) {
2489 nCBORError = QCBORDecode_GetNext(&DC, &Item4);
2490 }
2491 }
2492 }
2493 if(nCBORError != QCBOR_ERR_STRING_ALLOC) {
2494 return -5;
2495 }
2496
2497 return 0;
2498}
2499
2500
2501int MemPoolTest(void)
Laurence Lundblade0155b622018-10-12 20:04:37 +08002502{
2503 QCBORDecodeContext DC;
2504
2505 const uint8_t pMinimalCBOR[] = {0xa0}; // One empty map
2506
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302507 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pMinimalCBOR),0);
Laurence Lundblade0155b622018-10-12 20:04:37 +08002508
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302509 UsefulBuf_MAKE_STACK_UB(Pool, 100);
Laurence Lundblade0155b622018-10-12 20:04:37 +08002510
2511 QCBORDecode_SetMemPool(&DC, Pool, 0);
2512
2513 // Cheat a little to get to the string allocator object
2514 // so we can call it directly to test it
2515 QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2516
2517 // Ask for too much in one go
2518 // 90 < 100, but there is some overhead taken out of the 100
2519 UsefulBuf Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 90);
2520 if(!UsefulBuf_IsNULL(Allocated)) {
2521 return -1;
2522 }
2523
2524
2525
2526 QCBORDecode_SetMemPool(&DC, Pool, 0);
2527
2528 // Cheat a little to get to the string allocator object
2529 // so we can call it directly to test it
2530 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2531
2532 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2533 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2534 return -1;
2535 }
2536 UsefulBuf Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2537 if(!UsefulBuf_IsNULL(Allocated2)) { // expected to fail
2538 return -1;
2539 }
2540 (*pAlloc->fFree)(pAlloc->pAllocaterContext, Allocated.ptr);
2541 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
2542 if(UsefulBuf_IsNULL(Allocated)) { // succeed because of the free
2543 return -1;
2544 }
2545
2546
2547 QCBORDecode_SetMemPool(&DC, Pool, 0);
2548
2549 // Cheat a little to get to the string allocator object
2550 // so we can call it directly to test it
2551 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2552 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 20);
2553 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2554 return -1;
2555 }
2556 Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, 25);
2557 if(UsefulBuf_IsNULL(Allocated2)) { // expected to fail
2558 return -1;
2559 }
2560 if(Allocated2.ptr != Allocated.ptr || Allocated2.len != 25) {
2561 return -1;
2562 }
2563
Laurence Lundblade0155b622018-10-12 20:04:37 +08002564 return 0;
2565}
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002566
2567
2568
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08002569
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002570
2571