Skip to content

Commit 7ed4a8a

Browse files
committed
chore: add Value depth level guard
1 parent 887d7d0 commit 7ed4a8a

File tree

2 files changed

+40
-19
lines changed

2 files changed

+40
-19
lines changed

google/cloud/bigtable/value.cc

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
362365
Status 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)
425436
Status 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()) {

google/cloud/bigtable/value.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,17 +316,23 @@ class Value {
316316
}
317317

318318
static Status TypeAndValuesMatch(google::bigtable::v2::Type const& type,
319-
google::bigtable::v2::Value const& value);
319+
google::bigtable::v2::Value const& value) {
320+
return TypeAndValuesMatch(type, value, 1);
321+
}
320322

321323
private:
324+
static Status TypeAndValuesMatch(google::bigtable::v2::Type const& type,
325+
google::bigtable::v2::Value const& value,
326+
int depth);
322327
static Status TypeAndArrayValuesMatch(
323328
google::bigtable::v2::Type const& type,
324-
google::bigtable::v2::Value const& value);
329+
google::bigtable::v2::Value const& value, int depth);
325330
static Status TypeAndMapValuesMatch(google::bigtable::v2::Type const& type,
326-
google::bigtable::v2::Value const& value);
331+
google::bigtable::v2::Value const& value,
332+
int depth);
327333
static Status TypeAndStructValuesMatch(
328334
google::bigtable::v2::Type const& type,
329-
google::bigtable::v2::Value const& value);
335+
google::bigtable::v2::Value const& value, int depth);
330336

331337
// Metafunction that returns true if `T` is an `absl::optional<U>`
332338
template <typename T>

0 commit comments

Comments
 (0)