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

PATCH: Issue 1617: 'svn status' segfault

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: 2003-12-06 22:19:06 CET

"svn status .." seg-faults if "." is a WC but ".." is not. The reason is that "svn_path_dirname" or (in this case) "svn_path_split" is assumed to return the parent of a path, and this assumption is false when the path ends in "..".

The attached patch solves this case, but it really doesn't go far enough. There are many other such cases.

My solution is to introduce an alternative to "svn_path_split", called "svn_parent_path_split", which guarantees to return the parent directory rather than just a truncated path string. I would probably also introduce similar alternatives to "svn_path"dirname" and "svn_path_basename". In the long run I think we need to review all uses of these functions and see whether they really want the truncated string or the actual parent.

It may turn out that all callers really want the parent, in which case we can simply modify "svn_path_split" and friends instead of introducing new functions.

Does this patch look like a reasonable fix for this particular bug and a suitable starting point for fixing further cases? I'm not quite sure, because it works by converting a relative path to an absolute one when necessary, and this may not be appropriate in all cases. It at least avoids the intrusion of converting all user paths to absolute which would probably be unacceptably ugly.

An alternative would be to form the parent path by appending ".." but to do a private conversion to absolute in order to retrieve the appropriate base name of the child.

- Julian

Fix a segmentation fault on "svn status .." when "." is a WC but ".." is not.
(Issue #1617.)

* subversion/include/svn_path.h
* subversion/libsvn_subr/path.c
  (svn_path_parent_split): New function.

* subversion/libsvn_client/status.c
  (svn_client_status): Find the correct parent even when the path ends in "..".

Index: subversion/include/svn_path.h
===================================================================
--- subversion/include/svn_path.h (revision 7944)
+++ subversion/include/svn_path.h (working copy)
@@ -155,6 +155,14 @@ void svn_path_split (const char *path,
                      apr_pool_t *pool);
 
 
+/* Get the @a parent_path and @a base_name of @a path, allocated in @a pool.
+ This may involve converting @path to an absolute path. */
+svn_error_t * svn_path_parent_split (const char *path,
+ const char **parent_path,
+ const char **base_name,
+ apr_pool_t *pool);
+
+
 /** Return non-zero iff @a path is empty ("") or represents the current
  * directory -- that is, if prepending it as a component to an existing
  * path would result in no meaningful change.
Index: subversion/libsvn_client/status.c
===================================================================
--- subversion/libsvn_client/status.c (revision 7944)
+++ subversion/libsvn_client/status.c (working copy)
@@ -113,7 +113,7 @@ svn_client_status (svn_revnum_t *result_
   if (entry)
     SVN_ERR (svn_wc_get_actual_target (path, &anchor, &target, pool));
   else if (! update)
- svn_path_split (path, &anchor, &target, pool);
+ SVN_ERR (svn_path_parent_split (path, &anchor, &target, pool));
   else
     return svn_error_createf (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                               "'%s' is not under version control", path);
Index: subversion/libsvn_subr/path.c
===================================================================
--- subversion/libsvn_subr/path.c (revision 7944)
+++ subversion/libsvn_subr/path.c (working copy)
@@ -420,6 +420,24 @@ svn_path_split (const char *path,
 }
 
 
+svn_error_t *
+svn_path_parent_split (const char *path,
+ const char **parent_path,
+ const char **base_name,
+ apr_pool_t *pool)
+{
+ svn_path_split (path, parent_path, base_name, pool);
+ if (strcmp (*base_name, "..") == 0)
+ {
+ const char *abs_path;
+
+ SVN_ERR (svn_path_get_absolute (&abs_path, path, pool));
+ svn_path_split (abs_path, parent_path, base_name, pool);
+ }
+ return SVN_NO_ERROR;
+}
+
+
 int
 svn_path_is_empty (const char *path)
 {

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Dec 6 22:15:10 2003

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.