blob: f1b5dbf29dcf0759b5a94d2b18bb2e7a32216eb1 [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 Lundblade0595e932018-11-02 22:22:47 +0700457 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
Laurence Lundblade0595e932018-11-02 22:22:47 +0700465 UsefulBufC Encoded;
466 if(QCBOREncode_Finish(&ECtx, &Encoded))
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800467 goto Done;
468
469 if(*pEncoded != NULL) {
Laurence Lundblade0595e932018-11-02 22:22:47 +0700470 *pEncodedLen = Encoded.len;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800471 nReturn = 0;
472 goto Done;
473 }
Laurence Lundblade0595e932018-11-02 22:22:47 +0700474 *pEncoded = malloc(Encoded.len);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800475 if(*pEncoded == NULL) {
476 nReturn = -1;
477 goto Done;
478 }
479
480 } while(1);
481Done:
482 return (nReturn);
483
484}
485
486
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800487/*
488 {"first integer": 42,
489 "an array of two strings": ["string1", "string2"],
490 "map in a map": {
491 "bytes 1": h'78787878',
492 "bytes 2": h'79797979',
493 "another int": 98, "text 2":
494 "lies, damn lies and statistics"}
495 }
496 */
497
498static uint8_t pValidMapEncoded[] = {
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700499 0xa3, 0x6d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x69, 0x6e,
500 0x74, 0x65, 0x67, 0x65, 0x72, 0x18, 0x2a, 0x77, 0x61, 0x6e,
501 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20,
502 0x74, 0x77, 0x6f, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
503 0x73, 0x82, 0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31,
504 0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x6c, 0x6d,
505 0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x6d, 0x61,
506 0x70, 0xa4, 0x67, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x31,
507 0x44, 0x78, 0x78, 0x78, 0x78, 0x67, 0x62, 0x79, 0x74, 0x65,
508 0x73, 0x20, 0x32, 0x44, 0x79, 0x79, 0x79, 0x79, 0x6b, 0x61,
509 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x74,
510 0x18, 0x62, 0x66, 0x74, 0x65, 0x78, 0x74, 0x20, 0x32, 0x78,
511 0x1e, 0x6c, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x64, 0x61, 0x6d,
512 0x6e, 0x20, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64,
513 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
514 0x73 } ;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800515
516static 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)
517{
518 QCBORDecodeContext DCtx;
519 QCBORItem Item;
520 int nReturn = -1; // assume error until success
521
522 QCBORDecode_Init(&DCtx, (UsefulBufC){pEncoded, nLen}, QCBOR_DECODE_MODE_NORMAL);
523
524 // Make sure the first thing is a map
525 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_ARRAY)
526 goto Done;
527
528 // First integer
529 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 | Item.uDataType != QCBOR_TYPE_INT64)
530 goto Done;
531 *pInt1 = Item.val.int64;
532
533 // Second integer
534 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_INT64)
535 goto Done;
536 *pInt2 = Item.val.int64;
537
538 // First string
539 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
540 goto Done;
541 *pBuf3 = Item.val.string.ptr;
542 *pBuf3Len = Item.val.string.len;
543
544 // Second string
545 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
546 goto Done;
547 *pBuf4 = Item.val.string.ptr;
548 *pBuf4Len = Item.val.string.len;
549
550 nReturn = 0;
551
552Done:
553 return(nReturn);
554}
555
556
557
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800558
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800559int SimpleArrayTest()
560{
561 uint8_t *pEncoded;
562 size_t nEncodedLen;
563
564 int64_t i1, i2;
565 size_t i3, i4;
566 const uint8_t *s3, *s4;
567
568
569 if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
570 return(-1);
571 }
572
573 ParseOrderedArray(pEncoded, nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
574
575 if(i1 != 23 ||
576 i2 != 6000 ||
577 i3 != 8 ||
578 i4 != 11 ||
Laurence Lundbladea44d5062018-10-17 18:45:12 +0530579 memcmp("galactic", s3, 8) !=0 ||
580 memcmp("haven token", s4, 11) !=0) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800581 printf("SimpleArraryTest Failed\n");
582 return(-1);
583 }
584
585 return(0);
586}
587
588
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800589
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700590static uint8_t spDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80};
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800591
592int ParseDeepArrayTest()
593{
594 QCBORDecodeContext DCtx;
595 int nReturn = 0;
596 int i;
597
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700598 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDeepArrays), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800599
600 for(i = 0; i < 10; i++) {
601 QCBORItem Item;
602
603 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
604 Item.uDataType != QCBOR_TYPE_ARRAY ||
605 Item.uNestingLevel != i) {
606 nReturn = -1;
607 break;
608 }
609 }
610
611 return(nReturn);
612}
613
Laurence Lundblade972e59c2018-11-11 15:57:23 +0700614// Big enough to test nesting to the depth of 24
615static uint8_t spTooDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
616 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
617 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
618 0x80};
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800619
620int ParseTooDeepArrayTest()
621{
622 QCBORDecodeContext DCtx;
623 int nReturn = 0;
624 int i;
625 QCBORItem Item;
626
627
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700628 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooDeepArrays), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800629
Laurence Lundblade972e59c2018-11-11 15:57:23 +0700630 for(i = 0; i < QCBOR_MAX_ARRAY_NESTING1; i++) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800631
632 if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
633 Item.uDataType != QCBOR_TYPE_ARRAY ||
634 Item.uNestingLevel != i) {
635 nReturn = -1;
636 break;
637 }
638 }
639
640 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP)
641 nReturn = -1;
642
643 return(nReturn);
644}
645
646
647
648
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800649int ShortBufferParseTest()
650{
651 int nResult = 0;
652 QCBORDecodeContext DCtx;
653 int num;
654
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700655 for(num = sizeof(spExpectedEncodedInts)-1; num; num--) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800656 int n;
657
Laurence Lundbladeb836efb2018-10-28 20:09:58 +0700658 QCBORDecode_Init(&DCtx, (UsefulBufC){spExpectedEncodedInts, num}, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800659
660 n = IntegerValuesParseTestInternal(&DCtx);
661
662 //printf("Len %d, result: %d\n", num, n);
663
664 if(n != QCBOR_ERR_HIT_END) {
665 nResult = -1;
666 goto Done;
667 }
668 }
669Done:
670 return nResult;
671}
672
673
Laurence Lundblade9e3651c2018-10-10 11:49:55 +0800674
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800675int ShortBufferParseTest2()
676{
677 uint8_t *pEncoded;
678 int nReturn;
679 size_t nEncodedLen;
680
681 int64_t i1, i2;
682 size_t i3, i4;
683 const uint8_t *s3, *s4;
684
685 nReturn = 0;
686
687 if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
688 return(-1);
689 }
690
691 //printencoded(pEncoded, nEncodedLen);
692
693 for(nEncodedLen--; nEncodedLen; nEncodedLen--) {
694 int nResult = ParseOrderedArray(pEncoded, (uint32_t)nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
695 if(nResult == 0) {
696 nReturn = -1;
697 }
698 }
699
700 return(nReturn);
701}
702
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530703/*
704 Decode and thoroughly check a moderately complex
705 set of maps
706 */
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800707static int ParseMapTest1()
708{
709 QCBORDecodeContext DCtx;
710 QCBORItem Item;
711 int nCBORError;
712
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800713 QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
714
715 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
716 return nCBORError;
717 if(Item.uDataType != QCBOR_TYPE_MAP ||
718 Item.val.uCount != 3)
719 return -1;
720
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800721 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
722 return nCBORError;
723 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
724 Item.label.string.len != 13 ||
725 Item.uDataType != QCBOR_TYPE_INT64 ||
726 Item.val.int64 != 42 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530727 Item.uDataAlloc ||
728 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800729 memcmp(Item.label.string.ptr, "first integer", 13))
730 return -1;
731
732 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
733 return nCBORError;
734 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
735 Item.label.string.len != 23 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530736 Item.uDataAlloc ||
737 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800738 memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
739 Item.uDataType != QCBOR_TYPE_ARRAY ||
740 Item.val.uCount != 2)
741 return -1;
742
743 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
744 return nCBORError;
745 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
746 Item.val.string.len != 7 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530747 Item.uDataAlloc ||
748 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800749 memcmp(Item.val.string.ptr, "string1", 7))
750 return -1;
751
752 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
753 return nCBORError;
754 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
755 Item.val.string.len != 7 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530756 Item.uDataAlloc ||
757 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800758 memcmp(Item.val.string.ptr, "string2", 7))
759 return -1;
760
761 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
762 return nCBORError;
763 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
764 Item.label.string.len != 12 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530765 Item.uDataAlloc ||
766 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800767 memcmp(Item.label.string.ptr, "map in a map", 12) ||
768 Item.uDataType != QCBOR_TYPE_MAP ||
769 Item.val.uCount != 4)
770 return -1;
771
772 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
773 return nCBORError;
774 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
775 Item.label.string.len != 7 ||
776 memcmp(Item.label.string.ptr, "bytes 1", 7)||
777 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
778 Item.val.string.len != 4 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530779 Item.uDataAlloc ||
780 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800781 memcmp(Item.val.string.ptr, "xxxx", 4))
782 return -1;
783
784 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
785 return nCBORError;
786 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
787 Item.label.string.len != 7 ||
788 memcmp(Item.label.string.ptr, "bytes 2", 7) ||
789 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
790 Item.val.string.len != 4 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530791 Item.uDataAlloc ||
792 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800793 memcmp(Item.val.string.ptr, "yyyy", 4))
794 return -1;
795
796 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
797 return nCBORError;
798 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
799 Item.label.string.len != 11 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530800 Item.uDataAlloc ||
801 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800802 memcmp(Item.label.string.ptr, "another int", 11) ||
803 Item.uDataType != QCBOR_TYPE_INT64 ||
804 Item.val.int64 != 98)
805 return -1;
806
807 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
808 return nCBORError;
809 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
810 Item.label.string.len != 6 ||
811 memcmp(Item.label.string.ptr, "text 2", 6)||
812 Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
813 Item.val.string.len != 30 ||
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530814 Item.uDataAlloc ||
815 Item.uLabelAlloc ||
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800816 memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
817 return -1;
818
819 return 0;
820}
821
822
823
824/*
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530825 Fully or partially decode pValidMapEncoded. When
826 partially decoding check for the right error code.
827 How much partial decoding depends on nLevel.
828
829 The partial decodes test error conditions of
830 incomplete encoded input.
831
832 This could be combined with the above test
833 and made prettier and maybe a little more
834 thorough.
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800835 */
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800836static int ExtraBytesTest(int nLevel)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800837{
838 QCBORDecodeContext DCtx;
839 QCBORItem Item;
840 int nCBORError;
841
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800842 QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
843
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800844 if(nLevel < 1) {
845 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
846 return -1;
847 } else {
848 return 0;
849 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800850 }
Laurence Lundbladefab1b522018-10-19 13:40:52 +0530851
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800852
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800853 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
854 return nCBORError;
855 if(Item.uDataType != QCBOR_TYPE_MAP ||
856 Item.val.uCount != 3)
857 return -1;
858
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800859 if(nLevel < 2) {
860 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
861 return -1;
862 } else {
863 return 0;
864 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800865 }
866
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800867
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800868 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
869 return nCBORError;
870 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
871 Item.label.string.len != 13 ||
872 Item.uDataType != QCBOR_TYPE_INT64 ||
873 Item.val.uCount != 42 ||
874 memcmp(Item.label.string.ptr, "first integer", 13))
875 return -1;
876
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800877 if(nLevel < 3) {
878 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
879 return -1;
880 } else {
881 return 0;
882 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800883 }
884
885 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
886 return nCBORError;
887 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
888 Item.label.string.len != 23 ||
889 memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
890 Item.uDataType != QCBOR_TYPE_ARRAY ||
891 Item.val.uCount != 2)
892 return -1;
893
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800894
895 if(nLevel < 4) {
896 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
897 return -1;
898 } else {
899 return 0;
900 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800901 }
902
903
904 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
905 return nCBORError;
906 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
907 Item.val.string.len != 7 ||
908 memcmp(Item.val.string.ptr, "string1", 7))
909 return -1;
910
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800911 if(nLevel < 5) {
912 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
913 return -1;
914 } else {
915 return 0;
916 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800917 }
918
919 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
920 return nCBORError;
921 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
922 Item.val.string.len != 7 ||
923 memcmp(Item.val.string.ptr, "string2", 7))
924 return -1;
925
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800926 if(nLevel < 6) {
927 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
928 return -1;
929 } else {
930 return 0;
931 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800932 }
933
934 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
935 return nCBORError;
936 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
937 Item.label.string.len != 12 ||
938 memcmp(Item.label.string.ptr, "map in a map", 12) ||
939 Item.uDataType != QCBOR_TYPE_MAP ||
940 Item.val.uCount != 4)
941 return -1;
942
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800943 if(nLevel < 7) {
944 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
945 return -1;
946 } else {
947 return 0;
948 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800949 }
950
951 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
952 return nCBORError;
953 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
954 Item.label.string.len != 7 ||
955 memcmp(Item.label.string.ptr, "bytes 1", 7)||
956 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
957 Item.val.string.len != 4 ||
958 memcmp(Item.val.string.ptr, "xxxx", 4))
959 return -1;
960
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800961 if(nLevel < 8) {
962 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
963 return -1;
964 } else {
965 return 0;
966 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800967 }
968
969 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
970 return nCBORError;
971 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
972 Item.label.string.len != 7 ||
973 memcmp(Item.label.string.ptr, "bytes 2", 7) ||
974 Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
975 Item.val.string.len != 4 ||
976 memcmp(Item.val.string.ptr, "yyyy", 4))
977 return -1;
978
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800979 if(nLevel < 9) {
980 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
981 return -1;
982 } else {
983 return 0;
984 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +0800985 }
986
987 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
988 return nCBORError;
989 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
990 Item.label.string.len != 11 ||
991 memcmp(Item.label.string.ptr, "another int", 11) ||
992 Item.uDataType != QCBOR_TYPE_INT64 ||
993 Item.val.int64 != 98)
994 return -1;
995
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +0800996 if(nLevel < 10) {
997 if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
998 return -1;
999 } else {
1000 return 0;
1001 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001002 }
1003
1004 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1005 return nCBORError;
1006 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
1007 Item.label.string.len != 6 ||
1008 memcmp(Item.label.string.ptr, "text 2", 6)||
1009 Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1010 Item.val.string.len != 30 ||
1011 memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
1012 return -1;
1013
Laurence Lundbladefab1b522018-10-19 13:40:52 +05301014 if(QCBORDecode_Finish(&DCtx)) {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001015 return -1;
1016 }
1017
1018 return 0;
1019}
1020
1021
1022
1023
1024int ParseMapTest()
1025{
Laurence Lundbladefab1b522018-10-19 13:40:52 +05301026 // Parse a moderatly complex map structure very thoroughl
1027 int n = ParseMapTest1();
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001028
1029 if(!n) {
Laurence Lundblade0fb6c6d2018-10-12 22:02:05 +08001030 for(int i = 0; i < 10; i++) {
1031 n = ExtraBytesTest(i);
1032 if(n) {
1033 break;
1034 }
1035 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001036 }
1037
1038 return(n);
1039}
1040
1041
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001042static 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 +08001043
1044int ParseSimpleTest()
1045{
1046 QCBORDecodeContext DCtx;
1047 QCBORItem Item;
1048 int nCBORError;
1049
1050
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001051 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSimpleValues), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001052
1053
1054 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1055 return nCBORError;
1056 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1057 Item.val.uCount != 10)
1058 return -1;
1059
1060 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1061 return nCBORError;
1062 if(Item.uDataType != QCBOR_TYPE_FALSE)
1063 return -1;
1064
1065 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1066 return nCBORError;
1067 if(Item.uDataType != QCBOR_TYPE_TRUE)
1068 return -1;
1069
1070 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1071 return nCBORError;
1072 if(Item.uDataType != QCBOR_TYPE_NULL)
1073 return -1;
1074
1075 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1076 return nCBORError;
1077 if(Item.uDataType != QCBOR_TYPE_UNDEF)
1078 return -1;
1079
1080 // A break
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001081 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_BAD_BREAK)
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001082 return -1;
1083
1084 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1085 return nCBORError;
1086 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 0)
1087 return -1;
1088
1089 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1090 return nCBORError;
1091 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 19)
1092 return -1;
1093
1094 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
1095 return -1;
1096
1097 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
1098 return -1;
1099
1100 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
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 != 32)
1106 return -1;
1107
1108 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1109 return nCBORError;
1110 if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 255)
1111 return -1;
1112
1113 return 0;
1114
1115}
1116
1117
1118struct FailInput {
1119 UsefulBufC Input;
1120 int nError;
1121};
1122
1123
1124struct FailInput Failures[] = {
1125 { {(uint8_t[]){0x18}, 1}, QCBOR_ERR_HIT_END }, // 1 byte integer missing the byte
1126 { {(uint8_t[]){0x1c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1127 { {(uint8_t[]){0x1d}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 29
1128 { {(uint8_t[]){0x1e}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 30
1129 { {(uint8_t[]){0x1f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length integer
1130 { {(uint8_t[]){0x3c}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1131 { {(uint8_t[]){0x3d}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1132 { {(uint8_t[]){0x3e}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
1133 { {(uint8_t[]){0x3f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length negative integer
1134 { {(uint8_t[]){0x41}, 1}, QCBOR_ERR_HIT_END }, // Short byte string
1135 { {(uint8_t[]){0x5c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1136 { {(uint8_t[]){0x5f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length byte string
1137 { {(uint8_t[]){0x61}, 1}, QCBOR_ERR_HIT_END }, // Short UTF-8 string
1138 { {(uint8_t[]){0x7c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
1139 { {(uint8_t[]){0x7f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length UTF-8 string
1140 { {(uint8_t[]){0xff}, 1}, QCBOR_ERR_UNSUPPORTED } , // break
1141 { {(uint8_t[]){0xf8, 0x00}, 2}, QCBOR_ERR_INVALID_CBOR }, // An invalid encoding of a simple type
1142 { {(uint8_t[]){0xf8, 0x1f}, 2}, QCBOR_ERR_INVALID_CBOR }, // An invalid encoding of a simple type
1143 { {(uint8_t[]){0xc0, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG }, // Text-based date, with an integer
1144 { {(uint8_t[]){0xc1, 0x41, 0x33}, 3}, QCBOR_ERR_BAD_OPT_TAG }, // Epoch date, with an byte string
1145 { {(uint8_t[]){0xc1, 0xc0, 0x00}, 3}, QCBOR_ERR_BAD_OPT_TAG }, // tagged as both epoch and string dates
1146 { {(uint8_t[]){0xc2, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG } // big num tagged an int, not a byte string
1147
1148};
1149
1150
1151void Dump(UsefulBufC Input, int x)
1152{
1153 char label[10];
1154
1155 sprintf(label, "%d", x);
1156
1157 printencoded(label, Input.ptr, Input.len);
1158}
1159
1160
1161int FailureTests()
1162{
1163 int nResult = 0;
1164
1165 struct FailInput *pFEnd = &Failures[0] + sizeof(Failures)/sizeof(struct FailInput);
1166
1167 for(struct FailInput *pF = &Failures[0]; pF < pFEnd ;pF++) {
1168 QCBORDecodeContext DCtx;
1169 QCBORItem Item;
1170 int nCBORError;
1171
1172 QCBORDecode_Init(&DCtx, pF->Input, QCBOR_DECODE_MODE_NORMAL);
1173
1174 while(1) {
1175 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1176 if(QCBOR_ERR_HIT_END == nCBORError) {
1177 break;
1178 }
1179 if(nCBORError != pF->nError) {
1180 nResult = 1;
1181 // Dump(pF->Input, nCBORError);
1182 break;
1183 }
1184 }
1185 }
1186
1187 {
1188 QCBORDecodeContext DCtx;
1189 QCBORItem Item;
1190 int nCBORError;
1191
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001192 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSimpleValues), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001193
1194 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1195 return nCBORError;
1196 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1197 Item.val.uCount != 10)
1198 return -1;
1199
1200 DCtx.InBuf.magic = 0; // Corrupt the UsefulInputBuf
1201
1202 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1203 if(nCBORError != QCBOR_ERR_HIT_END)
1204 return -1;
1205 }
1206
1207
1208 return nResult;
1209}
1210
1211
1212
1213
1214static void Recurser(uint8_t *pBuf, int nLen, int nLenMax)
1215{
1216
1217 if(nLen >= nLenMax) {
1218 return;
1219 }
1220
1221 //printf("__%d__%d__\n", nLen, nLenMax);
1222
1223 for(int i = 0; i < 256; i++) {
1224 pBuf[nLen] = i;
1225
1226 QCBORDecodeContext DCtx;
1227 QCBORItem Item;
1228 int nCBORError;
1229
1230 UsefulBufC Input = {pBuf, nLen+1};
1231
1232 QCBORDecode_Init(&DCtx, Input, QCBOR_DECODE_MODE_NORMAL);
1233
1234 while(1) {
1235 nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
1236 if(QCBOR_ERR_HIT_END == nCBORError) {
1237 break;
1238 }
1239 if(nCBORError != QCBOR_SUCCESS) {
1240 if(nCBORError != QCBOR_ERR_UNSUPPORTED && nCBORError != QCBOR_ERR_HIT_END && nCBORError != QCBOR_ERR_INVALID_CBOR) {
1241 //Dump(Input, nCBORError);
1242 }
1243 break;
1244 }
1245 }
1246 //Dump(Input, -1);
1247
1248
1249 Recurser(pBuf, nLen+1, nLenMax);
1250 }
1251}
1252
1253
1254/*
1255 Runs all possible input strings of a given length. This is set to 3 to make the test
1256 run in reasonable time.
1257 Main point of this test is to not crash.
1258 */
1259
1260int ComprehensiveInputTest()
1261{
1262 uint8_t pBuf[3]; // 3 keeps it running in reasonable time. 4 takes tens of minutes.
1263
1264 Recurser(pBuf, 0, sizeof(pBuf));
1265
1266 return 0;
1267}
1268
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001269static uint8_t spDateTestInput[] = {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001270 0xc0, // tag for string date
1271 0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
1272
1273 0xc1, // tag for epoch date
1274 0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
1275
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001276 // CBOR_TAG_B64
1277 0xc1, 0xcf, 0xd8, 0x22, // 0xee, // Epoch date with extra tags TODO: fix this test
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001278 0x1a, 0x53, 0x72, 0x4E, 0x01,
1279
1280 0xc1, // tag for epoch date
1281 0x1b, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // Too large integer
1282
1283 0xc1, // tag for epoch date
1284 0xfa, 0x3f, 0x8c, 0xcc, 0xcd, // double with value 1.1
1285
1286 0xc1, // tag for epoch date
1287 0xfa, 0x7f, 0x7f, 0xff, 0xff // 3.4028234663852886e+38 too large
1288
1289};
1290
1291
1292// have to check float expected only to within an epsilon
1293int CHECK_EXPECTED_DOUBLE(double val, double expected) {
1294
1295 double diff = val - expected;
1296
1297 diff = fabs(diff);
1298
1299 return diff > 0.0000001;
1300}
1301
1302
1303int DateParseTest()
1304{
1305 QCBORDecodeContext DCtx;
1306 QCBORItem Item;
1307 int nCBORError;
1308
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001309 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001310
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001311 const uint64_t uTags[] = {15};
1312 QCBORTagListIn TagList = {1, uTags};
1313
1314 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
1315
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001316 // String date
1317 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1318 return -1;
1319 if(Item.uDataType != QCBOR_TYPE_DATE_STRING ||
Laurence Lundblade9e3651c2018-10-10 11:49:55 +08001320 UsefulBuf_Compare(Item.val.dateString, UsefulBuf_FromSZ("1985-04-12"))){
Laurence Lundblade67bd5512018-11-02 21:44:06 +07001321 return -2;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001322 }
1323
1324 // Epoch date
1325 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
Laurence Lundblade67bd5512018-11-02 21:44:06 +07001326 return -3;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001327 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1328 Item.val.epochDate.nSeconds != 1400000000 ||
1329 Item.val.epochDate.fSecondsFraction != 0 ) {
Laurence Lundblade67bd5512018-11-02 21:44:06 +07001330 return -4;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001331 }
1332
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001333 // Epoch date with extra CBOR_TAG_B64 tag that doesn't really mean anything
1334 // but want to be sure extra tag doesn't cause a problem
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001335 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
Laurence Lundblade67bd5512018-11-02 21:44:06 +07001336 return -5;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001337 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1338 Item.val.epochDate.nSeconds != 1400000001 ||
1339 Item.val.epochDate.fSecondsFraction != 0 ||
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001340 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_B64)) {
Laurence Lundblade67bd5512018-11-02 21:44:06 +07001341 return -6;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001342 }
1343
1344 // Epoch date that is too large for our representation
1345 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
Laurence Lundblade67bd5512018-11-02 21:44:06 +07001346 return -7;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001347 }
1348
1349 // Epoch date in float format with fractional seconds
1350 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
Laurence Lundblade67bd5512018-11-02 21:44:06 +07001351 return -8;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001352 if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
1353 Item.val.epochDate.nSeconds != 1 ||
1354 CHECK_EXPECTED_DOUBLE(Item.val.epochDate.fSecondsFraction, 0.1 )) {
Laurence Lundblade67bd5512018-11-02 21:44:06 +07001355 return -9;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001356 }
1357
1358 // Epoch date float that is too large for our representation
1359 if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
Laurence Lundblade67bd5512018-11-02 21:44:06 +07001360 return -10;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001361 }
1362
1363 // TODO: could use a few more tests with float, double, and half precsion and negative (but coverage is still pretty good)
1364
1365 return 0;
1366}
1367
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001368// Really simple basic input for tagging test
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001369static uint8_t spOptTestInput[] = {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001370 0xd9, 0xd9, 0xf7, // CBOR magic number
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001371 0x81, // Array of one
1372 0xd8, 0x04, // non-preferred serialization of tag 4
1373 0x82, 0x01, 0x03}; // fraction 1/3
1374
1375static uint8_t spEncodedLargeTag[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x80};
1376
1377// 0x9192939495969798, 0x88, 0x01, 0x04
1378static uint8_t spLotsOfTags[] = {0xdb, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0xd8, 0x88, 0xc5, 0xc4, 0x80};
1379
1380/*
1381 The cbor.me parse of this.
1382 55799(55799(55799({6(7(-23)): 5859837686836516696(7({7(-20): 11({17(-18): 17(17(17("Organization"))),
1383 9(-17): 773("SSG"), -15: 4(5(6(7(8(9(10(11(12(13(14(15("Confusion")))))))))))), 17(-16): 17("San Diego"),
1384 17(-14): 17("US")}), 23(-19): 19({-11: 9({-9: -7}),
1385 90599561(90599561(90599561(-10))): 12(h'0102030405060708090A')})})),
1386 16(-22): 23({11(8(7(-5))): 8(-3)})})))
1387 */
1388static uint8_t spCSRWithTags[] = {
1389 0xd9, 0xd9, 0xf7, 0xd9, 0xd9, 0xf7, 0xd9, 0xd9, 0xf7, 0xa2,
1390 0xc6, 0xc7, 0x36,
1391 0xdb, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0xc7, 0xa2,
1392 0xda, 0x00, 0x00, 0x00, 0x07, 0x33,
1393 0xcb, 0xa5,
1394 0xd1, 0x31,
1395 0xd1, 0xd1, 0xd1, 0x6c,
1396 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
1397 0xc9, 0x30,
1398 0xd9, 0x03, 0x05, 0x63,
1399 0x53, 0x53, 0x47,
1400 0x2e,
1401 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0x69,
1402 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73, 0x69, 0x6f, 0x6e,
1403 0xd1, 0x2f,
1404 0xd1, 0x69,
1405 0x53, 0x61, 0x6e, 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f,
1406 0xd1, 0x2d,
1407 0xd1, 0x62,
1408 0x55, 0x53,
1409 0xd7, 0x32,
1410 0xd3, 0xa2,
1411 0x2a,
1412 0xc9, 0xa1,
1413 0x28,
1414 0x26,
1415 0xda, 0x05, 0x66, 0x70, 0x89, 0xda, 0x05, 0x66, 0x70, 0x89, 0xda, 0x05, 0x66, 0x70, 0x89, 0x29,
1416 0xcc, 0x4a,
1417 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,0x07, 0x08, 0x09, 0x0a,
1418 0xd0, 0x35,
1419 0xd7, 0xa1,
1420 0xcb, 0xc8, 0xc7, 0x24,
1421 0xc8, 0x22};
1422
1423static int CheckCSRMaps(QCBORDecodeContext *pDC);
1424
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001425
1426int OptTagParseTest()
1427{
1428 QCBORDecodeContext DCtx;
1429 QCBORItem Item;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001430
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001431 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spOptTestInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001432
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001433 //-------------------------
1434 // This text matches the magic number tag and the fraction tag
1435 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1436 return -2;
1437 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001438 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001439 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC)) {
1440 return -3;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001441 }
1442
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001443 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1444 return -4;
1445 }
1446 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1447 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_FRACTION) ||
1448 Item.val.uCount != 2) {
1449 return -5;
1450 }
1451
1452 // --------------------------------
1453 // This test decodes the very large tag, but it is not in
1454 // any list so it is ignored.
1455 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
1456 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1457 return -6;
1458 }
1459 if(Item.uTagBits) {
1460 return -7;
1461 }
1462
1463 // ----------------------------------
1464 // This test sets up a caller-config list that includes the very large tage and then matches it.
1465 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
1466 const uint64_t puList[] = {0x9192939495969798, 257};
1467 const QCBORTagListIn TL = {2, puList};
1468 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TL);
1469
1470 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1471 return -8;
1472 }
1473 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
1474 !QCBORDecode_IsTagged(&DCtx, &Item, 0x9192939495969798) ||
1475 QCBORDecode_IsTagged(&DCtx, &Item, 257) ||
1476 QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_BIGFLOAT) ||
1477 Item.val.uCount != 0) {
1478 return -9;
1479 }
1480
1481 //------------------------
1482 // This test sets up a caller-configured list, and looks up something not in it
1483 const uint64_t puLongList[17] = {1,2,1};
1484 const QCBORTagListIn TLLong = {17, puLongList};
1485 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
1486 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TLLong);
1487 if(QCBORDecode_GetNext(&DCtx, &Item)) {
1488 return -11;
1489 }
1490
1491 // -----------------------
1492 // This tests retrievel of the full tag list
1493 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
1494 uint64_t puTags[16];
1495 QCBORTagListOut Out = {0, 4, puTags};
1496 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1497 return -12;
1498 }
1499 if(puTags[0] != 0x9192939495969798 ||
1500 puTags[1] != 0x88 ||
1501 puTags[2] != 0x05 ||
1502 puTags[3] != 0x04) {
1503 return -13;
1504 }
1505
1506 // ----------------------
1507 // This text if too small of an out list
1508 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
1509 QCBORTagListOut OutSmall = {0, 3, puTags};
1510 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &OutSmall) != QCBOR_ERR_TOO_MANY_TAGS) {
1511 return -14;
1512 }
1513
1514 // ---------------
1515 // Parse a version of the "CSR" that has had a ton of tags randomly inserted
1516 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
1517 int n = CheckCSRMaps(&DCtx);
1518 if(n) {
1519 return n-2000;
1520 }
1521
1522 Out = (QCBORTagListOut){0,16, puTags};
1523 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
1524
1525 const uint64_t puTagList[] = {773, 1, 90599561};
1526 const QCBORTagListIn TagList = {3, puTagList};
1527 QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
1528
1529
1530 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1531 return -100;
1532 }
1533 if(Item.uDataType != QCBOR_TYPE_MAP ||
1534 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC) ||
1535 QCBORDecode_IsTagged(&DCtx, &Item, 90599561) ||
1536 QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_DATE_EPOCH) ||
1537 Item.val.uCount != 2 ||
1538 puTags[0] != CBOR_TAG_CBOR_MAGIC ||
1539 puTags[1] != CBOR_TAG_CBOR_MAGIC ||
1540 puTags[2] != CBOR_TAG_CBOR_MAGIC ||
1541 Out.uNumUsed != 3) {
1542 return -101;
1543 }
1544
1545 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1546 return -102;
1547 }
1548 if(Item.uDataType != QCBOR_TYPE_MAP ||
1549 QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC) ||
1550 QCBORDecode_IsTagged(&DCtx, &Item, 6) ||
1551 QCBORDecode_IsTagged(&DCtx, &Item, 7) || // item is tagged 7, but 7 is not configured to be recognized
1552 Item.val.uCount != 2 ||
1553 puTags[0] != 5859837686836516696 ||
1554 puTags[1] != 7 ||
1555 Out.uNumUsed != 2) {
1556 return -103;
1557 }
1558
1559 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1560 return -104;
1561 }
1562 if(Item.uDataType != QCBOR_TYPE_MAP ||
1563 Item.uTagBits ||
1564 Item.val.uCount != 5 ||
1565 puTags[0] != 0x0b ||
1566 Out.uNumUsed != 1) {
1567 return -105;
1568 }
1569
1570 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1571 return -106;
1572 }
1573 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1574 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_COSE_MAC0) ||
1575 Item.val.string.len != 12 ||
1576 puTags[0] != CBOR_TAG_COSE_MAC0 ||
1577 puTags[1] != CBOR_TAG_COSE_MAC0 ||
1578 puTags[2] != CBOR_TAG_COSE_MAC0 ||
1579 Out.uNumUsed != 3) {
1580 return -105;
1581 }
1582
1583 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1584 return -107;
1585 }
1586 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1587 !QCBORDecode_IsTagged(&DCtx, &Item, 773) ||
1588 Item.val.string.len != 3 ||
1589 puTags[0] != 773 ||
1590 Out.uNumUsed != 1) {
1591 return -108;
1592 }
1593
1594 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1595 return -109;
1596 }
1597 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1598 !QCBORDecode_IsTagged(&DCtx, &Item, 4) ||
1599 Item.val.string.len != 9 ||
1600 puTags[0] != 4 ||
1601 puTags[11] != 0x0f ||
1602 Out.uNumUsed != 12) {
1603 return -110;
1604 }
1605
1606 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1607 return -111;
1608 }
1609 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1610 !QCBORDecode_IsTagged(&DCtx, &Item, 17) ||
1611 Item.val.string.len != 9 ||
1612 puTags[0] != 17 ||
1613 Out.uNumUsed != 1) {
1614 return -112;
1615 }
1616
1617 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1618 return -111;
1619 }
1620 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
1621 !QCBORDecode_IsTagged(&DCtx, &Item, 17) ||
1622 Item.val.string.len != 2 ||
1623 puTags[0] != 17 ||
1624 Out.uNumUsed != 1) {
1625 return -112;
1626 }
1627
1628 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1629 return -113;
1630 }
1631 if(Item.uDataType != QCBOR_TYPE_MAP ||
1632 QCBORDecode_IsTagged(&DCtx, &Item, 19) ||
1633 Item.val.uCount != 2 ||
1634 puTags[0] != 19 ||
1635 Out.uNumUsed != 1) {
1636 return -114;
1637 }
1638
1639 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1640 return -115;
1641 }
1642 if(Item.uDataType != QCBOR_TYPE_MAP ||
1643 QCBORDecode_IsTagged(&DCtx, &Item, 9) ||
1644 Item.uTagBits ||
1645 Item.val.uCount != 1 ||
1646 puTags[0] != 9 ||
1647 Out.uNumUsed != 1) {
1648 return -116;
1649 }
1650
1651 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1652 return -116;
1653 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001654 if(Item.uDataType != QCBOR_TYPE_INT64 ||
Laurence Lundbladedbe6f212018-10-28 11:37:53 +07001655 Item.val.int64 != -7 ||
1656 Item.uTagBits ||
1657 Out.uNumUsed != 0) {
1658 return -117;
1659 }
1660
1661 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1662 return -118;
1663 }
1664 if(Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
1665 Item.val.string.len != 10 ||
1666 Item.uTagBits ||
1667 puTags[0] != 12 ||
1668 Out.uNumUsed != 1) {
1669 return -119;
1670 }
1671
1672 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1673 return -120;
1674 }
1675 if(Item.uDataType != QCBOR_TYPE_MAP ||
1676 !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_ENC_AS_B16) ||
1677 Item.val.uCount != 1 ||
1678 puTags[0] != 0x17 ||
1679 Out.uNumUsed != 1) {
1680 return -121;
1681 }
1682
1683 if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
1684 return -122;
1685 }
1686 if(Item.uDataType != QCBOR_TYPE_INT64 ||
1687 QCBORDecode_IsTagged(&DCtx, &Item, 8) ||
1688 Item.val.int64 != -3 ||
1689 puTags[0] != 8 ||
1690 Out.uNumUsed != 1) {
1691 return -123;
1692 }
1693
1694 if(QCBORDecode_Finish(&DCtx)) {
1695 return -124;
1696 }
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001697
1698 return 0;
1699}
1700
1701
1702
1703
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001704static uint8_t spBigNumInput[] = {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001705 0x83,
1706 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1707 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1708 0xA4,
1709 0x63, 0x42, 0x4E, 0x2B,
1710 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1711 0x18, 0x40,
1712 0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1713 0x63, 0x42, 0x4E, 0x2D,
1714 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1715 0x38, 0x3F,
1716 0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1717
1718
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001719static uint8_t spBigNum[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001720
1721
1722int BignumParseTest()
1723{
1724 QCBORDecodeContext DCtx;
1725 QCBORItem Item;
1726 int nCBORError;
1727
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001728 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNumInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001729
1730
1731 //
1732 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1733 return -1;
1734 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1735 return -1;
1736 }
1737
1738 //
1739 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1740 return -1;
1741 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001742 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001743 return -1;
1744 }
1745
1746 //
1747 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1748 return -1;
1749 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001750 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001751 return -1;
1752 }
1753
1754 //
1755 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1756 return -1;
1757 if(Item.uDataType != QCBOR_TYPE_MAP) {
1758 return -1;
1759 }
1760
1761 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1762 return -1;
1763 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1764 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001765 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001766 return -1;
1767 }
1768
1769 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1770 return -1;
1771 if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
1772 Item.uLabelType != QCBOR_TYPE_INT64 ||
1773 Item.label.int64 != 64 ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001774 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001775 return -1;
1776 }
1777
1778 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1779 return -1;
1780 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1781 Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001782 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001783 return -1;
1784 }
1785
1786 if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
1787 return -1;
1788 if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
1789 Item.uLabelType != QCBOR_TYPE_INT64 ||
1790 Item.label.int64 != -64 ||
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001791 UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001792 return -1;
1793 }
1794
1795 return 0;
1796}
1797
1798
1799
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301800static 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 +08001801{
1802 QCBORItem Item;
1803 int nCBORError;
1804
1805 if((nCBORError = QCBORDecode_GetNext(pCtx, &Item))) return -1;
1806 if(Item.uDataType != uDataType) return -1;
1807 if(uNestingLevel > 0) {
1808 if(Item.uLabelType != QCBOR_TYPE_INT64 && Item.uLabelType != QCBOR_TYPE_UINT64) return -1;
1809 if(Item.uLabelType == QCBOR_TYPE_INT64) {
1810 if(Item.label.int64 != nLabel) return -1;
1811 } else {
Laurence Lundblade570fab52018-10-13 18:28:27 +08001812 if(Item.label.uint64 != (uint64_t)nLabel) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001813 }
1814 }
1815 if(Item.uNestingLevel != uNestingLevel) return -1;
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301816 if(Item.uNextNestLevel != uNextNest) return -1;
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001817
1818 if(pItem) {
1819 *pItem = Item;
1820 }
1821 return 0;
1822}
1823
1824
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001825// Same code checks definite and indefinite length versions of the map
1826static int CheckCSRMaps(QCBORDecodeContext *pDC)
1827{
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301828 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 0, 1, 0, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001829
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301830 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -23, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001831
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301832 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -20, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001833
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301834 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -18, NULL)) return -1;
1835 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -17, NULL)) return -1;
1836 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -15, NULL)) return -1;
1837 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -16, NULL)) return -1;
1838 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 2, -14, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001839
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301840 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -19, NULL)) return -1;
1841 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 3, 4, -11, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001842
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301843 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 4, 3, -9, NULL)) return -1;
1844 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_BYTE_STRING, 3, 1, -10, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001845
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301846 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -22, NULL)) return -1;
1847 if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 2, 0, -5, NULL)) return -1;
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001848
1849 if(QCBORDecode_Finish(pDC)) return -2;
1850
1851 return 0;
1852}
1853
1854
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001855/*
1856// cbor.me decoded output
1857{
1858 -23: {
1859 -20: {
1860 -18: "Organization",
1861 -17: "SSG",
1862 -15: "Confusion",
1863 -16: "San Diego",
1864 -14: "US"
1865 },
1866 -19: {
1867 -11: {
1868 -9: -7
1869 },
1870 -10: '\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\n'
1871 }
1872 },
1873 -22: {
1874 -5: -3
1875 }
1876}
1877 */
1878
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001879
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001880static uint8_t spCSRInput[] = {
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001881 0xa2, 0x36, 0xa2, 0x33, 0xa5, 0x31, 0x6c, 0x4f,
1882 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1883 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1884 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1885 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1886 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
1887 0x55, 0x53, 0x32, 0xa2, 0x2a, 0xa1, 0x28, 0x26,
1888 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1889 0x07, 0x08, 0x09, 0x0a, 0x35, 0xa1, 0x24, 0x22};
1890
1891int NestedMapTest()
1892{
1893 QCBORDecodeContext DCtx;
1894
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001895 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001896
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001897 return CheckCSRMaps(&DCtx);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001898}
1899
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001900// Same map as above, but using indefinite lengths
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001901static uint8_t spCSRInputIndefLen[] = {
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001902 0xbf, 0x36, 0xbf, 0x33, 0xbf, 0x31, 0x6c, 0x4f,
1903 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
1904 0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
1905 0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
1906 0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
1907 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001908 0x55, 0x53, 0xff, 0x32, 0xbf, 0x2a, 0xbf, 0x28,
1909 0x26, 0xff, 0x29, 0x4a, 0x01, 0x02, 0x03, 0x04,
1910 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0xff, 0xff,
1911 0x35, 0xbf, 0x24, 0x22, 0xff, 0xff};
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001912
1913int NestedMapTestIndefLen()
1914{
1915 QCBORDecodeContext DCtx;
1916
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001917 QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInputIndefLen), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade742df4a2018-10-13 20:07:17 +08001918
1919 return CheckCSRMaps(&DCtx);
1920}
1921
1922
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08001923
Laurence Lundblade17ede402018-10-13 11:43:07 +08001924static UsefulBufC make_nested_indefinite_arrays(int n, UsefulBuf Storage)
1925{
1926 UsefulOutBuf UOB;
1927 UsefulOutBuf_Init(&UOB, Storage);
1928
1929 int i;
1930 for(i = 0; i < n; i++) {
1931 UsefulOutBuf_AppendByte(&UOB, 0x9f);
1932 }
1933
1934 for(i = 0; i < n; i++) {
1935 UsefulOutBuf_AppendByte(&UOB, 0xff);
1936 }
1937 return UsefulOutBuf_OutUBuf(&UOB);
1938}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001939
1940
Laurence Lundblade17ede402018-10-13 11:43:07 +08001941static int parse_indeflen_nested(UsefulBufC Nested, int nNestLevel)
1942{
1943 QCBORDecodeContext DC;
1944 QCBORDecode_Init(&DC, Nested, 0);
1945
1946 int j;
1947 for(j = 0; j < nNestLevel; j++) {
1948 QCBORItem Item;
1949 int nReturn = QCBORDecode_GetNext(&DC, &Item);
1950 if(j >= QCBOR_MAX_ARRAY_NESTING) {
1951 // Should be in error
1952 if(nReturn != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP) {
1953 return -4;
1954 } else {
1955 return 0; // Decoding doesn't recover after an error
1956 }
1957 } else {
1958 // Should be no error
1959 if(nReturn) {
1960 return -9; // Should not have got an error
1961 }
1962 }
1963 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
1964 return -7;
1965 }
1966 }
1967 int nReturn = QCBORDecode_Finish(&DC);
1968 if(nReturn) {
1969 return -3;
1970 }
1971 return 0;
1972}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001973
1974
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301975int IndefiniteLengthNestTest()
Laurence Lundblade17ede402018-10-13 11:43:07 +08001976{
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05301977 UsefulBuf_MAKE_STACK_UB(Storage, 50);
Laurence Lundblade17ede402018-10-13 11:43:07 +08001978 int i;
Laurence Lundblade6de37062018-10-15 12:22:42 +05301979 for(i=1; i < QCBOR_MAX_ARRAY_NESTING+4; i++) {
Laurence Lundblade17ede402018-10-13 11:43:07 +08001980 UsefulBufC Nested = make_nested_indefinite_arrays(i, Storage);
1981 int nReturn = parse_indeflen_nested(Nested, i);
1982 if(nReturn) {
1983 return nReturn;
1984 }
1985 }
1986 return 0;
1987}
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001988
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001989
Laurence Lundblade6de37062018-10-15 12:22:42 +05301990
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07001991static const uint8_t spIndefiniteArray[] = {0x9f, 0x01, 0x82, 0x02, 0x03, 0xff}; // [1, [2, 3]]
1992static const uint8_t spIndefiniteArrayBad1[] = {0x9f}; // No closing break
1993static const uint8_t spIndefiniteArrayBad2[] = {0x9f, 0x9f, 0x02, 0xff}; // Not enough closing breaks
1994static const uint8_t spIndefiniteArrayBad3[] = {0x9f, 0x02, 0xff, 0xff}; // Too many closing breaks
1995static const uint8_t spIndefiniteArrayBad4[] = {0x81, 0x9f}; // Unclosed indeflen inside def len
1996static const uint8_t spIndefiniteArrayBad5[] = {0x9f, 0xd1, 0xff}; // confused tag
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001997
Laurence Lundbladea44d5062018-10-17 18:45:12 +05301998int IndefiniteLengthArrayMapTest()
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08001999{
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002000 int nResult;
2001 // --- first test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002002 UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArray);
Laurence Lundblade17ede402018-10-13 11:43:07 +08002003
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002004 // Decode it and see if it is OK
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302005 UsefulBuf_MAKE_STACK_UB(MemPool, 150);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002006 QCBORDecodeContext DC;
2007 QCBORItem Item;
2008 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2009
2010 QCBORDecode_SetMemPool(&DC, MemPool, false);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302011
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002012 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302013
2014 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
2015 Item.uNestingLevel != 0 ||
2016 Item.uNextNestLevel != 1) {
2017 return -111;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002018 }
2019
2020 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302021 if(Item.uDataType != QCBOR_TYPE_INT64 ||
2022 Item.uNestingLevel != 1 ||
2023 Item.uNextNestLevel != 1) {
2024 return -2;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002025 }
2026
2027 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302028 if(Item.uDataType != QCBOR_TYPE_ARRAY ||
2029 Item.uNestingLevel != 1 ||
2030 Item.uNextNestLevel != 2) {
2031 return -3;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002032 }
2033
2034 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302035 if(Item.uDataType != QCBOR_TYPE_INT64 |
2036 Item.uNestingLevel != 2 ||
2037 Item.uNextNestLevel != 2) {
2038 return -4;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002039 }
2040
2041 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302042 if(Item.uDataType != QCBOR_TYPE_INT64 |
2043 Item.uNestingLevel != 2 ||
2044 Item.uNextNestLevel != 0) {
2045 return -5;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002046 }
2047
2048 if(QCBORDecode_Finish(&DC)) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302049 return -6;
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002050 }
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002051
2052 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002053 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad1);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002054
2055 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2056
2057 QCBORDecode_SetMemPool(&DC, MemPool, false);
2058
2059 nResult = QCBORDecode_GetNext(&DC, &Item);
2060 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302061 return -7;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002062 }
2063
Laurence Lundblade570fab52018-10-13 18:28:27 +08002064 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302065 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
2066 return -8;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002067 }
2068
2069
2070 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002071 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad2);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002072
2073 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2074
2075 QCBORDecode_SetMemPool(&DC, MemPool, false);
2076
2077 nResult = QCBORDecode_GetNext(&DC, &Item);
2078 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302079 return -9;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002080 }
2081
2082 nResult = QCBORDecode_GetNext(&DC, &Item);
2083 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302084 return -10;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002085 }
2086
2087 nResult = QCBORDecode_GetNext(&DC, &Item);
2088 if(nResult || Item.uDataType != QCBOR_TYPE_INT64) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302089 return -11;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002090 }
2091
2092 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302093 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
2094 return -12;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002095 }
2096
2097
2098 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002099 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad3);
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002100
2101 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2102
2103 QCBORDecode_SetMemPool(&DC, MemPool, false);
2104
2105 nResult = QCBORDecode_GetNext(&DC, &Item);
2106 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302107 return -13;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002108 }
2109
2110 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302111 if(nResult != QCBOR_ERR_BAD_BREAK) {
2112 return -14;
Laurence Lundblade19e0c802018-10-13 12:19:55 +08002113 }
Laurence Lundblade6de37062018-10-15 12:22:42 +05302114
Laurence Lundblade570fab52018-10-13 18:28:27 +08002115
2116 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002117 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad4);
Laurence Lundblade570fab52018-10-13 18:28:27 +08002118
2119 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2120
2121 QCBORDecode_SetMemPool(&DC, MemPool, false);
2122
2123 nResult = QCBORDecode_GetNext(&DC, &Item);
2124 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302125 return -15;
Laurence Lundblade570fab52018-10-13 18:28:27 +08002126 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302127
Laurence Lundblade570fab52018-10-13 18:28:27 +08002128 nResult = QCBORDecode_GetNext(&DC, &Item);
2129 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302130 return -16;
Laurence Lundblade570fab52018-10-13 18:28:27 +08002131 }
2132
2133 nResult = QCBORDecode_Finish(&DC);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302134 if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
2135 return -17;
Laurence Lundblade570fab52018-10-13 18:28:27 +08002136 }
2137
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302138 // --- next test -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002139 IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad5);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302140
2141 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2142
2143 QCBORDecode_SetMemPool(&DC, MemPool, false);
2144
2145 nResult = QCBORDecode_GetNext(&DC, &Item);
2146 if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade6de37062018-10-15 12:22:42 +05302147 return -18;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302148 }
2149
2150 nResult = QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade6de37062018-10-15 12:22:42 +05302151 if(nResult != QCBOR_ERR_BAD_BREAK) {
2152 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302153 }
2154
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002155 return 0;
2156}
2157
Laurence Lundblade17ede402018-10-13 11:43:07 +08002158
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002159static const uint8_t spIndefiniteLenString[] = {
Laurence Lundblade17ede402018-10-13 11:43:07 +08002160 0x81, // Array of length one
2161 0x7f, // text string marked with indefinite length
2162 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
2163 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
2164 0xff // ending break
2165};
2166
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002167static const uint8_t spIndefiniteLenStringBad2[] = {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302168 0x81, // Array of length one
2169 0x7f, // text string marked with indefinite length
2170 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
2171 0x44, 0x6d, 0x69, 0x6e, 0x67, // second segment of wrong type
2172 0xff // ending break
2173};
2174
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002175static const uint8_t spIndefiniteLenStringBad3[] = {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302176 0x81, // Array of length one
2177 0x7f, // text string marked with indefinite length
2178 0x01, 0x02, // Not a string
2179 0xff // ending break
2180};
2181
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002182static const uint8_t spIndefiniteLenStringBad4[] = {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302183 0x81, // Array of length one
2184 0x7f, // text string marked with indefinite length
2185 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, // first segment
2186 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
2187 // missing end of string
2188};
2189
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002190static const uint8_t spIndefiniteLenStringLabel[] = {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302191 0xa1, // Array of length one
2192 0x7f, // text string marked with indefinite length
2193 0x65, 0x73, 0x74, 0x72, 0x75, 0x75, // first segment
2194 0x64, 0x6d, 0x69, 0x6e, 0x67, // second segment
2195 0xff, // ending break
2196 0x01 // integer being labeled.
2197};
2198
2199static UsefulBufC MakeIndefiniteBigBstr(UsefulBuf Storage)
2200{
2201 UsefulOutBuf UOB;
2202
2203 UsefulOutBuf_Init(&UOB, Storage);
2204 UsefulOutBuf_AppendByte(&UOB, 0x81);
2205 UsefulOutBuf_AppendByte(&UOB, 0x5f);
2206
2207 int i = 0;
2208 for(int nChunkSize = 1; nChunkSize <= 128; nChunkSize *= 2) {
2209 UsefulOutBuf_AppendByte(&UOB, 0x58);
2210 UsefulOutBuf_AppendByte(&UOB, (uint8_t)nChunkSize);
2211 for(int j = 0; j < nChunkSize; j++ ) {
2212 UsefulOutBuf_AppendByte(&UOB, i);
2213 i++;
2214 }
2215 }
2216 UsefulOutBuf_AppendByte(&UOB, 0xff);
2217
2218 return UsefulOutBuf_OutUBuf(&UOB);
2219}
2220
2221static int CheckBigString(UsefulBufC BigString)
2222{
2223 if(BigString.len != 255) {
2224 return 1;
2225 }
2226
2227 for(uint8_t i = 0; i < 255; i++){
2228 if(((const uint8_t *)BigString.ptr)[i] != i) {
2229 return 1;
2230 }
2231 }
2232 return 0;
2233}
2234
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302235
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302236int IndefiniteLengthStringTest()
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302237{
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302238 QCBORDecodeContext DC;
2239 QCBORItem Item;
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302240 // big enough for MakeIndefiniteBigBstr() + MemPool overhead
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302241 UsefulBuf_MAKE_STACK_UB(MemPool, 320);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302242
2243 // --- Simple normal indefinite length string ------
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002244 UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenString);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302245 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002246
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302247 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302248 return -1;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302249 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002250
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302251 if(QCBORDecode_GetNext(&DC, &Item)) {
2252 return -2;
2253 }
2254 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
2255 return -3;
2256 }
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002257
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302258 if(QCBORDecode_GetNext(&DC, &Item)) {
2259 return -4;
2260 }
2261 if(Item.uDataType != QCBOR_TYPE_TEXT_STRING || !Item.uDataAlloc) {
2262 return -5;
2263 }
2264 if(QCBORDecode_Finish(&DC)) {
2265 return -6;
2266 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302267
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302268 // ----- types mismatch ---
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002269 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad2), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302270
2271 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2272 return -7;
2273 }
2274
2275 if(QCBORDecode_GetNext(&DC, &Item)) {
2276 return -8;
2277 }
2278 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2279 return -9;
2280 }
2281
Laurence Lundblade30816f22018-11-10 13:40:22 +07002282 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_CHUNK) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302283 return -10;
2284 }
2285
2286 // ----- not a string ---
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002287 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad3), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302288
2289 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2290 return -11;
2291 }
2292
2293 if(QCBORDecode_GetNext(&DC, &Item)) {
2294 return -12;
2295 }
2296 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2297 return -13;
2298 }
2299
Laurence Lundblade30816f22018-11-10 13:40:22 +07002300 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_CHUNK) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302301 return -14;
2302 }
2303
2304 // ----- no end -----
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002305 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad4), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302306
2307 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2308 return -15;
2309 }
2310
2311 if(QCBORDecode_GetNext(&DC, &Item)) {
2312 return -16;
2313 }
2314 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
2315 return -17;
2316 }
2317
2318 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_HIT_END) {
2319 return -18;
2320 }
2321
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302322 // ------ Don't set a string allocator and see an error -----
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302323 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2324
2325 QCBORDecode_GetNext(&DC, &Item);
2326 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302327 return -19;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302328 }
2329
2330 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_NO_STRING_ALLOCATOR) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302331 return -20;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302332 }
2333
2334 // ----- Mempool is way too small -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302335 UsefulBuf_MAKE_STACK_UB(MemPoolTooSmall, 20); // 20 is too small no matter what
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302336
2337 QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
2338 if(!QCBORDecode_SetMemPool(&DC, MemPoolTooSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302339 return -21;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302340 }
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302341
2342 // ----- Mempool is way too small -----
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302343 UsefulBuf_MAKE_STACK_UB(BigIndefBStrStorage, 290);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302344 UsefulBufC BigIndefBStr = MakeIndefiniteBigBstr(BigIndefBStrStorage);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302345
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302346 UsefulBuf_MAKE_STACK_UB(MemPoolSmall, 80); // 80 is big enough for MemPool overhead, but not BigIndefBStr
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302347
2348 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302349 if(QCBORDecode_SetMemPool(&DC, MemPoolSmall, false)) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302350 return -22;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302351 }
2352
2353 QCBORDecode_GetNext(&DC, &Item);
2354 if(Item.uDataType != QCBOR_TYPE_ARRAY) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302355 return -23;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302356 }
Laurence Lundblade30816f22018-11-10 13:40:22 +07002357 if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_STRING_ALLOCATE) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302358 return -24;
Laurence Lundblade5b8c5852018-10-14 21:11:42 +05302359 }
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302360
2361 // ---- big bstr -----
2362 QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
2363
2364 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2365 return -25;
2366 }
2367
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302368 if(QCBORDecode_GetNext(&DC, &Item)) {
2369 return -26;
2370 }
2371 if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302372 return -26;
2373 }
2374
2375 if(QCBORDecode_GetNext(&DC, &Item)) {
2376 return -27;
2377 }
Laurence Lundblade7e0d13b2018-10-16 19:54:13 +05302378 if(Item.uDataType != QCBOR_TYPE_BYTE_STRING || !Item.uDataAlloc || Item.uNestingLevel != 1) {
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302379 return -28;
2380 }
2381 if(CheckBigString(Item.val.string)) {
2382 return -3;
2383 }
2384 if(QCBORDecode_Finish(&DC)) {
2385 return -29;
2386 }
2387
2388 // --- label is an indefinite length string ------
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002389 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringLabel), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundblade57dd1442018-10-15 20:26:28 +05302390
2391 if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
2392 return -30;
2393 }
2394
2395 QCBORDecode_GetNext(&DC, &Item);
2396 if(Item.uDataType != QCBOR_TYPE_MAP) {
2397 return -31;
2398 }
2399
2400 if(QCBORDecode_GetNext(&DC, &Item)){
2401 return -32;
2402 }
2403 if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING || Item.uDataType != QCBOR_TYPE_INT64 ||
2404 Item.uDataAlloc || !Item.uLabelAlloc ||
2405 UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("struuming"))) {
2406 return -33;
2407 }
2408
2409 if(QCBORDecode_Finish(&DC)) {
2410 return -34;
2411 }
2412
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002413 return 0;
2414}
2415
2416
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302417int AllocAllStringsTest()
2418{
2419 QCBORDecodeContext DC;
2420
2421 // First test, use the "CSRMap" as easy input and checking
Laurence Lundbladeb836efb2018-10-28 20:09:58 +07002422 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302423
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302424 UsefulBuf_MAKE_STACK_UB(Pool, 300);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302425
2426 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2427
2428 if(CheckCSRMaps(&DC)) {
2429 return -1;
2430 }
2431
2432 // Next parse, save pointers to a few strings, destroy original and see all is OK.
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302433 UsefulBuf_MAKE_STACK_UB(CopyOfStorage, 160);
2434 UsefulBufC CopyOf = UsefulBuf_Copy(CopyOfStorage, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded));
Laurence Lundblade4d1ecba2018-10-12 21:22:30 +08002435
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302436 QCBORDecode_Init(&DC, CopyOf, QCBOR_DECODE_MODE_NORMAL);
2437 QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
2438
2439 int nCBORError;
2440 QCBORItem Item1, Item2, Item3, Item4;
2441 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2442 return nCBORError;
2443 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2444 Item1.val.uCount != 3)
2445 return -1;
2446 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2447 return nCBORError;
2448 if((nCBORError = QCBORDecode_GetNext(&DC, &Item2)))
2449 return nCBORError;
2450 if((nCBORError = QCBORDecode_GetNext(&DC, &Item3)))
2451 return nCBORError;
2452 if((nCBORError = QCBORDecode_GetNext(&DC, &Item4)))
2453 return nCBORError;
2454
Laurence Lundblade05ec57b2018-10-21 01:50:03 +05302455 UsefulBuf_Set(CopyOfStorage, '_');
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302456
2457 if(Item1.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2458 Item1.label.string.len != 13 ||
2459 Item1.uDataType != QCBOR_TYPE_INT64 ||
2460 Item1.val.int64 != 42 ||
2461 memcmp(Item1.label.string.ptr, "first integer", 13))
2462 return -1;
2463
2464
2465 if(Item2.uLabelType != QCBOR_TYPE_TEXT_STRING ||
2466 Item2.label.string.len != 23 ||
2467 memcmp(Item2.label.string.ptr, "an array of two strings", 23) ||
2468 Item2.uDataType != QCBOR_TYPE_ARRAY ||
2469 Item2.val.uCount != 2)
2470 return -1;
2471
2472 if(Item3.uDataType != QCBOR_TYPE_TEXT_STRING ||
2473 Item3.val.string.len != 7 ||
2474 memcmp(Item3.val.string.ptr, "string1", 7))
2475 return -1;
2476
2477 if(Item4.uDataType != QCBOR_TYPE_TEXT_STRING ||
2478 Item4.val.string.len != 7 ||
2479 memcmp(Item4.val.string.ptr, "string2", 7))
2480 return -1;
2481
2482 // Next parse with a pool that is too small
Laurence Lundblade4fe9f312018-10-22 10:22:39 +05302483 UsefulBuf_MAKE_STACK_UB(SmallPool, 80);
2484 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), QCBOR_DECODE_MODE_NORMAL);
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302485 QCBORDecode_SetMemPool(&DC, SmallPool, 1); // Turn on copying.
2486 if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
2487 return nCBORError;
2488 if(Item1.uDataType != QCBOR_TYPE_MAP ||
2489 Item1.val.uCount != 3)
2490 return -1;
2491 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item1))){
2492 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item2))) {
2493 if(!(nCBORError = QCBORDecode_GetNext(&DC, &Item3))) {
2494 nCBORError = QCBORDecode_GetNext(&DC, &Item4);
2495 }
2496 }
2497 }
Laurence Lundblade30816f22018-11-10 13:40:22 +07002498 if(nCBORError != QCBOR_ERR_STRING_ALLOCATE) {
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302499 return -5;
2500 }
2501
2502 return 0;
2503}
2504
Laurence Lundbladef6531662018-12-04 10:42:22 +09002505// Cheating declaration to get to the special test hook
2506size_t MemPoolTestHook_GetPoolSize(void *ctx);
2507
Laurence Lundbladea44d5062018-10-17 18:45:12 +05302508
2509int MemPoolTest(void)
Laurence Lundblade0155b622018-10-12 20:04:37 +08002510{
Laurence Lundbladef6531662018-12-04 10:42:22 +09002511 // Set up the decoder with a tiny bit of CBOR to parse
2512 QCBORDecodeContext DC;
2513 const uint8_t pMinimalCBOR[] = {0xa0}; // One empty map
2514 QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pMinimalCBOR),0);
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002515
Laurence Lundbladef6531662018-12-04 10:42:22 +09002516 // Set up an memory pool of 100 bytes
2517 UsefulBuf_MAKE_STACK_UB(Pool, 100);
2518 QCBORDecode_SetMemPool(&DC, Pool, 0);
2519
2520 // Cheat a little to get to the string allocator object
2521 // so we can call it directly to test it
2522 QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2523 // Cheat some more to know exactly the
2524 size_t uAvailPool = MemPoolTestHook_GetPoolSize(pAlloc);
2525
2526 // First test -- ask for too much in one go
2527 UsefulBuf Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool+1);
2528 if(!UsefulBuf_IsNULL(Allocated)) {
2529 return -1;
2530 }
2531
2532
2533 // Re do the set up for the next test that will do a successful alloc,
2534 // a fail, a free and then success
2535 // This test should work on 32 and 64-bit machines if the compiler
2536 // does the expected thing with pointer sizes for the internal
2537 // MemPool implementation leaving 44 or 72 bytes of pool memory.
2538 QCBORDecode_SetMemPool(&DC, Pool, 0);
2539
2540 // Cheat a little to get to the string allocator object
2541 // so we can call it directly to test it
2542 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2543 // Cheat some more to know exactly the
2544 uAvailPool = MemPoolTestHook_GetPoolSize(pAlloc);
2545
2546 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool-1);
2547 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2548 return -2;
2549 }
2550 UsefulBuf Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool/2);
2551 if(!UsefulBuf_IsNULL(Allocated2)) { // expected to fail
2552 return -3;
2553 }
2554 (*pAlloc->fFree)(pAlloc->pAllocaterContext, Allocated.ptr);
2555 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool/2);
2556 if(UsefulBuf_IsNULL(Allocated)) { // succeed because of the free
2557 return -4;
2558 }
2559
2560
2561 // Re do set up for next test that involves a successful alloc,
2562 // and a successful realloc and a failed realloc
2563 QCBORDecode_SetMemPool(&DC, Pool, 0);
2564
2565 // Cheat a little to get to the string allocator object
2566 // so we can call it directly to test it
2567 pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
2568 Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool/2);
2569 if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
2570 return -5;
2571 }
2572 Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, uAvailPool);
2573 if(UsefulBuf_IsNULL(Allocated2)) {
2574 return -6;
2575 }
2576 if(Allocated2.ptr != Allocated.ptr || Allocated2.len != uAvailPool) {
2577 return -7;
2578 }
2579 UsefulBuf Allocated3 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, uAvailPool+1);
2580 if(!UsefulBuf_IsNULL(Allocated3)) { // expected to fail
2581 return -8;
2582 }
2583
2584 return 0;
2585}
Laurence Lundblade2ded3d92018-10-09 21:36:11 +08002586