Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ref(relay): Move cabi glob matching into cabi #3924

Merged
merged 1 commit into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions relay-cabi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ workspace = true
[dependencies]
anyhow = { workspace = true, features = ["backtrace"] }
chrono = { workspace = true }
globset = { workspace = true }
json-forensics = { workspace = true }
lru = { workspace = true }
once_cell = { workspace = true }
Expand Down
64 changes: 50 additions & 14 deletions relay-common/src/glob.rs → relay-cabi/src/glob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,58 @@ use std::num::NonZeroUsize;
use globset::GlobBuilder;
use lru::LruCache;
use once_cell::sync::Lazy;
use parking_lot::Mutex;
use regex::bytes::{Regex, RegexBuilder};
use std::sync::{Mutex, PoisonError};

use crate::{RelayBuf, RelayStr};

/// Controls the globbing behaviors.
#[repr(u32)]
pub enum GlobFlags {
/// When enabled `**` matches over path separators and `*` does not.
DoubleStar = 1,
/// Enables case insensitive path matching.
CaseInsensitive = 2,
/// Enables path normalization.
PathNormalize = 4,
/// Allows newlines.
AllowNewline = 8,
}

/// Performs a glob operation on bytes.
///
/// Returns `true` if the glob matches, `false` otherwise.
#[no_mangle]
#[relay_ffi::catch_unwind]
pub unsafe extern "C" fn relay_is_glob_match(
value: *const RelayBuf,
pat: *const RelayStr,
flags: GlobFlags,
) -> bool {
let mut options = GlobOptions::default();
let flags = flags as u32;
if (flags & GlobFlags::DoubleStar as u32) != 0 {
options.double_star = true;
}
if (flags & GlobFlags::CaseInsensitive as u32) != 0 {
options.case_insensitive = true;
}
if (flags & GlobFlags::PathNormalize as u32) != 0 {
options.path_normalize = true;
}
if (flags & GlobFlags::AllowNewline as u32) != 0 {
options.allow_newline = true;
}
glob_match_bytes((*value).as_bytes(), (*pat).as_str(), options)
}

/// LRU cache for [`Regex`]s in relation to [`GlobOptions`] and the provided string pattern.
static GLOB_CACHE: Lazy<Mutex<LruCache<(GlobOptions, String), Regex>>> =
Lazy::new(|| Mutex::new(LruCache::new(NonZeroUsize::new(500).unwrap())));

/// Controls the options of the globber.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct GlobOptions {
struct GlobOptions {
/// When enabled `**` matches over path separators and `*` does not.
pub double_star: bool,
/// Enables case insensitive path matching.
Expand All @@ -40,7 +82,7 @@ fn translate_pattern(pat: &str, options: GlobOptions) -> Option<Regex> {
/// Performs a glob operation on bytes.
///
/// Returns `true` if the glob matches, `false` otherwise.
pub fn glob_match_bytes(value: &[u8], pat: &str, options: GlobOptions) -> bool {
fn glob_match_bytes(value: &[u8], pat: &str, options: GlobOptions) -> bool {
let (value, pat) = if options.path_normalize {
(
Cow::Owned(
Expand All @@ -55,7 +97,7 @@ pub fn glob_match_bytes(value: &[u8], pat: &str, options: GlobOptions) -> bool {
(Cow::Borrowed(value), pat.to_string())
};
let key = (options, pat);
let mut cache = GLOB_CACHE.lock();
let mut cache = GLOB_CACHE.lock().unwrap_or_else(PoisonError::into_inner);

if let Some(pattern) = cache.get(&key) {
pattern.is_match(&value)
Expand All @@ -68,20 +110,14 @@ pub fn glob_match_bytes(value: &[u8], pat: &str, options: GlobOptions) -> bool {
}
}

/// Performs a glob operation.
///
/// Returns `true` if the glob matches.
///
/// Note that even though this accepts strings, the case insensitivity here is only
/// applied on ASCII characters as the underlying globber matches on bytes exclusively.
pub fn glob_match(value: &str, pat: &str, options: GlobOptions) -> bool {
glob_match_bytes(value.as_bytes(), pat, options)
}

#[cfg(test)]
mod tests {
use super::*;

fn glob_match(value: &str, pat: &str, options: GlobOptions) -> bool {
glob_match_bytes(value.as_bytes(), pat, options)
}

#[test]
fn test_globs() {
macro_rules! test_glob {
Expand Down
2 changes: 2 additions & 0 deletions relay-cabi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,13 @@ mod codeowners;
mod constants;
mod core;
mod ffi;
mod glob;
mod processing;

pub use crate::auth::*;
pub use crate::codeowners::*;
pub use crate::constants::*;
pub use crate::core::*;
pub use crate::ffi::*;
pub use crate::glob::*;
pub use crate::processing::*;
43 changes: 1 addition & 42 deletions relay-cabi/src/processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use std::sync::OnceLock;

use chrono::{DateTime, Utc};
use relay_cardinality::CardinalityLimit;
use relay_common::glob::{glob_match_bytes, GlobOptions};
use relay_dynamic_config::{normalize_json, GlobalConfig, ProjectConfig};
use relay_event_normalization::{
normalize_event, validate_event, BreakdownsConfig, ClientHints, EventValidationConfig,
Expand All @@ -28,7 +27,7 @@ use relay_sampling::SamplingConfig;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::core::{RelayBuf, RelayStr};
use crate::core::RelayStr;

/// Configuration for the store step -- validation and normalization.
#[derive(Serialize, Deserialize, Debug, Default)]
Expand Down Expand Up @@ -369,46 +368,6 @@ pub unsafe extern "C" fn relay_test_panic() -> () {
panic!("this is a test panic")
}

/// Controls the globbing behaviors.
#[repr(u32)]
pub enum GlobFlags {
/// When enabled `**` matches over path separators and `*` does not.
DoubleStar = 1,
/// Enables case insensitive path matching.
CaseInsensitive = 2,
/// Enables path normalization.
PathNormalize = 4,
/// Allows newlines.
AllowNewline = 8,
}

/// Performs a glob operation on bytes.
///
/// Returns `true` if the glob matches, `false` otherwise.
#[no_mangle]
#[relay_ffi::catch_unwind]
pub unsafe extern "C" fn relay_is_glob_match(
value: *const RelayBuf,
pat: *const RelayStr,
flags: GlobFlags,
) -> bool {
let mut options = GlobOptions::default();
let flags = flags as u32;
if (flags & GlobFlags::DoubleStar as u32) != 0 {
options.double_star = true;
}
if (flags & GlobFlags::CaseInsensitive as u32) != 0 {
options.case_insensitive = true;
}
if (flags & GlobFlags::PathNormalize as u32) != 0 {
options.path_normalize = true;
}
if (flags & GlobFlags::AllowNewline as u32) != 0 {
options.allow_newline = true;
}
glob_match_bytes((*value).as_bytes(), (*pat).as_str(), options)
}

/// Parse a sentry release structure from a string.
#[no_mangle]
#[relay_ffi::catch_unwind]
Expand Down
2 changes: 0 additions & 2 deletions relay-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ workspace = true
[dependencies]
chrono = { workspace = true }
globset = { workspace = true }
lru = { workspace = true }
once_cell = { workspace = true }
parking_lot = { workspace = true }
regex = { workspace = true }
sentry-types = { workspace = true }
serde = { workspace = true }
Expand Down
1 change: 0 additions & 1 deletion relay-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

mod macros;

pub mod glob;
pub mod glob2;
pub mod glob3;
pub mod time;
Expand Down
Loading