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

[PATCH v2] Issue #2748: non-UTF-8 filenames in the repository

From: Daniel Shahaf <d.s_at_daniel.shahaf.name>
Date: Wed, 17 Sep 2008 22:14:07 +0300 (Jerusalem Daylight Time)

Daniel Shahaf wrote on Wed, 17 Sep 2008 at 15:42 +0300:
> Patch for issue #2748 ("clients can create non UTF-8 filenames in the
> repository").

New iteration. It moves the logic to libsvn_fs and doesn't touch
svn_path_check_valid(). No tests included this time (but I could write
one if the rest looks good).

Daniel

[[[
Enforce the requirement that paths added to the filesystem must be in UTF-8.
This fixes issue #2748.

* subversion/libsvn_fs/fs-loader.c
  (svn_utf_private.h): Include.
  (path_valid): New helper.
  (svn_fs_make_dir, svn_fs_make_file, svn_fs_copy):
    Call path_valid() instead of svn_path_check_valid().

* subversion/include/svn_path.h,
  subversion/libsvn_subr/path.c
  (svn_path_is_dotpath_present):
    New, similar to svn_path_is_backpath_present().

* subversion/include/svn_path.h
  (svn_path_check_valid):
    Clarify that this function is unrelated to the FS layer's concept of
    validty.

* subversion/libsvn_subr/utf_impl.h
  (svn_utf__cstring_is_valid): Move the declaration ...

* subversion/include/private/svn_utf_private.h
  (svn_utf__cstring_is_valid): ... here.
]]]

Index: subversion/libsvn_fs/fs-loader.c
===================================================================
--- subversion/libsvn_fs/fs-loader.c (revision 33124)
+++ subversion/libsvn_fs/fs-loader.c (working copy)
@@ -34,6 +34,8 @@
 #include "svn_md5.h"
 #include "svn_private_config.h"
 
+#include "private/svn_utf_private.h"
+
 #include "fs-loader.h"
 
 /* This is defined by configure on platforms which use configure, but
@@ -324,6 +326,28 @@ default_warning_func(void *baton, svn_error_t *err
   abort();
 }
 
+static svn_error_t *
+path_valid(const char *path, apr_pool_t *pool)
+{
+ /* UTF-8 encoded string without NULs. */
+ if (! svn_utf__cstring_is_valid(path))
+ {
+ return svn_error_createf(SVN_ERR_FS_PATH_SYNTAX, NULL,
+ _("Path '%s' is not in UTF-8"), path);
+ }
+
+ /* No "." or ".." elements. */
+ if (svn_path_is_backpath_present(path)
+ || svn_path_is_dotpath_present(path))
+ {
+ return svn_error_createf(SVN_ERR_FS_PATH_SYNTAX, NULL,
+ _("Path '%s' contains '.' or '..' element"));
+ }
+
+ /* That's good enough. */
+ return SVN_NO_ERROR;
+}
+
 /* This API is publicly deprecated, but we continue to use it
    internally to properly allocate svn_fs_t structures. */
 svn_fs_t *
@@ -866,7 +890,7 @@ svn_fs_dir_entries(apr_hash_t **entries_p, svn_fs_
 svn_error_t *
 svn_fs_make_dir(svn_fs_root_t *root, const char *path, apr_pool_t *pool)
 {
- SVN_ERR(svn_path_check_valid(path, pool));
+ SVN_ERR(path_valid(path, pool));
   return root->vtable->make_dir(root, path, pool);
 }
 
@@ -880,7 +904,7 @@ svn_error_t *
 svn_fs_copy(svn_fs_root_t *from_root, const char *from_path,
             svn_fs_root_t *to_root, const char *to_path, apr_pool_t *pool)
 {
- SVN_ERR(svn_path_check_valid(to_path, pool));
+ SVN_ERR(path_valid(to_path, pool));
   return to_root->vtable->copy(from_root, from_path, to_root, to_path, pool);
 }
 
@@ -950,7 +974,7 @@ svn_fs_file_contents(svn_stream_t **contents, svn_
 svn_error_t *
 svn_fs_make_file(svn_fs_root_t *root, const char *path, apr_pool_t *pool)
 {
- SVN_ERR(svn_path_check_valid(path, pool));
+ SVN_ERR(path_valid(path, pool));
   return root->vtable->make_file(root, path, pool);
 }
 
Index: subversion/libsvn_subr/utf_impl.h
===================================================================
--- subversion/libsvn_subr/utf_impl.h (revision 33124)
+++ subversion/libsvn_subr/utf_impl.h (working copy)
@@ -50,9 +50,6 @@ const char *svn_utf__cstring_from_utf8_fuzzy(const
  */
 const char *svn_utf__last_valid(const char *src, apr_size_t len);
 
-/* As for svn_utf__is_valid but SRC is NULL terminated. */
-svn_boolean_t svn_utf__cstring_is_valid(const char *src);
-
 /* As for svn_utf__last_valid but uses a different implementation without
    lookup tables. It avoids the table memory use (about 400 bytes) but the
    function is longer (about 200 bytes extra) and likely to be slower when
Index: subversion/libsvn_subr/path.c
===================================================================
--- subversion/libsvn_subr/path.c (revision 33124)
+++ subversion/libsvn_subr/path.c (working copy)
@@ -842,6 +842,26 @@ svn_path_is_single_path_component(const char *name
 
 
 svn_boolean_t
+svn_path_is_dotpath_present(const char *path)
+{
+ int len = strlen(path);
+
+ if (! strcmp(path, "."))
+ return TRUE;
+
+ if (! strncmp(path, "./", 2))
+ return TRUE;
+
+ if (strstr(path, "/./") != NULL)
+ return TRUE;
+
+ if (path[len - 2] == '/' && path[len - 1] == '.')
+ return TRUE;
+
+ return FALSE;
+}
+
+svn_boolean_t
 svn_path_is_backpath_present(const char *path)
 {
   int len = strlen(path);
Index: subversion/include/svn_path.h
===================================================================
--- subversion/include/svn_path.h (revision 33124)
+++ subversion/include/svn_path.h (working copy)
@@ -396,6 +396,16 @@ svn_boolean_t svn_path_is_single_path_component(co
 svn_boolean_t svn_path_is_backpath_present(const char *path);
 
 
+/**
+ * Test to see if a dotpath, i.e. '.', is present in @a path.
+ * If not, return @c FALSE.
+ * If so, return @c TRUE.
+ *
+ * @since New in 1.6.
+ */
+svn_boolean_t svn_path_is_dotpath_present(const char *path);
+
+
 /** Test if @a path2 is a child of @a path1.
  * If not, return @c NULL.
  * If so, return a copy of the remainder path, allocated in @a pool.
@@ -443,6 +453,9 @@ svn_path_is_ancestor(const char *path1, const char
  * Return @c SVN_NO_ERROR if valid and @c SVN_ERR_FS_PATH_SYNTAX if
  * invalid.
  *
+ * @note Despite returning an @c SVN_ERR_FS_* error, this function has
+ * nothing to do with the versioned filesystem's concept of validity.
+ *
  * @since New in 1.2.
  */
 svn_error_t *svn_path_check_valid(const char *path, apr_pool_t *pool);
Index: subversion/include/private/svn_utf_private.h
===================================================================
--- subversion/include/private/svn_utf_private.h (revision 33124)
+++ subversion/include/private/svn_utf_private.h (working copy)
@@ -34,7 +34,10 @@ extern "C" {
 svn_boolean_t
 svn_utf__is_valid(const char *src, apr_size_t len);
 
+/* As for svn_utf__is_valid but SRC is NULL terminated. */
+svn_boolean_t svn_utf__cstring_is_valid(const char *src);
 
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-09-17 21:14:30 CEST

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.