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 2018/12/15 12:20:58 UTC

svn commit: r1848990 - in /subversion/trunk/subversion: include/svn_dirent_uri.h libsvn_subr/dirent_uri.c

Author: brane
Date: Sat Dec 15 12:20:57 2018
New Revision: 1848990

URL: http://svn.apache.org/viewvc?rev=1848990&view=rev
Log:
Make sure that the "safe" canonicalization functions won't abort.

* subversion/include/svn_dirent_uri.h
  (svn_dirent_canonicalize_safe,
   svn_relpath_canonicalize_safe,
   svn_uri_canonicalize_safe): Update docstrings.

* subversion/libsvn_subr/dirent_uri.c
  (canonicalize): Change signature to return an svn_error_t.
   Remove both assertions and return an error instead.
  (canonicalize_dirent): New private helper function.
  (svn_dirent_canonicalize,
   svn_dirent_canonicalize_safe,
   svn_relpath_canonicalize,
   svn_relpath_canonicalize_safe,
   svn_uri_canonicalize,
   svn_uri_canonicalize_safe): Update implementations.

Modified:
    subversion/trunk/subversion/include/svn_dirent_uri.h
    subversion/trunk/subversion/libsvn_subr/dirent_uri.c

Modified: subversion/trunk/subversion/include/svn_dirent_uri.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_dirent_uri.h?rev=1848990&r1=1848989&r2=1848990&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_dirent_uri.h (original)
+++ subversion/trunk/subversion/include/svn_dirent_uri.h Sat Dec 15 12:20:57 2018
@@ -477,7 +477,7 @@ svn_dirent_canonicalize(const char *dire
                         apr_pool_t *result_pool);
 
 /**
- * Return a new @a *cannonical_dirent like @a dirent, but transformed such
+ * Return a new @a *canonical_dirent like @a dirent, but transformed such
  * that some types of dirent specification redundancies are removed.
  *
  * Similar to svn_dirent_canonicalize() (which see), but returns an error
@@ -485,8 +485,8 @@ svn_dirent_canonicalize(const char *dire
  * the svn_dirent_is_canonical() test.
  *
  * If the function fails and @a non_canonical_result is not @c NULL, the
- * result of the failed canonicalization attempt will be returned in
- * @a *non_canonical_result.
+ * result of the failed canonicalization attempt (which may be @c NULL)
+ * will be returned in @a *non_canonical_result.
  *
  * Allocates the results in @a result_pool. Uses @a scratch_pool for
  * temporary allocations.
@@ -528,8 +528,8 @@ svn_relpath_canonicalize(const char *rel
  * pass the svn_relpath_is_canonical() test.
  *
  * If the function fails and @a non_canonical_result is not @c NULL, the
- * result of the failed canonicalization attempt will be returned in
- * @a *non_canonical_result.
+ * result of the failed canonicalization attempt (which may be @c NULL)
+ * will be returned in @a *non_canonical_result.
  *
  * Allocates the results in @a result_pool. Uses @a scratch_pool for
  * temporary allocations.
@@ -577,8 +577,8 @@ svn_uri_canonicalize(const char *uri,
  * svn_uri_is_canonical() test.
  *
  * If the function fails and @a non_canonical_result is not @c NULL, the
- * result of the failed canonicalization attempt will be returned in
- * @a *non_canonical_result.
+ * result of the failed canonicalization attempt (which may be @c NULL)
+ * will be returned in @a *non_canonical_result.
  *
  * Allocates the results in @a result_pool. Uses @a scratch_pool for
  * temporary allocations.

Modified: subversion/trunk/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/dirent_uri.c?rev=1848990&r1=1848989&r2=1848990&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/trunk/subversion/libsvn_subr/dirent_uri.c Sat Dec 15 12:20:57 2018
@@ -292,8 +292,9 @@ uri_previous_segment(const char *uri,
 /* Return the canonicalized version of PATH, of type TYPE, allocated in
  * POOL.
  */
-static const char *
-canonicalize(path_type_t type, const char *path, apr_pool_t *pool)
+static svn_error_t *
+canonicalize(const char **canonical_path,
+             path_type_t type, const char *path, apr_pool_t *pool)
 {
   char *canon, *dst;
   const char *src;
@@ -307,8 +308,12 @@ canonicalize(path_type_t type, const cha
      depends on path not being zero-length.  */
   if (SVN_PATH_IS_EMPTY(path))
     {
-      assert(type != type_uri);
-      return "";
+      *canonical_path = "";
+      if (type == type_uri)
+        return svn_error_create(SVN_ERR_CANONICALIZATION_FAILED, NULL,
+                                _("An empty URI can not be canonicalized"));
+      else
+        return SVN_NO_ERROR;
     }
 
   dst = canon = apr_pcalloc(pool, strlen(path) + 1);
@@ -319,7 +324,12 @@ canonicalize(path_type_t type, const cha
   src = path;
   if (type == type_uri)
     {
-      assert(*src != '/');
+      if (*src == '/')
+        {
+          *canonical_path = src;
+          return svn_error_create(SVN_ERR_CANONICALIZATION_FAILED, NULL,
+                                  _("A URI can not start with '/'"));
+        }
 
       while (*src && (*src != '/') && (*src != ':'))
         src++;
@@ -546,7 +556,10 @@ canonicalize(path_type_t type, const cha
   if ((type == type_dirent) && canon[0] == '/' && canon[1] == '/')
     {
       if (canon_segments < 2)
-        return canon + 1;
+        {
+          *canonical_path = canon + 1;
+          return SVN_NO_ERROR;
+        }
       else
         {
           /* Now we're sure this is a valid UNC path, convert the server name
@@ -654,7 +667,8 @@ canonicalize(path_type_t type, const cha
       *dst = '\0';
     }
 
-  return canon;
+  *canonical_path = canon;
+  return SVN_NO_ERROR;
 }
 
 /* Return the string length of the longest common ancestor of PATH1 and PATH2.
@@ -1643,7 +1657,11 @@ svn_dirent_get_absolute(const char **pab
 const char *
 svn_uri_canonicalize(const char *uri, apr_pool_t *pool)
 {
-  return canonicalize(type_uri, uri, pool);
+  const char *result;
+  svn_error_t *const err = canonicalize(&result, type_uri, uri, pool);
+  svn_error_clear(err);
+  SVN_ERR_ASSERT_NO_RETURN(!err);
+  return result;
 }
 
 svn_error_t *
@@ -1653,7 +1671,8 @@ svn_uri_canonicalize_safe(const char **c
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
-  const char *const result = svn_uri_canonicalize(uri, result_pool);
+  const char *result = NULL;
+  SVN_ERR(canonicalize(&result, type_uri, uri, result_pool));
   if (!svn_uri_is_canonical(result, scratch_pool))
     {
       if (non_canonical_result)
@@ -1672,7 +1691,11 @@ svn_uri_canonicalize_safe(const char **c
 const char *
 svn_relpath_canonicalize(const char *relpath, apr_pool_t *pool)
 {
-  return canonicalize(type_relpath, relpath, pool);
+  const char *result;
+  svn_error_t *const err = canonicalize(&result, type_relpath, relpath, pool);
+  svn_error_clear(err);
+  SVN_ERR_ASSERT_NO_RETURN(!err);
+  return result;
 }
 
 svn_error_t *
@@ -1682,7 +1705,8 @@ svn_relpath_canonicalize_safe(const char
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
 {
-  const char *const result = svn_relpath_canonicalize(relpath, result_pool);
+  const char *result = NULL;
+  SVN_ERR(canonicalize(&result, type_relpath, relpath, result_pool));
   if (!svn_relpath_is_canonical(result))
     {
       if (non_canonical_result)
@@ -1700,10 +1724,11 @@ svn_relpath_canonicalize_safe(const char
   return SVN_NO_ERROR;
 }
 
-const char *
-svn_dirent_canonicalize(const char *dirent, apr_pool_t *pool)
+static svn_error_t *
+canonicalize_dirent(const char **result, const char *dirent, apr_pool_t *pool)
 {
-  const char *dst = canonicalize(type_dirent, dirent, pool);
+  const char *dst;
+  SVN_ERR(canonicalize(&dst, type_dirent, dirent, pool));
 
 #ifdef SVN_USE_DOS_PATHS
   /* Handle a specific case on Windows where path == "X:/". Here we have to
@@ -1719,11 +1744,23 @@ svn_dirent_canonicalize(const char *dire
       dst_slash[2] = '/';
       dst_slash[3] = '\0';
 
-      return dst_slash;
+      *result = dst_slash;
+      return SVN_NO_ERROR;
     }
 #endif /* SVN_USE_DOS_PATHS */
 
-  return dst;
+  *result = dst;
+  return SVN_NO_ERROR;
+}
+
+const char *
+svn_dirent_canonicalize(const char *dirent, apr_pool_t *pool)
+{
+  const char *result;
+  svn_error_t *const err = canonicalize_dirent(&result, dirent, pool);
+  svn_error_clear(err);
+  SVN_ERR_ASSERT_NO_RETURN(!err);
+  return result;
 }
 
 svn_error_t *
@@ -1733,7 +1770,8 @@ svn_dirent_canonicalize_safe(const char
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool)
 {
-  const char *const result = svn_dirent_canonicalize(dirent, result_pool);
+  const char *result = NULL;
+  SVN_ERR(canonicalize_dirent(&result, dirent, result_pool));
   if (!svn_dirent_is_canonical(result, scratch_pool))
     {
       if (non_canonical_result)