From 8807db531458d7108880d4aad6f3aa01f0751969 Mon Sep 17 00:00:00 2001 From: Einliterflasche Date: Wed, 7 Aug 2024 14:11:58 +0200 Subject: [PATCH] move regex automata to lazy statics using macro and once_cell --- Cargo.lock | 1 + swap/Cargo.toml | 1 + swap/src/common.rs | 72 +++++++++++++++++----------------------------- 3 files changed, 28 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee9ae00a..1b58ff6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4571,6 +4571,7 @@ dependencies = [ "monero", "monero-harness", "monero-rpc", + "once_cell", "pem", "port_check", "proptest", diff --git a/swap/Cargo.toml b/swap/Cargo.toml index 27c75f1b..4fd43a2e 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -37,6 +37,7 @@ jsonrpsee-core = "0.16.2" libp2p = { version = "0.42.2", default-features = false, features = [ "tcp-tokio", "yamux", "mplex", "dns-tokio", "noise", "request-response", "websocket", "ping", "rendezvous", "identify" ] } monero = { version = "0.12", features = [ "serde_support" ] } monero-rpc = { path = "../monero-rpc" } +once_cell = "1.19" pem = "3.0" proptest = "1" qrcode = "0.14" diff --git a/swap/src/common.rs b/swap/src/common.rs index 00703942..54332f01 100644 --- a/swap/src/common.rs +++ b/swap/src/common.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use anyhow::anyhow; -use regex::Regex; const LATEST_RELEASE_URL: &str = "https://github.com/comit-network/xmr-btc-swap/releases/latest"; @@ -36,6 +35,26 @@ fn is_latest_version(current: &str, latest: &str) -> bool { current == latest } +/// helper macro for [`redact`]... eldrich sorcery +macro_rules! regex_find_placeholders { + ($pattern:expr, $create_placeholder:expr, $replacements:expr, $input:expr) => {{ + // compile the regex pattern + let regex = once_cell::sync::Lazy::new(|| regex::Regex::new($pattern).expect("invalid regex pattern")); + + // keep count of count patterns to generate distinct placeholders + let mut counter: usize = 0; + + // for every matched address check whether we already found it + // and if we didn't, generate a placeholder for it + for address in regex.find_iter($input) { + if !$replacements.contains_key(address.as_str()) { + $replacements.insert(address.as_str().to_owned(), $create_placeholder(counter)); + counter += 1; + } + } + }}; +} + /// Redact logs, etc. by replacing Bitcoin and Monero addresses /// with generic placeholders. /// @@ -50,32 +69,6 @@ pub fn redact(input: &str) -> String { // Use a hashmap to keep track of which address we replace with which placeholder let mut replacements: HashMap = HashMap::new(); - /// Helper function to insert placeholders for all addresses - /// of a specific regex pattern into the hashmap. - fn insert_placeholders( - input: &str, - replacements: &mut HashMap, - pattern: &str, - create_placeholder: impl Fn(usize) -> String, - ) -> Result<(), regex::Error> { - // compile the regex pattern - let regex = Regex::new(pattern)?; - - // keep count to generate distinct placeholders - let mut counter: usize = 0; - - // for every matched address check whether we already found it - // and if we didn't, generate a placeholder for it - for address in regex.find_iter(input) { - if !replacements.contains_key(address.as_str()) { - replacements.insert(address.as_str().to_owned(), create_placeholder(counter)); - counter += 1; - } - } - - Ok(()) - } - // TODO: verify regex patterns const MONERO_ADDR_REGEX: &str = r#"[48][1-9A-HJ-NP-Za-km-z]{94}"#; @@ -86,25 +79,12 @@ pub fn redact(input: &str) -> String { const SWAP_ID_REGEX: &str = r#"\b[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}\b"#; - insert_placeholders(input, &mut replacements, MONERO_ADDR_REGEX, |count| { - format!("") - }) - .expect("regex to be valid"); - - insert_placeholders(input, &mut replacements, BITCOIN_ADDR_REGEX, |count| { - format!("") - }) - .expect("regex to be valid"); - - insert_placeholders(input, &mut replacements, TX_ID_REGEX, |count| { - format!("") - }) - .expect("regex to be valid"); - - insert_placeholders(input, &mut replacements, SWAP_ID_REGEX, |count| { - format!("") - }) - .expect("regex to be valid"); + // use the macro to find all addresses and generate placeholders + // has to be a macro in order to create the regex automata only once. + regex_find_placeholders!(MONERO_ADDR_REGEX, |count| format!(""), replacements, input); + regex_find_placeholders!(BITCOIN_ADDR_REGEX, |count| format!(""), replacements, input); + regex_find_placeholders!(TX_ID_REGEX, |count| format!(""), replacements, input); + regex_find_placeholders!(SWAP_ID_REGEX, |count| format!(""), replacements, input); // allocate string variable to operate on let mut redacted = input.to_owned();