[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] svn: enforce exact version match

From: Daniel Shahaf <danielsh_at_elego.de>
Date: Thu, 11 Jul 2013 02:22:10 +0300

We decided a while ago that the cmdline client and all C libraries must
be upgraded in lockstep.[1] However, a Subversion 1.7.10 client out
there happily uses 1.7.9 libraries that happened to be lying in the
runtime linker's search path.

The enclosed patch fixes that to require exact version match in svn and
in libraries that have an svn_ver_check_list() call. (Some libraries
have that, and some don't; I haven't looked into the reason for that.)

Thoughts?

(I'll add svnadmin, svnserve, etc to the patch before commit.)

Daniel

[[[
* subversion/include/svn_version.h
  (svn_ver_check_list): Deprecate.
  (svn_ver_check_list2): New.

* subversion/svn/svn.c
  (check_lib_versions): Require libraries to be the exact same version,
    not merely a compatible one.
]]]

Index: subversion/include/svn_version.h
===================================================================
--- subversion/include/svn_version.h (revision 1502047)
+++ subversion/include/svn_version.h (working copy)
@@ -95,7 +95,7 @@ extern "C" {
  *
  * Always change this at the same time as SVN_VER_NUMTAG.
  */
-#define SVN_VER_TAG " (under development)"
+#define SVN_VER_TAG " (foobar)"
 
 
 /** Number tag: a string describing the version.
@@ -110,7 +110,7 @@ extern "C" {
  *
  * Always change this at the same time as SVN_VER_TAG.
  */
-#define SVN_VER_NUMTAG "-dev"
+#define SVN_VER_NUMTAG "-foobar"
 
 
 /** Revision number: The repository revision number of this release.
@@ -192,6 +192,8 @@ struct svn_version_t
  * unreleased library. A development client is always compatible with
  * a previous released library.
  *
+ * @note Implements the #svn_ver_check_list2.@a comparator interface.
+ *
  * @since New in 1.1.
  */
 svn_boolean_t
@@ -201,6 +203,8 @@ svn_ver_compatible(const svn_version_t *my_version
 /**
  * Check if @a my_version and @a lib_version encode the same version number.
  *
+ * @note Implements the #svn_ver_check_list2.@a comparator interface.
+ *
  * @since New in 1.2.
  */
 svn_boolean_t
@@ -228,11 +232,27 @@ typedef struct svn_version_checklist_t
  * my_version is compatible with each entry in @a checklist. @a
  * checklist must end with an entry whose label is @c NULL.
  *
- * @see svn_ver_compatible()
+ * @a my_version is considered to be compatible with a version in @a checklist
+ * if @a comparator returns #TRUE when called with @a my_version as the first
+ * parammeter and the @a checklist version as the second parameter.
  *
- * @since New in 1.1.
+ * @see svn_ver_compatible(), svn_ver_equal()
+ *
+ * @since New in 1.9.
  */
 svn_error_t *
+svn_ver_check_list2(const svn_version_t *my_version,
+ const svn_version_checklist_t *checklist,
+ svn_boolean_t (*comparator)(const svn_version_t *,
+ const svn_version_t *));
+
+/** Similar to svn_ver_check_list2(), with @a comparator set to
+ * #svn_ver_compatible.
+ *
+ * @deprecated Provided for backward compatibility with 1.8 API.
+ */
+SVN_DEPRECATED
+svn_error_t *
 svn_ver_check_list(const svn_version_t *my_version,
                    const svn_version_checklist_t *checklist);
 
Index: subversion/libsvn_subr/deprecated.c
===================================================================
--- subversion/libsvn_subr/deprecated.c (revision 1502047)
+++ subversion/libsvn_subr/deprecated.c (working copy)
@@ -1301,4 +1301,10 @@ svn_subst_build_keywords(svn_subst_keywords_t *kw,
   return SVN_NO_ERROR;
 }
 
-
+/*** From version.c ***/
+svn_error_t *
+svn_ver_check_list(const svn_version_t *my_version,
+ const svn_version_checklist_t *checklist)
+{
+ return svn_ver_check_list2(my_version, checklist, svn_ver_compatible);
+}
Index: subversion/libsvn_subr/version.c
===================================================================
--- subversion/libsvn_subr/version.c (revision 1502047)
+++ subversion/libsvn_subr/version.c (working copy)
@@ -75,8 +75,10 @@ svn_boolean_t svn_ver_equal(const svn_version_t *m
 
 
 svn_error_t *
-svn_ver_check_list(const svn_version_t *my_version,
- const svn_version_checklist_t *checklist)
+svn_ver_check_list2(const svn_version_t *my_version,
+ const svn_version_checklist_t *checklist,
+ svn_boolean_t (*comparator)(const svn_version_t *,
+ const svn_version_t *))
 {
   svn_error_t *err = SVN_NO_ERROR;
   int i;
@@ -84,12 +86,17 @@ svn_error_t *
   for (i = 0; checklist[i].label != NULL; ++i)
     {
       const svn_version_t *lib_version = checklist[i].version_query();
- if (!svn_ver_compatible(my_version, lib_version))
+ if (!comparator(my_version, lib_version))
         err = svn_error_createf(SVN_ERR_VERSION_MISMATCH, err,
- _("Version mismatch in '%s':"
+ _("Version mismatch in '%s'%s:"
                                   " found %d.%d.%d%s,"
                                   " expected %d.%d.%d%s"),
                                 checklist[i].label,
+ comparator == svn_ver_equal
+ ? _(" (expecting equality)")
+ : comparator == svn_ver_compatible
+ ? _(" (expecting compatibility)")
+ : "",
                                 lib_version->major, lib_version->minor,
                                 lib_version->patch, lib_version->tag,
                                 my_version->major, my_version->minor,
Index: subversion/svn/svn.c
===================================================================
--- subversion/svn/svn.c (revision 1502047)
+++ subversion/svn/svn.c (working copy)
@@ -1658,7 +1658,11 @@ check_lib_versions(void)
     };
   SVN_VERSION_DEFINE(my_version);
 
- return svn_ver_check_list(&my_version, checklist);
+ /* Use svn_ver_equal() since the cmdline tools sometimes use non-public APIs
+ (such as utility functions that haven't been promoted to svn_cmdline.h).
+ If you copy this code to a third-party tool written against our APIs,
+ consider using svn_ver_compatible() instead. */
+ return svn_ver_check_list2(&my_version, checklist, svn_ver_equal);
 }
 
 
Index: subversion/libsvn_fs_fs/fs.c
===================================================================
--- subversion/libsvn_fs_fs/fs.c (revision 1502047)
+++ subversion/libsvn_fs_fs/fs.c (working copy)
@@ -484,7 +484,8 @@ svn_fs_fs__init(const svn_version_t *loader_versio
     return svn_error_createf(SVN_ERR_VERSION_MISMATCH, NULL,
                              _("Unsupported FS loader version (%d) for fsfs"),
                              loader_version->major);
- SVN_ERR(svn_ver_check_list(fs_version(), checklist));
+ /* Interlibrary dependencies require an exact match. */
+ SVN_ERR(svn_ver_check_list2(fs_version(), checklist, svn_ver_equal));
 
   *vtable = &library_vtable;
   return SVN_NO_ERROR;
Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c (revision 1502047)
+++ subversion/libsvn_ra_svn/client.c (working copy)
@@ -2730,7 +2730,8 @@ svn_ra_svn__init(const svn_version_t *loader_versi
       { NULL, NULL }
     };
 
- SVN_ERR(svn_ver_check_list(svn_ra_svn_version(), checklist));
+ /* Interlibrary dependencies require an exact match. */
+ SVN_ERR(svn_ver_check_list2(svn_ra_svn_version(), checklist, svn_ver_equal));
 
   /* Simplified version check to make sure we can safely use the
      VTABLE parameter. The RA loader does a more exhaustive check. */

[1] I am not sure that was the right decision, but anyway, that's what
we decided.
Received on 2013-07-11 01:23:02 CEST

This is an archived mail posted to the Subversion Dev mailing list.