From 0ed79071da40fc1473eb21b9d6647e761effb78e Mon Sep 17 00:00:00 2001 From: Nikolai Golub Date: Thu, 22 Oct 2026 10:01:18 +0200 Subject: [PATCH] fix(beatree): prevent underflow on deletion of non-existend key --- nomt/src/beatree/ops/update/leaf_stage.rs | 2 +- nomt/tests/add_remove.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/nomt/src/beatree/ops/update/leaf_stage.rs b/nomt/src/beatree/ops/update/leaf_stage.rs index 8ddb37fbab..3f965be212 100644 --- a/nomt/src/beatree/ops/update/leaf_stage.rs +++ b/nomt/src/beatree/ops/update/leaf_stage.rs @@ -231,7 +231,7 @@ fn filter_leaves_changeset(leaf_changeset: &mut Vec<(Key, Option)>) // The deleted page was already inserted in the freed_pages, thus, // now only the inserted page must be kept, resulting in a standard // modification of the same page, but made by two workers. - for i in 0..leaf_changeset.len() - 1 { + for i in 0..leaf_changeset.len().saturating_sub(1) { if leaf_changeset[i].0 == leaf_changeset[i + 1].0 { // PANICS: If two changesets refer to the same page, they // are expected to be treated as a single one, with one diff --git a/nomt/tests/add_remove.rs b/nomt/tests/add_remove.rs index 28aae763c3..fc5a6ace49 100644 --- a/nomt/tests/add_remove.rs +++ b/nomt/tests/add_remove.rs @@ -54,3 +54,19 @@ fn add_remove_1000() { assert_eq!(root, expected_roots[10 - i - 1]); } } + +#[test] +fn delete_missing_key_in_empty_db() { + let mut t = Test::new("delete_missing_key_in_empty_db"); + t.write([0; 32], None); + assert_eq!(t.commit().0.into_inner(), Node::default()); +} + +#[test] +fn delete_missing_key_in_non_empty_db() { + let mut t = Test::new("delete_missing_key_in_non_empty_db"); + common::set_balance(&mut t, 0, 1000); + let root = t.commit().0; + common::kill(&mut t, 1); + assert_eq!(t.commit().0, root); +}