From c298481025e0daf3fa8b03ff27dd5768743e9908 Mon Sep 17 00:00:00 2001 From: Carl Niklas Rydberg Date: Sun, 21 Dec 2025 20:21:34 +0100 Subject: [PATCH] =?UTF-8?q?Implemented=20identity-domain=20validation=20an?= =?UTF-8?q?d=20duplicate=20EdgeRef=20detection=20in=20the=20in=E2=80=91mem?= =?UTF-8?q?ory=20TGK=20store?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/adapters/tgk_store_mem/tgk_store_mem.c | 105 +++++++++++++++++++-- 1 file changed, 98 insertions(+), 7 deletions(-) diff --git a/src/adapters/tgk_store_mem/tgk_store_mem.c b/src/adapters/tgk_store_mem/tgk_store_mem.c index 898e465..e355394 100644 --- a/src/adapters/tgk_store_mem/tgk_store_mem.c +++ b/src/adapters/tgk_store_mem/tgk_store_mem.c @@ -5,20 +5,46 @@ #include #include +static bool amduat_tgk_store_mem_id_space_valid( + amduat_tgk_id_space_config_t id_space) { + size_t i; + size_t j; + + if (id_space.domains_len != 0 && id_space.domains == NULL) { + return false; + } + for (i = 0; i < id_space.domains_len; ++i) { + for (j = i + 1; j < id_space.domains_len; ++j) { + if (id_space.domains[i].hash_id == id_space.domains[j].hash_id) { + return false; + } + } + } + return true; +} + static bool amduat_tgk_store_mem_hash_id_supported( const amduat_tgk_store_mem_t *mem, amduat_hash_id_t hash_id) { size_t i; + bool found = false; if (mem == NULL) { return false; } + if (mem->config.id_space.domains_len != 0 && + mem->config.id_space.domains == NULL) { + return false; + } for (i = 0; i < mem->config.id_space.domains_len; ++i) { if (mem->config.id_space.domains[i].hash_id == hash_id) { - return true; + if (found) { + return false; + } + found = true; } } - return false; + return found; } static bool amduat_tgk_store_mem_edge_tag_supported( @@ -91,6 +117,15 @@ static bool amduat_tgk_store_mem_type_filter_match( return false; } +static bool amduat_tgk_store_mem_artifact_eq(amduat_artifact_t a, + amduat_artifact_t b) { + if ((a.bytes.len != 0 && a.bytes.data == NULL) || + (b.bytes.len != 0 && b.bytes.data == NULL)) { + return false; + } + return amduat_artifact_eq(a, b); +} + static bool amduat_tgk_store_mem_node_in_list( amduat_reference_t node, const amduat_reference_t *list, @@ -260,18 +295,59 @@ static bool amduat_tgk_store_mem_edge_view_clone( static const amduat_tgk_store_mem_artifact_t * amduat_tgk_store_mem_lookup_artifact(const amduat_tgk_store_mem_t *mem, - amduat_reference_t ref) { + amduat_reference_t ref, + bool *out_conflict) { + const amduat_tgk_store_mem_artifact_t *found = NULL; size_t i; + if (out_conflict != NULL) { + *out_conflict = false; + } if (mem == NULL) { return NULL; } for (i = 0; i < mem->artifacts_len; ++i) { - if (amduat_reference_eq(mem->artifacts[i].ref, ref)) { - return &mem->artifacts[i]; + if (!amduat_reference_eq(mem->artifacts[i].ref, ref)) { + continue; + } + if (found == NULL) { + found = &mem->artifacts[i]; + continue; + } + if (!amduat_tgk_store_mem_artifact_eq(found->artifact, + mem->artifacts[i].artifact)) { + if (out_conflict != NULL) { + *out_conflict = true; + } + return found; } } - return NULL; + return found; +} + +static bool amduat_tgk_store_mem_check_duplicate_artifact( + const amduat_tgk_store_mem_artifact_t *artifacts, + size_t index, + bool *out_duplicate) { + size_t i; + + if (out_duplicate != NULL) { + *out_duplicate = false; + } + for (i = 0; i < index; ++i) { + if (!amduat_reference_eq(artifacts[i].ref, artifacts[index].ref)) { + continue; + } + if (!amduat_tgk_store_mem_artifact_eq(artifacts[i].artifact, + artifacts[index].artifact)) { + return false; + } + if (out_duplicate != NULL) { + *out_duplicate = true; + } + return true; + } + return true; } static amduat_tgk_graph_error_t amduat_tgk_store_mem_decode_edge( @@ -456,6 +532,7 @@ static amduat_tgk_graph_error_t amduat_tgk_store_mem_resolve_edge( amduat_tgk_edge_body_t *out_body) { amduat_tgk_store_mem_t *mem = (amduat_tgk_store_mem_t *)ctx; const amduat_tgk_store_mem_artifact_t *entry; + bool conflict = false; if (out_body != NULL) { memset(out_body, 0, sizeof(*out_body)); @@ -466,7 +543,10 @@ static amduat_tgk_graph_error_t amduat_tgk_store_mem_resolve_edge( if (!amduat_tgk_store_mem_hash_id_supported(mem, ref.hash_id)) { return GS_ERR_UNSUPPORTED; } - entry = amduat_tgk_store_mem_lookup_artifact(mem, ref); + entry = amduat_tgk_store_mem_lookup_artifact(mem, ref, &conflict); + if (conflict) { + return GS_ERR_INTEGRITY; + } if (entry == NULL) { return GS_ERR_ARTIFACT_ERROR; } @@ -657,6 +737,9 @@ bool amduat_tgk_store_mem_init(amduat_tgk_store_mem_t *mem, mem->edges = NULL; mem->edges_len = 0; + if (!amduat_tgk_store_mem_id_space_valid(config.id_space)) { + return false; + } if (config.tgk_profiles.encodings_len != 0 && config.tgk_profiles.encodings == NULL) { return false; @@ -685,7 +768,15 @@ bool amduat_tgk_store_mem_init(amduat_tgk_store_mem_t *mem, amduat_tgk_edge_body_t body; amduat_tgk_graph_error_t err; const amduat_tgk_store_mem_artifact_t *entry = &artifacts[i]; + bool duplicate = false; + if (!amduat_tgk_store_mem_check_duplicate_artifact(artifacts, i, + &duplicate)) { + goto cleanup; + } + if (duplicate) { + continue; + } if (!amduat_tgk_store_mem_hash_id_supported(mem, entry->ref.hash_id)) { continue; }