summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/repos.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/repos.c')
-rw-r--r--contrib/cvs/src/repos.c60
1 files changed, 56 insertions, 4 deletions
diff --git a/contrib/cvs/src/repos.c b/contrib/cvs/src/repos.c
index 2590df5..2738665 100644
--- a/contrib/cvs/src/repos.c
+++ b/contrib/cvs/src/repos.c
@@ -3,9 +3,10 @@
* Copyright (c) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
+ * specified in the README file that comes with the CVS source distribution.
*/
+#include <assert.h>
#include "cvs.h"
#include "getline.h"
@@ -86,7 +87,6 @@ Name_Repository (dir, update_dir)
error (1, save_errno, "cannot open %s", tmp);
}
- free (tmp);
if (getline (&repos, &repos_allocated, fpin) < 0)
{
@@ -94,7 +94,10 @@ Name_Repository (dir, update_dir)
error (0, 0, "in directory %s:", xupdate_dir);
error (1, errno, "cannot read %s", CVSADM_REP);
}
- (void) fclose (fpin);
+ if (fclose (fpin) < 0)
+ error (0, errno, "cannot close %s", tmp);
+ free (tmp);
+
if ((cp = strrchr (repos, '\n')) != NULL)
*cp = '\0'; /* strip the newline */
@@ -126,7 +129,8 @@ Name_Repository (dir, update_dir)
repos = newrepos;
}
- strip_trailing_slashes (repos);
+ Sanitize_Repository_Name (repos);
+
return repos;
}
@@ -152,3 +156,51 @@ Short_Repository (repository)
else
return (repository);
}
+
+/* Sanitize the repository name (in place) by removing trailing
+ * slashes and a trailing "." if present. It should be safe for
+ * callers to use strcat and friends to create repository names.
+ * Without this check, names like "/path/to/repos/./foo" and
+ * "/path/to/repos//foo" would be created. For example, one
+ * significant case is the CVSROOT-detection code in commit.c. It
+ * decides whether or not it needs to rebuild the administrative file
+ * database by doing a string compare. If we've done a `cvs co .' to
+ * get the CVSROOT files, "/path/to/repos/./CVSROOT" and
+ * "/path/to/repos/CVSROOT" are the arguments that are compared!
+ *
+ * This function ends up being called from the same places as
+ * strip_path, though what it does is much more conservative. Many
+ * comments about this operation (which was scattered around in
+ * several places in the source code) ran thus:
+ *
+ * ``repository ends with "/."; omit it. This sort of thing used
+ * to be taken care of by strip_path. Now we try to be more
+ * selective. I suspect that it would be even better to push it
+ * back further someday, so that the trailing "/." doesn't get into
+ * repository in the first place, but we haven't taken things that
+ * far yet.'' --Jim Kingdon (recurse.c, 07-Sep-97)
+ *
+ * Ahh, all too true. The major consideration is RELATIVE_REPOS. If
+ * the "/." doesn't end up in the repository while RELATIVE_REPOS is
+ * defined, there will be nothing in the CVS/Repository file. I
+ * haven't verified that the remote protocol will handle that
+ * correctly yet, so I've not made that change. */
+
+void
+Sanitize_Repository_Name (repository)
+ char *repository;
+{
+ size_t len;
+
+ assert (repository != NULL);
+
+ strip_trailing_slashes (repository);
+
+ len = strlen (repository);
+ if (len >= 2
+ && repository[len - 1] == '.'
+ && ISDIRSEP (repository[len - 2]))
+ {
+ repository[len - 2] = '\0';
+ }
+}
OpenPOWER on IntegriCloud