subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cmpil...@apache.org
Subject svn commit: r931190 - in /subversion/trunk/subversion: include/private/svn_mergeinfo_private.h libsvn_subr/mergeinfo.c tests/libsvn_subr/mergeinfo-test.c
Date Tue, 06 Apr 2010 15:48:58 GMT
Author: cmpilato
Date: Tue Apr  6 15:48:58 2010
New Revision: 931190

URL: http://svn.apache.org/viewvc?rev=931190&view=rev
Log:
Rework svn_mergeinfo__remove_prefix_from_catalog() so that its output
is more consistent with Subversion path handling/passing semantics.

* subversion/include/private/svn_mergeinfo_private.h
  (svn_mergeinfo__remove_prefix_from_catalog): Update docstring to
    indicate new stricter (and more useful!) semantics.

* subversion/libsvn_subr/mergeinfo.c
  (svn_mergeinfo__remove_prefix_from_catalog): Rename 'prefix' to
    'prefix_path', and rework this function's logic to always return
    paths relative to the prefix path.  (That is, suitable for
    path_join'ing back to that prefix path to get the originals.)

* subversion/tests/libsvn_subr/mergeinfo-test.c
  (struct catalog_bits): New test data structure.
  (remove_prefix_helper, test_remove_prefix_from_catalog): New functions.
  (test_funcs): Add reference to test_remove_prefix_from_catalog().

Modified:
    subversion/trunk/subversion/include/private/svn_mergeinfo_private.h
    subversion/trunk/subversion/libsvn_subr/mergeinfo.c
    subversion/trunk/subversion/tests/libsvn_subr/mergeinfo-test.c

Modified: subversion/trunk/subversion/include/private/svn_mergeinfo_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_mergeinfo_private.h?rev=931190&r1=931189&r2=931190&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_mergeinfo_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_mergeinfo_private.h Tue Apr  6 15:48:58
2010
@@ -85,17 +85,18 @@ svn_boolean_t
 svn_mergeinfo__remove_empty_rangelists(svn_mergeinfo_t mergeinfo,
                                        apr_pool_t *pool);
 
-/* Makes a shallow (ie, mergeinfos are not duped, or altered at all;
-   keys share storage) copy of IN_CATALOG in *OUT_CATALOG.  PREFIX is
-   removed from the beginning of each key in the catalog; it is
-   illegal for any key to not start with PREFIX.  The new hash and
-   temporary values are allocated in POOL.  (This is useful for making
-   the return value from svn_ra_get_mergeinfo relative to the session
-   root, say.) */
+/* Make a shallow (ie, mergeinfos are not duped, or altered at all;
+   keys share storage) copy of IN_CATALOG in *OUT_CATALOG, removing
+   PREFIX_PATH (which is an absolute path) from the beginning of each
+   key in the catalog (each of which is also an absolute path).  It is
+   illegal for any key to not start with PREFIX_PATH.  The new hash
+   and temporary values are allocated in POOL.  (This is useful for
+   making the return value from svn_ra_get_mergeinfo relative to the
+   session root, say.) */
 svn_error_t *
 svn_mergeinfo__remove_prefix_from_catalog(svn_mergeinfo_catalog_t *out_catalog,
                                           svn_mergeinfo_catalog_t in_catalog,
-                                          const char *prefix,
+                                          const char *prefix_path,
                                           apr_pool_t *pool);
 
 /* Makes a deep copy of MERGEINFO in *OUT_MERGEINFO.  If SUFFIX_REL_PATH is

Modified: subversion/trunk/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/mergeinfo.c?rev=931190&r1=931189&r2=931190&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/trunk/subversion/libsvn_subr/mergeinfo.c Tue Apr  6 15:48:58 2010
@@ -1679,11 +1679,13 @@ svn_mergeinfo__remove_empty_rangelists(s
 svn_error_t *
 svn_mergeinfo__remove_prefix_from_catalog(svn_mergeinfo_catalog_t *out_catalog,
                                           svn_mergeinfo_catalog_t in_catalog,
-                                          const char *prefix,
+                                          const char *prefix_path,
                                           apr_pool_t *pool)
 {
   apr_hash_index_t *hi;
-  size_t prefix_len = strlen(prefix);
+  size_t prefix_len = strlen(prefix_path);
+
+  SVN_ERR_ASSERT(prefix_path[0] == '/');
 
   *out_catalog = apr_hash_make(pool);
 
@@ -1692,12 +1694,21 @@ svn_mergeinfo__remove_prefix_from_catalo
       const char *original_path = svn__apr_hash_index_key(hi);
       apr_ssize_t klen = svn__apr_hash_index_klen(hi);
       svn_mergeinfo_t value = svn__apr_hash_index_val(hi);
+      apr_ssize_t padding = 0;
 
       SVN_ERR_ASSERT(klen >= prefix_len);
-      SVN_ERR_ASSERT(strncmp(original_path, prefix, prefix_len) == 0);
+      SVN_ERR_ASSERT(svn_uri_is_ancestor(prefix_path, original_path));
+
+      /* If the ORIGINAL_PATH doesn't match the PREFIX_PATH exactly
+         and we're not simply removing a single leading slash (such as
+         when PREFIX_PATH is "/"), we advance our string offset by an
+         extra character (to get past the directory separator that
+         follows the prefix).  */
+      if ((strcmp(original_path, prefix_path) != 0) && (prefix_len != 1))
+        padding = 1;
 
-      apr_hash_set(*out_catalog, original_path + prefix_len,
-                   klen-prefix_len, value);
+      apr_hash_set(*out_catalog, original_path + prefix_len + padding,
+                   klen - prefix_len - padding, value);
     }
 
   return SVN_NO_ERROR;

Modified: subversion/trunk/subversion/tests/libsvn_subr/mergeinfo-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=931190&r1=931189&r2=931190&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_subr/mergeinfo-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_subr/mergeinfo-test.c Tue Apr  6 15:48:58 2010
@@ -1559,6 +1559,99 @@ test_rangelist_diff(apr_pool_t *pool)
     }
   return err;
 }
+
+
+/* Test data structure for test_remove_prefix_from_catalog(). */
+struct catalog_bits
+{
+  const char *orig_path;
+  const char *new_path;
+  const char *mergeinfo;
+};
+
+
+/* Helper for test_remove_prefix_from_catalog(). */
+static svn_error_t *
+remove_prefix_helper(struct catalog_bits *test_data,
+                     const char *prefix_path,
+                     apr_pool_t *pool)
+{
+  svn_mergeinfo_catalog_t in_catalog, out_catalog, exp_out_catalog;
+  apr_hash_index_t *hi;
+  int i = 0;
+  
+  in_catalog = apr_hash_make(pool);
+  exp_out_catalog = apr_hash_make(pool);
+  while (test_data[i].orig_path)
+    {
+      struct catalog_bits data = test_data[i];
+      const char *orig_path = apr_pstrdup(pool, data.orig_path);
+      const char *new_path = apr_pstrdup(pool, data.new_path);
+      svn_mergeinfo_t mergeinfo;
+      SVN_ERR(svn_mergeinfo_parse(&mergeinfo, data.mergeinfo, pool));
+      apr_hash_set(in_catalog, orig_path, APR_HASH_KEY_STRING, mergeinfo);
+      apr_hash_set(exp_out_catalog, new_path, APR_HASH_KEY_STRING, mergeinfo);
+      i++;
+    }
+  SVN_ERR(svn_mergeinfo__remove_prefix_from_catalog(&out_catalog, in_catalog,
+                                                    prefix_path, pool));
+  if (apr_hash_count(exp_out_catalog) != apr_hash_count(out_catalog))
+    return svn_error_create(SVN_ERR_TEST_FAILED, 0,
+                            "Got unexpected number of catalog entries");
+  for (hi = apr_hash_first(pool, out_catalog); hi; hi = apr_hash_next(hi))
+    {
+      const void *path;
+      apr_ssize_t path_len;
+      void *out_mergeinfo, *exp_out_mergeinfo;
+      apr_hash_this(hi, &path, &path_len, &out_mergeinfo);
+      exp_out_mergeinfo = apr_hash_get(exp_out_catalog, path, path_len);
+      if (! exp_out_mergeinfo)
+        return svn_error_createf(SVN_ERR_TEST_FAILED, 0,
+                                 "Found unexpected key '%s' in catalog",
+                                 (const char *)path);
+      if (exp_out_mergeinfo != out_mergeinfo)
+        return svn_error_create(SVN_ERR_TEST_FAILED, 0,
+                                "Detected value tampering in catalog");
+    }
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_remove_prefix_from_catalog(apr_pool_t *pool)
+{
+  apr_pool_t *subpool = svn_pool_create(pool);
+
+  /* For testing the remove of the prefix "/trunk"  */
+  struct catalog_bits test_data_1[] =
+    {
+      { "/trunk",           "",          "/A:1" },
+      { "/trunk/foo",       "foo",       "/A/foo:1,3*" },
+      { "/trunk/foo/bar",   "foo/bar",   "/A/foo:1-4" },
+      { "/trunk/baz",       "baz",       "/A/baz:2" },
+      { NULL, NULL, NULL }
+    };
+
+  /* For testing the remove of the prefix "/"  */
+  struct catalog_bits test_data_2[] =
+    {
+      { "/",                "",                "/:2" },
+      { "/trunk",           "trunk",           "/A:1" },
+      { "/trunk/foo",       "trunk/foo",       "/A/foo:1,3*" },
+      { "/trunk/foo/bar",   "trunk/foo/bar",   "/A/foo:1-4" },
+      { "/trunk/baz",       "trunk/baz",       "/A/baz:2" },
+      { NULL, NULL, NULL }
+    };
+
+  svn_pool_clear(subpool);
+  SVN_ERR(remove_prefix_helper(test_data_1, "/trunk", subpool));
+
+  svn_pool_clear(subpool);
+  SVN_ERR(remove_prefix_helper(test_data_2, "/", subpool));
+
+  svn_pool_destroy(subpool);
+  return SVN_NO_ERROR;
+}
+
 
 /* The test table.  */
 
@@ -1599,5 +1692,7 @@ struct svn_test_descriptor_t test_funcs[
                    "merge of rangelists"),
     SVN_TEST_PASS2(test_rangelist_diff,
                    "diff of rangelists"),
+    SVN_TEST_PASS2(test_remove_prefix_from_catalog,
+                   "removal of prefix paths from catalog keys"),
     SVN_TEST_NULL
   };



Mime
View raw message