Skip to content

Commit f78722b

Browse files
committed
codetracer-python-recorder/src/trace_filter/engine.rs:i Address review comment
Signed-off-by: Tzanko Matev <[email protected]>
1 parent 2ace132 commit f78722b

File tree

1 file changed

+79
-9
lines changed
  • codetracer-python-recorder/src/trace_filter

1 file changed

+79
-9
lines changed

codetracer-python-recorder/src/trace_filter/engine.rs

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,7 @@ impl TraceFilterEngine {
253253
value_default = rule_value;
254254
}
255255
if !rule.value_patterns.is_empty() {
256-
let mut merged =
257-
Vec::with_capacity(rule.value_patterns.len() + patterns.len());
256+
let mut merged = Vec::with_capacity(rule.value_patterns.len() + patterns.len());
258257
merged.extend(rule.value_patterns.iter().cloned());
259258
merged.extend(patterns.into_iter());
260259
patterns = merged;
@@ -404,10 +403,20 @@ impl ScopeContext {
404403
}
405404
});
406405

407-
let module_name = relative_path
406+
let mut module_name = relative_path
408407
.as_deref()
409408
.and_then(|rel| module_from_relative(rel).map(|cow| cow.into_owned()));
410409

410+
if module_name.is_none() {
411+
module_name = absolute_path
412+
.as_deref()
413+
.and_then(|abs| module_from_relative(abs).map(|cow| cow.into_owned()));
414+
}
415+
416+
if module_name.is_none() && !qualname.is_empty() {
417+
module_name = Some(qualname.to_string());
418+
}
419+
411420
let object_name = module_name
412421
.as_ref()
413422
.map(|module| format!("{}.{}", module, qualname))
@@ -473,12 +482,15 @@ fn module_from_relative(relative: &str) -> Option<Cow<'_, str>> {
473482
if relative.is_empty() {
474483
return None;
475484
}
476-
let trimmed = relative.trim_start_matches("./");
485+
let trimmed = relative.trim_start_matches("./").trim_start_matches('/');
477486
let without_suffix = trimmed.strip_suffix(".py").unwrap_or(trimmed);
478487
if without_suffix.is_empty() {
479488
return None;
480489
}
481-
let mut parts: Vec<&str> = without_suffix.split('/').collect();
490+
let mut parts: Vec<&str> = without_suffix
491+
.split('/')
492+
.filter(|segment| !segment.is_empty())
493+
.collect();
482494
if let Some(last) = parts.last().copied() {
483495
if last == "__init__" {
484496
parts.pop();
@@ -509,6 +521,67 @@ mod tests {
509521
use std::io::Write;
510522
use tempfile::tempdir;
511523

524+
#[test]
525+
fn builtin_redactions_apply_without_project_filter() -> RecorderResult<()> {
526+
use std::path::PathBuf;
527+
528+
const BUILTIN_LABEL: &str = "builtin-default";
529+
const BUILTIN_FILTER: &str =
530+
include_str!("../../resources/trace_filters/builtin_default.toml");
531+
532+
let config =
533+
TraceFilterConfig::from_inline_and_paths(&[(BUILTIN_LABEL, BUILTIN_FILTER)], &[])?;
534+
assert_eq!(config.sources().len(), 1);
535+
536+
let mut inline_source = config.sources()[0].clone();
537+
inline_source.project_root = PathBuf::from(".");
538+
539+
let rules = compile_rules(config.rules());
540+
let mut value_default = config.default_value_action();
541+
let mut patterns: Vec<CompiledValuePattern> = Vec::new();
542+
543+
let temp = tempdir().expect("temp dir");
544+
let script_path = temp.path().join("app.py");
545+
fs::write(&script_path, "print('placeholder')\n").expect("create script file");
546+
let script_path = script_path.to_string_lossy().to_string();
547+
548+
let context = ScopeContext::derive(&script_path, "leak", &[inline_source]);
549+
assert!(
550+
context.relative_path.is_none(),
551+
"expected unresolved relative path"
552+
);
553+
assert!(
554+
context.module_name.is_some(),
555+
"module name should be derived despite missing project filter"
556+
);
557+
558+
for rule in rules.iter() {
559+
if rule.matches(&context) {
560+
if let Some(rule_value) = rule.value_default {
561+
value_default = rule_value;
562+
}
563+
if !rule.value_patterns.is_empty() {
564+
let mut merged = Vec::with_capacity(rule.value_patterns.len() + patterns.len());
565+
merged.extend(rule.value_patterns.iter().cloned());
566+
merged.extend(patterns.into_iter());
567+
patterns = merged;
568+
}
569+
}
570+
}
571+
572+
let policy = ValuePolicy::new(value_default, patterns.into());
573+
574+
assert_eq!(
575+
policy.decide(ValueKind::Local, "password"),
576+
ValueAction::Redact
577+
);
578+
assert_eq!(
579+
policy.decide(ValueKind::Arg, "password"),
580+
ValueAction::Redact
581+
);
582+
Ok(())
583+
}
584+
512585
#[test]
513586
fn caches_resolution_and_applies_value_patterns() -> RecorderResult<()> {
514587
let (config, file_path) = filter_with_pkg_rule(
@@ -705,10 +778,7 @@ mod tests {
705778
policy.decide(ValueKind::Local, "secret_token"),
706779
ValueAction::Allow
707780
);
708-
assert_eq!(
709-
policy.decide(ValueKind::Local, "other"),
710-
ValueAction::Allow
711-
);
781+
assert_eq!(policy.decide(ValueKind::Local, "other"), ValueAction::Allow);
712782
Ok(())
713783
})
714784
}

0 commit comments

Comments
 (0)