@@ -340,17 +340,20 @@ std::ostream& operator<<(std::ostream& os, Value const& v) {
340340}
341341
342342// NOLINTNEXTLINE(misc-no-recursion)
343- Status Value::TypeAndArrayValuesMatch (
344- google::bigtable::v2::Type const & type,
345- google::bigtable::v2::Value const & value) {
343+ Status Value::TypeAndArrayValuesMatch (google::bigtable::v2::Type const & type,
344+ google::bigtable::v2::Value const & value,
345+ int depth) {
346+ if (depth > 10 ) {
347+ return internal::InternalError (" Nested value depth exceeds 10 levels" );
348+ }
346349 if (!value.has_array_value ()) {
347350 return internal::InternalError (
348351 " Value kind must be ARRAY_VALUE for columns of type: MAP" );
349352 }
350353 auto const & vals = value.array_value ().values ();
351354 for (auto const & val : vals) {
352355 auto const element_match_result =
353- TypeAndValuesMatch (type.array_type ().element_type (), val);
356+ TypeAndValuesMatch (type.array_type ().element_type (), val, depth + 1 );
354357 if (!element_match_result.ok ()) {
355358 return element_match_result;
356359 }
@@ -360,7 +363,11 @@ Status Value::TypeAndArrayValuesMatch(
360363
361364// NOLINTNEXTLINE(misc-no-recursion)
362365Status Value::TypeAndMapValuesMatch (google::bigtable::v2::Type const & type,
363- google::bigtable::v2::Value const & value) {
366+ google::bigtable::v2::Value const & value,
367+ int depth) {
368+ if (depth > 10 ) {
369+ return internal::InternalError (" Nested value depth exceeds 10 levels" );
370+ }
364371 if (!value.has_array_value ()) {
365372 return internal::InternalError (
366373 " Value kind must be ARRAY_VALUE for columns of type: MAP" );
@@ -376,12 +383,13 @@ Status Value::TypeAndMapValuesMatch(google::bigtable::v2::Type const& type,
376383 auto map_key = val.array_value ().values (0 );
377384 auto map_value = val.array_value ().values (1 );
378385 // NOLINTNEXTLINE(misc-no-recursion)
379- auto key_match_result = TypeAndValuesMatch (key_type, map_key);
386+ auto key_match_result = TypeAndValuesMatch (key_type, map_key, depth + 1 );
380387 if (!key_match_result.ok ()) {
381388 return key_match_result;
382389 }
383390 // NOLINTNEXTLINE(misc-no-recursion)
384- auto value_match_result = TypeAndValuesMatch (value_type, map_value);
391+ auto value_match_result =
392+ TypeAndValuesMatch (value_type, map_value, depth + 1 );
385393 if (!value_match_result.ok ()) {
386394 return value_match_result;
387395 }
@@ -390,9 +398,12 @@ Status Value::TypeAndMapValuesMatch(google::bigtable::v2::Type const& type,
390398}
391399
392400// NOLINTNEXTLINE(misc-no-recursion)
393- Status Value::TypeAndStructValuesMatch (
394- google::bigtable::v2::Type const & type,
395- google::bigtable::v2::Value const & value) {
401+ Status Value::TypeAndStructValuesMatch (google::bigtable::v2::Type const & type,
402+ google::bigtable::v2::Value const & value,
403+ int depth) {
404+ if (depth > 10 ) {
405+ return internal::InternalError (" Nested value depth exceeds 10 levels" );
406+ }
396407 if (!value.has_array_value ()) {
397408 return internal::InternalError (
398409 " Value kind must be ARRAY_VALUE for columns of type: STRUCT" );
@@ -408,7 +419,7 @@ Status Value::TypeAndStructValuesMatch(
408419 for (int i = 0 ; i < fields.size (); ++i) {
409420 auto const & f1 = fields.Get (i);
410421 auto const & v = values[i];
411- auto match_result = TypeAndValuesMatch (f1.type (), v);
422+ auto match_result = TypeAndValuesMatch (f1.type (), v, depth + 1 );
412423 if (!match_result.ok ()) {
413424 return match_result;
414425 }
@@ -423,7 +434,11 @@ Status Value::TypeAndStructValuesMatch(
423434 */
424435// NOLINTNEXTLINE(misc-no-recursion)
425436Status Value::TypeAndValuesMatch (google::bigtable::v2::Type const & type,
426- google::bigtable::v2::Value const & value) {
437+ google::bigtable::v2::Value const & value,
438+ int depth) {
439+ if (depth > 10 ) {
440+ return internal::InternalError (" Nested value depth exceeds 10 levels" );
441+ }
427442 using google::bigtable::v2::Type;
428443 auto make_mismatch_metadata_status = [&](std::string const & value_kind,
429444 std::string const & type_name) {
@@ -438,13 +453,13 @@ Status Value::TypeAndValuesMatch(google::bigtable::v2::Type const& type,
438453 Status result;
439454 switch (type.kind_case ()) {
440455 case Type::kArrayType :
441- result = TypeAndArrayValuesMatch (type, value);
456+ result = TypeAndArrayValuesMatch (type, value, depth + 1 );
442457 break ;
443458 case Type::kMapType :
444- result = TypeAndMapValuesMatch (type, value);
459+ result = TypeAndMapValuesMatch (type, value, depth + 1 );
445460 break ;
446461 case Type::kStructType :
447- result = TypeAndStructValuesMatch (type, value);
462+ result = TypeAndStructValuesMatch (type, value, depth + 1 );
448463 break ;
449464 case Type::kBoolType :
450465 if (!value.has_bool_value ()) {
0 commit comments