From 592e97158855182be01ca77a30bc2452f29fd0e5 Mon Sep 17 00:00:00 2001 From: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz> Date: Fri, 16 Oct 2026 15:44:51 -0400 Subject: [PATCH] test(buzz-db): detect ON CONFLICT( upserts at a token boundary sql_update_sets() matched only the spaced ' on conflict ' spelling, so ON CONFLICT(request_id) DO UPDATE ... slipped past the approval append-only rule and the manifest content-UPDATE rule. Match on conflict and do update set at identifier boundaries and add no-space negative fixtures for both tables plus a no-space DO NOTHING accept fixture. Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz> --- crates/buzz-db/tests/observability_source.rs | 35 +++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/crates/buzz-db/tests/observability_source.rs b/crates/buzz-db/tests/observability_source.rs index 813880c6c6..18dc409cfd 100644 --- a/crates/buzz-db/tests/observability_source.rs +++ b/crates/buzz-db/tests/observability_source.rs @@ -1947,19 +1947,25 @@ const SINGLE_TABLE_GUARD_TABLES: [&str; 5] = [ ]; const DELETION_STORE_PATH: &str = "buzz-db/src/store/deletion.rs"; +/// The text after each occurrence of `marker` that sits on identifier +/// boundaries, so `on conflict` matches before a space or `(` alike. +fn sql_token_suffixes<'a>(source: &'a str, marker: &str) -> Vec<&'a str> { + let is_ident = |ch: char| ch.is_ascii_alphanumeric() || ch == '_'; + source + .match_indices(marker) + .filter_map(|(at, found)| { + let rest = &source[at + found.len()..]; + (!source[..at].chars().next_back().is_some_and(is_ident) + && !rest.chars().next().is_some_and(is_ident)) + .then_some(rest) + }) + .collect() +} + fn sql_table_suffixes<'a>(source: &'a str, verb: &str, table: &str) -> Vec<&'a str> { [format!("{verb} {table}"), format!("{verb} public.{table}")] .iter() - .flat_map(|marker| { - source.match_indices(marker).filter_map(|(at, found)| { - let before = &source[..at]; - let rest = &source[at + found.len()..]; - let is_ident = |ch: char| ch.is_ascii_alphanumeric() || ch == '_'; - (!before.chars().next_back().is_some_and(is_ident) - && !rest.chars().next().is_some_and(is_ident)) - .then_some(rest) - }) - }) + .flat_map(|marker| sql_token_suffixes(source, marker)) .collect() } @@ -1979,8 +1985,10 @@ fn sql_update_sets<'a>(source: &'a str, table: &str) -> Vec<(&'a str, &'a str)> .into_iter() .filter_map(|rest| { let statement = rest.split(['"', ';']).next()?; - let (_, conflict) = statement.split_once(" on conflict ")?; - conflict.split_once(" do update set ").map(|(_, set)| set) + let conflict = *sql_token_suffixes(statement, "on conflict").first()?; + sql_token_suffixes(conflict, "do update set") + .first() + .map(|set| set.trim_start()) }); updates .chain(conflict_updates) @@ -2510,6 +2518,7 @@ fn single_table_policy_rejects_approval_mutations() { "UPDATE community_deletion_approvals SET approved_by = $1 WHERE request_id = $2", "DELETE FROM community_deletion_approvals WHERE request_id = $1", "INSERT INTO community_deletion_approvals (request_id, note) VALUES ($1, $2) ON CONFLICT (request_id) DO UPDATE SET note = EXCLUDED.note", + "INSERT INTO community_deletion_approvals (request_id, note) VALUES ($1, $2) ON CONFLICT(request_id) DO UPDATE SET note = EXCLUDED.note", ] { let source = format!("async fn bypass() {{ query(\"{sql}\"); }}"); assert_eq!( @@ -2522,6 +2531,7 @@ fn single_table_policy_rejects_approval_mutations() { let append = r#"async fn approve() { query("INSERT INTO community_deletion_approvals (request_id, note) VALUES ($1, $2)"); query("INSERT INTO community_deletion_approvals (request_id, note) VALUES ($1, $2) ON CONFLICT (request_id) DO NOTHING"); + query("INSERT INTO community_deletion_approvals (request_id, note) VALUES ($1, $2) ON CONFLICT(request_id) DO NOTHING"); }"#; assert!( single_table_guard_violations(DELETION_STORE_PATH, append, &mut Default::default()) @@ -2580,6 +2590,7 @@ fn single_table_policy_rejects_manifest_content_updates() { for sql in [ "UPDATE community_deletion_manifest_keys SET keys = $1 WHERE request_id = $2", "INSERT INTO community_deletion_manifest_keys (request_id, chunk_no, keys) VALUES ($1, $2, $3) ON CONFLICT (request_id, chunk_no) DO UPDATE SET keys = EXCLUDED.keys", + "INSERT INTO community_deletion_manifest_keys (request_id, chunk_no, keys) VALUES ($1, $2, $3) ON CONFLICT(request_id, chunk_no) DO UPDATE SET keys = EXCLUDED.keys", ] { let source = format!("async fn append() {{ guard_manifest_chunk_write(); query(\"{sql}\"); }}"); let violations =