From 76cb26541b6359c24d8e4cc922df6e8f829abf90 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Tue, 3 Jan 2023 22:29:59 +0100 Subject: [PATCH] crossroads: Do not output descendants on introspection Fixes: #412 --- dbus-crossroads/src/crossroads.rs | 8 +++++--- dbus-crossroads/src/stdimpl.rs | 4 ++-- dbus-crossroads/src/test.rs | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dbus-crossroads/src/crossroads.rs b/dbus-crossroads/src/crossroads.rs index cbdf2461..679e4f86 100644 --- a/dbus-crossroads/src/crossroads.rs +++ b/dbus-crossroads/src/crossroads.rs @@ -224,17 +224,19 @@ impl Crossroads { (&self.registry, &obj.ifaces) } - pub (crate) fn get_children(&self, path: &dbus::Path<'static>) -> Vec<&str> { + pub (crate) fn get_children(&self, path: &dbus::Path<'static>, direct_only: bool) -> Vec<&str> { use std::ops::Bound; let mut range = self.map.range((Bound::Excluded(path), Bound::Unbounded)); let p2 = path.as_bytes(); let substart = if &p2 == &b"/" { 0 } else { p2.len() }; - let mut r = vec!(); + let mut r: Vec<&str> = vec!(); while let Some((c, _)) = range.next() { if !c.as_bytes().starts_with(p2) { break; } let csub: &str = &c[substart..]; if csub.len() == 0 || csub.as_bytes()[0] != b'/' { continue; } - r.push(&csub[1..]); + let csub1 = &csub[1..]; + if direct_only && r.len() > 0 && csub1.as_bytes().starts_with(r[r.len()-1].as_bytes()) { continue; } + r.push(csub1); }; r } diff --git a/dbus-crossroads/src/stdimpl.rs b/dbus-crossroads/src/stdimpl.rs index 83094cf8..79f8c7e2 100644 --- a/dbus-crossroads/src/stdimpl.rs +++ b/dbus-crossroads/src/stdimpl.rs @@ -9,7 +9,7 @@ use std::marker::PhantomData; use crate::ifacedesc::EMITS_CHANGED; fn introspect(cr: &Crossroads, path: &dbus::Path<'static>) -> String { - let mut children = cr.get_children(path); + let mut children = cr.get_children(path, true); let mut childstr = String::new(); children.sort_unstable(); for c in children { @@ -347,7 +347,7 @@ fn get_managed_objects(mut ctx: Context, cr: &mut Crossroads, _: ()) -> Option, IfacePropMap> let parent = ctx.path(); let children: Vec> = - cr.get_children(ctx.path()).into_iter().map(|child_path| { + cr.get_children(ctx.path(), false).into_iter().map(|child_path| { let mut x = String::from(&**parent); if !x.ends_with('/') { x.push_str("/"); diff --git a/dbus-crossroads/src/test.rs b/dbus-crossroads/src/test.rs index c728ef08..73a8bedc 100644 --- a/dbus-crossroads/src/test.rs +++ b/dbus-crossroads/src/test.rs @@ -164,6 +164,7 @@ fn introspect() { }); cr.insert("/com/example/sample_object0", &[token], ()); cr.insert("/com/example/sample_object0/child_of_sample_object", &[], ()); + cr.insert("/com/example/sample_object0/child_of_sample_object/subchild", &[], ()); cr.insert("/com/example/sample_object0123", &[], ()); cr.insert("/com/example/sample_object0/another_child_of_sample_object", &[], ());