From d23cdacb0da95a177dc7708bd26f284af732e508 Mon Sep 17 00:00:00 2001
From: Simon McVittie <simon.mcvittie@collabora.co.uk>
Date: Thu, 7 Apr 2011 14:45:19 +0100
Subject: [PATCH 4/7] path_prefix: anchor matches at path-component boundaries, and give examples

It seems wrong that path_prefix="/foo" matches /foobar, and it isn't
difficult or expensive to check.
---
 bus/signals.c              |   14 +++++++++++++-
 doc/dbus-specification.xml |   31 +++++++++++++++++++++++++++----
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/bus/signals.c b/bus/signals.c
index 0d18dc6..5913334 100644
--- a/bus/signals.c
+++ b/bus/signals.c
@@ -1801,6 +1801,7 @@ match_rule_matches (BusMatchRule    *rule,
   if (flags & BUS_MATCH_PATH_PREFIX)
     {
       const char *path;
+      int len;
 
       _dbus_assert (rule->path_prefix != NULL);
 
@@ -1810,6 +1811,17 @@ match_rule_matches (BusMatchRule    *rule,
 
       if (!str_has_prefix (path, rule->path_prefix))
         return FALSE;
+
+      len = strlen (rule->path_prefix);
+
+      /* Check that the actual argument is within the expected
+       * namespace, rather than just starting with that string,
+       * by checking that the matched prefix either ends in a '/',
+       * or is followed by a '/' or the end of the path.
+       */
+      if (rule->path_prefix[len - 1] != '/' &&
+          path[len] != '\0' && path[len] != '/')
+        return FALSE;
     }
 
   if (flags & BUS_MATCH_ARGS)
@@ -2736,12 +2748,12 @@ path_prefix_should_not_match_message_2[] = {
 
 static const char*
 path_prefix_should_match_message_3[] = {
-  "type='signal',path_prefix='/foo/TheObjectManager'",
   NULL
 };
 
 static const char*
 path_prefix_should_not_match_message_3[] = {
+  "type='signal',path_prefix='/foo/TheObjectManager'",
   "type='signal',path_prefix='/foo/TheObjectManager/'",
   NULL
 };
diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml
index 1c19a4a..63146bb 100644
--- a/doc/dbus-specification.xml
+++ b/doc/dbus-specification.xml
@@ -3727,10 +3727,33 @@
                   <entry>
                     <para>
                       Matches messages which are sent from or to an
-                      object for which the object path is a prefix of
-                      the given value. Examples of matches are
-                      path_prefix='/org/Application/ObjectManager' or
-                      path_prefix='/org/Application/ContactObjects/'.
+                      object for which the object path is a descendant of
+                      the given value. If the prefix ends with a slash, it
+                      matches all paths starting with that string;
+                      if it does not end with a slash, it matches either
+                      that exact path, or that path followed by one or
+                      more path components.
+                    </para>
+
+                    <para>
+                      For example,
+                      <literal>path_prefix='/com/example/foo'</literal>
+                      would match signals sent by
+                      <literal>/com/example/foo</literal>
+                      or by
+                      <literal>/com/example/foo/bar</literal>,
+                      but not by
+                      <literal>/com/example/foobar</literal>.
+                    </para>
+
+                    <para>
+                      However,
+                      <literal>path_prefix='/com/example/foo/'</literal>
+                      would still match signals sent by
+                      <literal>/com/example/foo/bar</literal>,
+                      but would not match signals sent by
+                      <literal>/com/example/foo</literal> or
+                      <literal>/com/example/foobar</literal>.
                     </para>
                     <para>
                       <emphasis>
-- 
1.7.4.1