2525#define CFL_VARIANT_UTILS_MAXIMUM_FIXED_ARRAY_SIZE 100
2626#define CFL_VARIANT_UTILS_INITIAL_ARRAY_SIZE 100
2727#define CFL_VARIANT_UTILS_SERIALIZED_ARRAY_SIZE_LIMIT 100000
28+ #define CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH 32
2829
2930/* These are the only functions meant for general use,
3031 * the reason why the kvlist packing and unpacking
@@ -48,9 +49,17 @@ static inline int pack_cfl_variant(mpack_writer_t *writer,
4849static inline int pack_cfl_variant_kvlist (mpack_writer_t * writer ,
4950 struct cfl_kvlist * kvlist );
5051
52+ static inline int unpack_cfl_variant_depth (mpack_reader_t * reader ,
53+ struct cfl_variant * * value ,
54+ size_t depth );
55+
5156static inline int unpack_cfl_variant (mpack_reader_t * reader ,
5257 struct cfl_variant * * value );
5358
59+ static inline int unpack_cfl_kvlist_depth (mpack_reader_t * reader ,
60+ struct cfl_kvlist * * result_kvlist ,
61+ size_t depth );
62+
5463static inline int unpack_cfl_kvlist (mpack_reader_t * reader ,
5564 struct cfl_kvlist * * result_kvlist );
5665
@@ -234,7 +243,8 @@ static inline int unpack_cfl_variant_read_tag(mpack_reader_t *reader,
234243}
235244
236245static inline int unpack_cfl_array (mpack_reader_t * reader ,
237- struct cfl_array * * result_array )
246+ struct cfl_array * * result_array ,
247+ size_t depth )
238248{
239249 struct cfl_array * internal_array ;
240250 size_t entry_count ;
@@ -243,6 +253,10 @@ static inline int unpack_cfl_array(mpack_reader_t *reader,
243253 size_t index ;
244254 mpack_tag_t tag ;
245255
256+ if (depth >= CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH ) {
257+ return -2 ;
258+ }
259+
246260 result = unpack_cfl_variant_read_tag (reader , & tag , mpack_type_array );
247261
248262 if (result != 0 ) {
@@ -271,7 +285,7 @@ static inline int unpack_cfl_array(mpack_reader_t *reader,
271285 }
272286
273287 for (index = 0 ; index < entry_count ; index ++ ) {
274- result = unpack_cfl_variant (reader , & entry_value );
288+ result = unpack_cfl_variant_depth (reader , & entry_value , depth + 1 );
275289
276290 if (result != 0 ) {
277291 cfl_array_destroy (internal_array );
@@ -301,8 +315,9 @@ static inline int unpack_cfl_array(mpack_reader_t *reader,
301315 return 0 ;
302316}
303317
304- static inline int unpack_cfl_kvlist (mpack_reader_t * reader ,
305- struct cfl_kvlist * * result_kvlist )
318+ static inline int unpack_cfl_kvlist_depth (mpack_reader_t * reader ,
319+ struct cfl_kvlist * * result_kvlist ,
320+ size_t depth )
306321{
307322 struct cfl_kvlist * internal_kvlist ;
308323 char key_name [256 ];
@@ -314,6 +329,10 @@ static inline int unpack_cfl_kvlist(mpack_reader_t *reader,
314329 size_t index ;
315330 mpack_tag_t tag ;
316331
332+ if (depth >= CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH ) {
333+ return -2 ;
334+ }
335+
317336 result = unpack_cfl_variant_read_tag (reader , & tag , mpack_type_map );
318337
319338 if (result != 0 ) {
@@ -360,7 +379,7 @@ static inline int unpack_cfl_kvlist(mpack_reader_t *reader,
360379 break ;
361380 }
362381
363- result = unpack_cfl_variant (reader , & key_value );
382+ result = unpack_cfl_variant_depth (reader , & key_value , depth + 1 );
364383
365384 if (result != 0 ) {
366385 result = -7 ;
@@ -399,6 +418,12 @@ static inline int unpack_cfl_kvlist(mpack_reader_t *reader,
399418 return result ;
400419}
401420
421+ static inline int unpack_cfl_kvlist (mpack_reader_t * reader ,
422+ struct cfl_kvlist * * result_kvlist )
423+ {
424+ return unpack_cfl_kvlist_depth (reader , result_kvlist , 0 );
425+ }
426+
402427static inline int unpack_cfl_variant_string (mpack_reader_t * reader ,
403428 struct cfl_variant * * value )
404429{
@@ -595,12 +620,13 @@ static inline int unpack_cfl_variant_null(mpack_reader_t *reader,
595620}
596621
597622static inline int unpack_cfl_variant_array (mpack_reader_t * reader ,
598- struct cfl_variant * * value )
623+ struct cfl_variant * * value ,
624+ size_t depth )
599625{
600626 struct cfl_array * unpacked_array ;
601627 int result ;
602628
603- result = unpack_cfl_array (reader , & unpacked_array );
629+ result = unpack_cfl_array (reader , & unpacked_array , depth );
604630
605631 if (result != 0 ) {
606632 return result ;
@@ -616,12 +642,13 @@ static inline int unpack_cfl_variant_array(mpack_reader_t *reader,
616642}
617643
618644static inline int unpack_cfl_variant_kvlist (mpack_reader_t * reader ,
619- struct cfl_variant * * value )
645+ struct cfl_variant * * value ,
646+ size_t depth )
620647{
621648 struct cfl_kvlist * unpacked_kvlist ;
622649 int result ;
623650
624- result = unpack_cfl_kvlist (reader , & unpacked_kvlist );
651+ result = unpack_cfl_kvlist_depth (reader , & unpacked_kvlist , depth );
625652
626653 if (result != 0 ) {
627654 return result ;
@@ -636,8 +663,9 @@ static inline int unpack_cfl_variant_kvlist(mpack_reader_t *reader,
636663 return 0 ;
637664}
638665
639- static inline int unpack_cfl_variant (mpack_reader_t * reader ,
640- struct cfl_variant * * value )
666+ static inline int unpack_cfl_variant_depth (mpack_reader_t * reader ,
667+ struct cfl_variant * * value ,
668+ size_t depth )
641669{
642670 mpack_type_t value_type ;
643671 int result ;
@@ -670,10 +698,10 @@ static inline int unpack_cfl_variant(mpack_reader_t *reader,
670698 result = unpack_cfl_variant_null (reader , value );
671699 }
672700 else if (value_type == mpack_type_array ) {
673- result = unpack_cfl_variant_array (reader , value );
701+ result = unpack_cfl_variant_array (reader , value , depth );
674702 }
675703 else if (value_type == mpack_type_map ) {
676- result = unpack_cfl_variant_kvlist (reader , value );
704+ result = unpack_cfl_variant_kvlist (reader , value , depth );
677705 }
678706 else if (value_type == mpack_type_bin ) {
679707 result = unpack_cfl_variant_binary (reader , value );
@@ -685,4 +713,10 @@ static inline int unpack_cfl_variant(mpack_reader_t *reader,
685713 return result ;
686714}
687715
716+ static inline int unpack_cfl_variant (mpack_reader_t * reader ,
717+ struct cfl_variant * * value )
718+ {
719+ return unpack_cfl_variant_depth (reader , value , 0 );
720+ }
721+
688722#endif
0 commit comments