@@ -214,6 +214,10 @@ static bool is_fixed_type(uint8_t type)
214
214
215
215
static CborError preparse_value (CborValue * it )
216
216
{
217
+ enum {
218
+ /* flags to keep */
219
+ FlagsToKeep = CborIteratorFlag_ContainerIsMap | CborIteratorFlag_NextIsMapKey
220
+ };
217
221
const CborParser * parser = it -> parser ;
218
222
it -> type = CborInvalidType ;
219
223
@@ -224,7 +228,7 @@ static CborError preparse_value(CborValue *it)
224
228
uint8_t descriptor = * it -> ptr ;
225
229
uint8_t type = descriptor & MajorTypeMask ;
226
230
it -> type = type ;
227
- it -> flags = 0 ;
231
+ it -> flags &= FlagsToKeep ;
228
232
it -> extra = (descriptor &= SmallValueMask );
229
233
230
234
if (descriptor > Value64Bit ) {
@@ -302,6 +306,11 @@ static CborError preparse_next_value_nodecrement(CborValue *it)
302
306
{
303
307
if (it -> remaining == UINT32_MAX && it -> ptr != it -> parser -> end && * it -> ptr == (uint8_t )BreakByte ) {
304
308
/* end of map or array */
309
+ if ((it -> flags & CborIteratorFlag_ContainerIsMap && it -> flags & CborIteratorFlag_NextIsMapKey )
310
+ || it -> type == CborTagType ) {
311
+ /* but we weren't expecting it! */
312
+ return CborErrorUnexpectedBreak ;
313
+ }
305
314
++ it -> ptr ;
306
315
it -> type = CborInvalidType ;
307
316
it -> remaining = 0 ;
@@ -313,13 +322,20 @@ static CborError preparse_next_value_nodecrement(CborValue *it)
313
322
314
323
static CborError preparse_next_value (CborValue * it )
315
324
{
325
+ /* tags don't count towards item totals or whether we've successfully
326
+ * read a map's key or value */
327
+ bool itemCounts = it -> type != CborTagType ;
328
+
316
329
if (it -> remaining != UINT32_MAX ) {
317
- /* don't decrement the item count if the current item is tag: they don't count */
318
- if (it -> type != CborTagType && -- it -> remaining == 0 ) {
330
+ if (itemCounts && -- it -> remaining == 0 ) {
319
331
it -> type = CborInvalidType ;
320
332
return CborNoError ;
321
333
}
322
334
}
335
+ if (itemCounts ) {
336
+ /* toggle the flag indicating whether this was a map key */
337
+ it -> flags ^= CborIteratorFlag_NextIsMapKey ;
338
+ }
323
339
return preparse_next_value_nodecrement (it );
324
340
}
325
341
@@ -381,6 +397,7 @@ CborError cbor_parser_init(const uint8_t *buffer, size_t size, uint32_t flags, C
381
397
it -> parser = parser ;
382
398
it -> ptr = buffer ;
383
399
it -> remaining = 1 ; /* there's one type altogether, usually an array or map */
400
+ it -> flags = 0 ;
384
401
return preparse_value (it );
385
402
}
386
403
@@ -586,6 +603,7 @@ CborError cbor_value_skip_tag(CborValue *it)
586
603
*/
587
604
CborError cbor_value_enter_container (const CborValue * it , CborValue * recursed )
588
605
{
606
+ cbor_static_assert (CborIteratorFlag_ContainerIsMap == (CborMapType & ~CborArrayType ));
589
607
cbor_assert (cbor_value_is_container (it ));
590
608
* recursed = * it ;
591
609
@@ -618,6 +636,7 @@ CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed)
618
636
return CborNoError ;
619
637
}
620
638
}
639
+ recursed -> flags = (recursed -> type & CborIteratorFlag_ContainerIsMap );
621
640
return preparse_next_value_nodecrement (recursed );
622
641
}
623
642
0 commit comments