=== trunk/subversion/tests/libsvn_repos/repos-test.c
==================================================================
--- trunk/subversion/tests/libsvn_repos/repos-test.c  (revision 127)
+++ trunk/subversion/tests/libsvn_repos/repos-test.c  (revision 131)
@@ -1130,6 +1130,12 @@
    * and another containing a reference to an undefined group.  Verify
    * that svn_repos_authz_read fails to load both and returns an
    * "invalid configuration" error.
+   *
+   * 3. Regression test for a bug in how recursion is handled in
+   * authz.  The bug was that paths not under the parent path
+   * requested were being considered during the determination of
+   * access rights (eg. a rule for /dir2 matched during a lookup for
+   * /dir), due to incomplete tests on path relations.
    */
 
   /* The authz rules for the phase 1 tests. */
@@ -1254,6 +1260,33 @@
                               err ? "unexpected" : "no");
   svn_error_clear (err);
 
+  /* The authz rules for the phase 3 tests */
+  contents =
+    "[/]"
+    APR_EOL_STR
+    "* = rw"
+    APR_EOL_STR
+    APR_EOL_STR
+    "[greek:/dir2/secret]"
+    APR_EOL_STR
+    "* ="
+    APR_EOL_STR;
+
+  /* Load the test authz rules. */
+  SVN_ERR (authz_get_handle(&authz, contents, subpool));
+
+  /* Verify that the rule on /dir2/secret doesn't affect this
+     request */
+  SVN_ERR (svn_repos_authz_check_access (authz, "greek",
+                                         "/dir", NULL,
+                                         (svn_authz_read
+                                          | svn_authz_recursive),
+                                         &access_granted, subpool));
+  if (!access_granted)
+    return svn_error_create (SVN_ERR_TEST_FAILED, NULL,
+                             "Regression: incomplete ancestry test "
+                             "for recursive access lookup.");
+
   /* That's a wrap! */
   svn_pool_destroy (subpool);
   return SVN_NO_ERROR;
=== trunk/subversion/libsvn_repos/authz.c
==================================================================
--- trunk/subversion/libsvn_repos/authz.c  (revision 127)
+++ trunk/subversion/libsvn_repos/authz.c  (revision 131)
@@ -197,6 +197,24 @@
 
 
 
+/*
+ * Utility function for authz_parse_section, to determine whether
+ * path2 is a child of path1 (or *is* path1).
+ */
+static svn_boolean_t
+authz_path_is_ancestor (const char *path1, const char *path2)
+{
+  apr_size_t path1_len = strlen (path1);
+
+  if (strncmp (path1, path2, path1_len) == 0)
+    return path1[path1_len - 1] == '/'
+      || (path2[path1_len] == '/' || path2[path1_len] == '\0');
+
+  return FALSE;
+}
+
+
+
 /* Callback to parse a section and update the authz_baton if the
  * section denies access to the subtree the baton describes.
  */
@@ -207,10 +225,10 @@
   svn_boolean_t conclusive;
 
   /* Does the section apply to us? */
-  if (strncmp (section_name, b->qualified_repos_path,
-               strlen (b->qualified_repos_path)) != 0
-      && strncmp (section_name, b->repos_path,
-                  strlen (b->repos_path)) != 0)
+  if (authz_path_is_ancestor (b->qualified_repos_path,
+                              section_name) == FALSE
+      && authz_path_is_ancestor (b->repos_path,
+                                 section_name) == FALSE)
     return TRUE;
 
   /* Work out what this section grants. */

