@@ -204,7 +204,7 @@ void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int f
204
204
{
205
205
encoder -> data .ptr = buffer ;
206
206
encoder -> end = buffer + size ;
207
- encoder -> added = 0 ;
207
+ encoder -> remaining = 2 ;
208
208
encoder -> flags = flags ;
209
209
}
210
210
@@ -305,9 +305,15 @@ static inline CborError encode_number_no_update(CborEncoder *encoder, uint64_t u
305
305
return append_to_buffer (encoder , bufstart , bufend - bufstart );
306
306
}
307
307
308
+ static inline void saturated_decrement (CborEncoder * encoder )
309
+ {
310
+ if (encoder -> remaining )
311
+ -- encoder -> remaining ;
312
+ }
313
+
308
314
static inline CborError encode_number (CborEncoder * encoder , uint64_t ui , uint8_t shiftedMajorType )
309
315
{
310
- ++ encoder -> added ;
316
+ saturated_decrement ( encoder ) ;
311
317
return encode_number_no_update (encoder , ui , shiftedMajorType );
312
318
}
313
319
@@ -389,7 +395,7 @@ CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, cons
389
395
put32 (buf + 1 , * (const uint32_t * )value );
390
396
else
391
397
put16 (buf + 1 , * (const uint16_t * )value );
392
- ++ encoder -> added ;
398
+ saturated_decrement ( encoder ) ;
393
399
return append_to_buffer (encoder , buf , size + 1 );
394
400
}
395
401
@@ -454,8 +460,8 @@ static CborError create_container(CborEncoder *encoder, CborEncoder *container,
454
460
CborError err ;
455
461
container -> data .ptr = encoder -> data .ptr ;
456
462
container -> end = encoder -> end ;
457
- ++ encoder -> added ;
458
- container -> added = 0 ;
463
+ saturated_decrement ( encoder ) ;
464
+ container -> remaining = length + 1 ; /* overflow ok on CborIndefiniteLength */
459
465
460
466
cbor_static_assert (((MapType << MajorTypeShift ) & CborIteratorFlag_ContainerIsMap ) == CborIteratorFlag_ContainerIsMap );
461
467
cbor_static_assert (((ArrayType << MajorTypeShift ) & CborIteratorFlag_ContainerIsMap ) == 0 );
@@ -465,6 +471,8 @@ static CborError create_container(CborEncoder *encoder, CborEncoder *container,
465
471
container -> flags |= CborIteratorFlag_UnknownLength ;
466
472
err = append_byte_to_buffer (container , shiftedMajorType + IndefiniteLength );
467
473
} else {
474
+ if (shiftedMajorType & CborIteratorFlag_ContainerIsMap )
475
+ container -> remaining += length ;
468
476
err = encode_number_no_update (container , length , shiftedMajorType );
469
477
}
470
478
return err ;
@@ -520,8 +528,8 @@ CborError cbor_encoder_create_map(CborEncoder *encoder, CborEncoder *mapEncoder,
520
528
* same as were passed to cbor_encoder_create_array() or
521
529
* cbor_encoder_create_map().
522
530
*
523
- * This function does not verify that the number of items (or pair of items, in
524
- * the case of a map) was correct. To execute that verification, call
531
+ * Since version 0.5, this function verifies that the number of items (or pair
532
+ * of items, in the case of a map) was correct. It is no longer needed to call
525
533
* cbor_encoder_close_container_checked() instead.
526
534
*
527
535
* \sa cbor_encoder_create_array(), cbor_encoder_create_map()
@@ -535,6 +543,10 @@ CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *
535
543
encoder -> end = containerEncoder -> end ;
536
544
if (containerEncoder -> flags & CborIteratorFlag_UnknownLength )
537
545
return append_byte_to_buffer (encoder , BreakByte );
546
+
547
+ if (containerEncoder -> remaining != 1 )
548
+ return containerEncoder -> remaining == 0 ? CborErrorTooManyItems : CborErrorTooFewItems ;
549
+
538
550
if (!encoder -> end )
539
551
return CborErrorOutOfMemory ; /* keep the state */
540
552
return CborNoError ;
0 commit comments