From cb38f68c0c880f1dad554e1e394c0ce406fa4890 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Sat, 24 Oct 2026 04:45:01 -0400 Subject: [PATCH] fix(security): linear docprops reordering and deduplicate restored deletion nodes (#1258) * fix(security): linear docprops reordering and deduplicate restored deletion nodes * style: format if-let condition --- crates/collab/src/docprops.rs | 9 +++------ crates/collab/src/server.rs | 5 ++++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/collab/src/docprops.rs b/crates/collab/src/docprops.rs index 9b35e05da..e4ff32c2f 100644 --- a/crates/collab/src/docprops.rs +++ b/crates/collab/src/docprops.rs @@ -132,18 +132,15 @@ impl List { let keys: Vec = value.read("order")?; let list = (self.get_mut)(doc); let mut slots: Vec> = std::mem::take(list).into_iter().map(Some).collect(); - let mut at: BTreeMap> = BTreeMap::new(); + let mut at: BTreeMap> = BTreeMap::new(); for (i, e) in slots.iter().enumerate() { if let Some(e) = e { - at.entry(e.key()).or_default().push(i); + at.entry(e.key()).or_default().push_back(i); } } for k in keys { let Some(idx) = at.get_mut(&k) else { continue }; - if idx.is_empty() { - continue; - } - let i = idx.remove(0); + let Some(i) = idx.pop_front() else { continue }; if let Some(e) = slots.get_mut(i).and_then(Option::take) { list.push(e); } diff --git a/crates/collab/src/server.rs b/crates/collab/src/server.rs index 38ed3de8f..dd654efe6 100644 --- a/crates/collab/src/server.rs +++ b/crates/collab/src/server.rs @@ -541,11 +541,14 @@ impl Server { nodes.extend(t.write(self.state.value(&t)?.as_ref())); } } + let mut restored = std::collections::BTreeSet::new(); for id in gone { match doc.node(id) { Some(_) => { for d in doc.subtree(id) { - if let Some(n) = doc.node(d) { + if restored.insert(d) + && let Some(n) = doc.node(d) + { nodes.push(create_change(n, self.state.key(d))?); } }