You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2012/11/23 22:57:41 UTC

svn commit: r1413083 - in /subversion/trunk/subversion: svn/cl.h svn/props.c tests/cmdline/prop_tests.py

Author: brane
Date: Fri Nov 23 21:57:40 2012
New Revision: 1413083

URL: http://svn.apache.org/viewvc?rev=1413083&view=rev
Log:
Further constrain when we require --force to set a property whose name
does not start with svn:

* subversion/svn/cl.h (svn_cl__check_svn_prop_name): Document exactly how
   we match property names.
* subversion/svn/props.c: Get rid of all qsort_r cruft.
  (svn_cl__check_svn_prop_name): Implement stricter matching rules.

* subversion/tests/cmdline/prop_tests.py (almost_known_prop_names): Add cases
   that cover the stricter matching rules.

Modified:
    subversion/trunk/subversion/svn/cl.h
    subversion/trunk/subversion/svn/props.c
    subversion/trunk/subversion/tests/cmdline/prop_tests.py

Modified: subversion/trunk/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1413083&r1=1413082&r2=1413083&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Fri Nov 23 21:57:40 2012
@@ -768,7 +768,12 @@ svn_cl__operation_str_human_readable(svn
                                      apr_pool_t *pool);
 
 /* If PROPNAME looks like but is not identical to one of the svn:
- * poperties, raise an error and suggest a better spelling.
+ * poperties, raise an error and suggest a better spelling. Names that
+ * raise errors look like this:
+ *
+ *   - start with svn: but do not exactly match a known property; or,
+ *   - start with a 3-letter prefix that differs in only one letter
+ *     from "svn:", and the rest exactly matches a known propery.
  *
  * If REVPROP is TRUE, only check revision property names; otherwise
  * only check node property names.

Modified: subversion/trunk/subversion/svn/props.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/props.c?rev=1413083&r1=1413082&r2=1413083&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/props.c (original)
+++ subversion/trunk/subversion/svn/props.c Fri Nov 23 21:57:40 2012
@@ -239,9 +239,7 @@ struct simprop_t
   svn_string_t name;      /* svn: property name */
   unsigned int score;     /* the similarity score */
   apr_size_t diff;        /* number of chars different from context.name */
-#ifndef HAVE_QSORT_R
   struct simprop_context_t *context; /* sorting context for qsort() */
-#endif
 };
 
 /* Similarity test between two property names */
@@ -258,22 +256,13 @@ simprop_key_diff(const svn_string_t *key
   return score;
 }
 
-/* Key comparator for qsort or qsort_r for simprop_t */
-#ifdef HAVE_QSORT_R
-static int
-simprop_compare(void *pcontext, const void *pkeya, const void *pkeyb)
-#else
+/* Key comparator for qsort for simprop_t */
 static int
 simprop_compare(const void *pkeya, const void *pkeyb)
-#endif
 {
   struct simprop_t *const keya = *(struct simprop_t *const *)pkeya;
   struct simprop_t *const keyb = *(struct simprop_t *const *)pkeyb;
-#ifdef HAVE_QSORT_R
-  struct simprop_context_t *const context = pcontext;
-#else
   struct simprop_context_t *const context = keya->context;
-#endif
 
   if (keya->score == -1)
     keya->score = simprop_key_diff(&keya->name, &context->name,
@@ -296,15 +285,19 @@ svn_cl__check_svn_prop_name(const char *
     {
       SVN_PROP_NODE_ALL_PROPS
     };
+  static const apr_size_t nodeprops_len = sizeof(nodeprops)/sizeof(*nodeprops);
+
   static const char *const revprops[] =
     {
       SVN_PROP_REVISION_ALL_PROPS
     };
+  static const apr_size_t revprops_len = sizeof(revprops)/sizeof(*revprops);
+
+  const char *const *const proplist = (revprop ? revprops : nodeprops);
+  const apr_size_t numprops = (revprop ? revprops_len : nodeprops_len);
 
   struct simprop_t **propkeys;
   struct simprop_t *propbuf;
-  const char *const *proplist;
-  apr_size_t numprops;
   apr_size_t i;
 
   struct simprop_context_t context;
@@ -332,21 +325,26 @@ svn_cl__check_svn_prop_name(const char *
       context.name.len = name_len; /* Restore the original propname length */
       if (lcs < prefix.len - 1)
         return SVN_NO_ERROR;    /* Wrong prefix, ignore */
+
+      /* If the prefix is slightly different, the rest must be
+         identical in order to trigger the error. */
+      if (lcs == prefix.len - 1)
+        {
+          for (i = 0; i < numprops; ++i)
+            {
+              if (0 == strcmp(proplist[i] + prefix.len, propname + prefix.len))
+                return svn_error_createf(
+                  SVN_ERR_CLIENT_PROPERTY_NAME, NULL,
+                  _("'%s' is not a valid %s property name; did you mean '%s'?"
+                    "\n(To set the '%s' property, re-run with '--force'.)"),
+                  propname, SVN_PROP_PREFIX, proplist[i], propname);
+            }
+          return SVN_NO_ERROR;
+        }
     }
 
   /* Now find the closest match from amongst a the set of reserved
      node or revision property names. */
-  if (revprop)
-    {
-      proplist = revprops;
-      numprops = sizeof(revprops) / sizeof(*revprops);
-    }
-  else
-    {
-      proplist = nodeprops;
-      numprops = sizeof(nodeprops) / sizeof(*nodeprops);
-    }
-
   propkeys = apr_palloc(scratch_pool,
                         numprops * sizeof(struct simprop_t*));
   propbuf = apr_palloc(scratch_pool,
@@ -357,13 +355,10 @@ svn_cl__check_svn_prop_name(const char *
       propbuf[i].name.data = proplist[i];
       propbuf[i].name.len = strlen(proplist[i]);
       propbuf[i].score = (unsigned int)-1;
-#ifndef HAVE_QSORT_R
       propbuf[i].context = &context;
-#endif
     }
 
-  SVN_QSORT_R(propkeys, numprops, sizeof(*propkeys),
-              simprop_compare, &context);
+  qsort(propkeys, numprops, sizeof(*propkeys), simprop_compare);
 
   if (0 == propkeys[0]->diff)
     return SVN_NO_ERROR;        /* We found an exact match. */

Modified: subversion/trunk/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/prop_tests.py?rev=1413083&r1=1413082&r2=1413083&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/prop_tests.py Fri Nov 23 21:57:40 2012
@@ -2677,12 +2677,23 @@ def almost_known_prop_names(sbox):
   wc_dir = sbox.wc_dir
   iota_path = sbox.ospath('iota')
 
-  # Node properties
+  # Same prefix, different prop name
   svntest.actions.set_prop('svn:exemutable', 'x', iota_path,
                            "svn: E195011: 'svn:exemutable' "
                            "is not a valid svn: property name")
   svntest.actions.set_prop('svn:exemutable', 'x', iota_path, force=True)
-  svntest.actions.set_prop('tsvn:exemutable', 'x', iota_path)
+
+  # Similar prefix, different prop name
+  svntest.actions.set_prop('svm:exemutable', 'x', iota_path)
+
+  # Similar prefix, same prop name
+  svntest.actions.set_prop('svm:executable', 'x', iota_path,
+                           "svn: E195011: 'svm:executable' "
+                           "is not a valid svn: property name")
+  svntest.actions.set_prop('svm:executable', 'x', iota_path, force=True)
+
+  # Different prefix, same prop name
+  svntest.actions.set_prop('tsvn:executable', 'x', iota_path)
 
 ########################################################################
 # Run the tests