From 9bd16ba97422fac995d1737c6b9783a790390bf6 Mon Sep 17 00:00:00 2001 From: "Paul J. Davis" Date: Tue, 5 Mar 2024 11:19:37 -0600 Subject: [PATCH] Fix segfault in ArraySchema::check (#4787) Previously we weren't accounting for when enumerations weren't loaded and a check was performed. This lead to attempts to dereference the nullptr when the enumeration hadn't been loaded. Given that enumerations are only unloaded when reading an array, that means these checks were already run when the schema was written so ignoring them here is fine since they're just enforcing a maximum size constraint. --- TYPE: BUG DESC: Fix segfault in ArraySchema::check --- test/src/unit-enumerations.cc | 12 ++++++++++++ tiledb/sm/array_schema/array_schema.cc | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/test/src/unit-enumerations.cc b/test/src/unit-enumerations.cc index e35cbc30d12..15d874c31fa 100644 --- a/test/src/unit-enumerations.cc +++ b/test/src/unit-enumerations.cc @@ -1452,6 +1452,18 @@ TEST_CASE_METHOD( REQUIRE_THROWS_WITH(schema->check(cfg_), matcher); } +TEST_CASE_METHOD( + EnumerationFx, + "ArraySchema - No Segfault on Check", + "[enumeration][array-scehma][size-check]") { + create_array(); + auto array = get_array(QueryType::READ); + auto schema = array->array_schema_latest_ptr(); + // Schema has unloaded enumerations at this point. Make sure that check + // doesn't segfault. + REQUIRE_NOTHROW(schema->check(cfg_)); +} + TEST_CASE_METHOD( EnumerationFx, "ArraySchema - Many Large Enumerations", diff --git a/tiledb/sm/array_schema/array_schema.cc b/tiledb/sm/array_schema/array_schema.cc index f35ced27396..e5bee621663 100644 --- a/tiledb/sm/array_schema/array_schema.cc +++ b/tiledb/sm/array_schema/array_schema.cc @@ -586,6 +586,12 @@ void ArraySchema::check_enumerations(const Config& cfg) const { uint64_t total_size = 0; for (const auto& pair : enumeration_map_) { + if (!pair.second) { + // We don't have an Array instance at this point so the best we can do + // is just avoid segfaulting when we attempt to check with unloaded + // enumerations. + continue; + } uint64_t size = pair.second->data().size() + pair.second->offsets().size(); if (size > max_size.value()) { throw ArraySchemaException(