summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2004-06-10 19:05:38 +0000
committerpeter <peter@FreeBSD.org>2004-06-10 19:05:38 +0000
commit8416bda1d23bda4666a5b880a9d78eccaa640036 (patch)
tree7d97944b58f1e30ab542f9c3d6720b69314cec4d /contrib/cvs/src
parent3d101ef985844544d089e129157a94a0640fd246 (diff)
downloadFreeBSD-src-8416bda1d23bda4666a5b880a9d78eccaa640036.zip
FreeBSD-src-8416bda1d23bda4666a5b880a9d78eccaa640036.tar.gz
Import cvs-1.11.17 onto vendor branch.
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r--contrib/cvs/src/ChangeLog108
-rw-r--r--contrib/cvs/src/add.c24
-rw-r--r--contrib/cvs/src/client.c2
-rw-r--r--contrib/cvs/src/commit.c125
-rw-r--r--contrib/cvs/src/cvs.h5
-rw-r--r--contrib/cvs/src/filesubr.c8
-rw-r--r--contrib/cvs/src/history.c33
-rw-r--r--contrib/cvs/src/ignore.c4
-rw-r--r--contrib/cvs/src/log.c6
-rwxr-xr-xcontrib/cvs/src/sanity.sh134
-rw-r--r--contrib/cvs/src/server.c76
-rw-r--r--contrib/cvs/src/subr.c41
-rw-r--r--contrib/cvs/src/update.c50
-rw-r--r--contrib/cvs/src/vers_ts.c2
-rw-r--r--contrib/cvs/src/wrapper.c34
15 files changed, 522 insertions, 130 deletions
diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog
index f7e9470..87caf76 100644
--- a/contrib/cvs/src/ChangeLog
+++ b/contrib/cvs/src/ChangeLog
@@ -1,3 +1,111 @@
+2004-06-09 Derek Price <derek@ximbiot.com>
+
+ * commit.c, filesubr.c, history.c, server.c, wrapper.c: Various
+ security fixes.
+ (Original patch from Stefan Essler <s.esser@e-matters.de> & Sebastian
+ Krahmer <krahmer@suse.de>.)
+
+ * cvs.h: Include xsize.h.
+
+2004-06-09 Derek Price <derek@ximbiot.com>
+
+ * server.c (serve_entry, serve_is_modified, serve_unchanged): Protect
+ against malformed entries.
+ * sanity.sh (server): Tests for same.
+
+2004-06-07 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * sanity.sh (basica): More tests for string-based revision inc.
+
+2004-06-04 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * subr.c (increment_revnum): Rewrite ala RCS to work directly on
+ the string rather than converting to int to avoid overflow.
+ * sanity.sh (basica): New tests for above, update others to match.
+
+2004-05-19 Derek Price <derek@ximbiot.com>
+
+ * server.c (serve_unchanged, serve_is_modified): Overwrite existing
+ data in timefields. Fixes CAN-2004-0396.
+
+2004-05-14 Derek Price <derek@ximbiot.com>
+
+ * subr.c (file_has_conflict), vers_ts.c (time_stamp_server): Don't
+ require '=' to be the only character here, as this is potentially
+ destabilizing.
+
+2004-05-14 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (trailingslashes): During cleanup remove topfile,v to
+ avoid problems in later tests (editor-1).
+
+2004-05-13 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (trailingslashes): Note TODO item #205 in the comment.
+
+2004-05-13 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (trailingslashes): New tests to expose a bug in CVS when
+ paths are specified with trailing slashes. This relates to TODO #205.
+
+2004-05-12 Derek Price <derek@ximbiot.com>
+
+ * subr.c (file_has_conflict), vers_ts.c (time_stamp_server): Only
+ special case "=" when it is the only character in a timestamp field.
+ Gratuitous reformatting.
+ * vers_ts.c (time_stamp_server): Check for NULL in a consistent manner.
+ Gratuitous reformatting.
+
+2004-05-10 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (top-level): Rename to...
+ (rstar-toplevel): ...this for clarity.
+
+2004-05-10 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (dirs2-10ar): Remove unnecessary empty argument.
+
+2004-05-02 Larry Jones <lawrence.jones@ugsplm.com>
+
+ * log.c (log_expand_revlist): Suppress warnings if really_quiet.
+
+2004-05-07 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (basica): Remove unnecessary empty arguments.
+
+2004-05-07 Derek Price <derek@ximbiot.com>
+
+ * cvs.h (fopen_case): Remove obsolescent prototype.
+
+2004-05-05 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Wait a second and retry if cvs-serv* directories are
+ discovered to avoid race conditions on some systems.
+ (Patch from Pavel Roskin <proski@gnu.org>.)
+
+2004-05-05 Derek Price <derek@ximbiot.com>
+
+ * commit.c: Some gratuitous reformatting.
+
+2004-05-04 Derek Price <derek@ximbiot.com>
+
+ * update.c: Some gratuitous reformatting.
+
+2004-05-04 Derek Price <derek@ximbiot.com>
+
+ * add.c (add): Remove obsolete FIXME comment.
+ (*): Some gratuitous reformatting.
+
+2004-04-26 Derek Price <derek@ximbiot.com>
+
+ * client.c (start_rsh_server): Don't rely on GNU argument processing
+ capabilities in the RSH command.
+ (Report from Mark Andrews <Mark_Andrews@isc.org>.)
+
+2004-04-19 Derek Price <derek@ximbiot.com>
+
+ * ignore.c: Gratuitous reformatting.
+
2004-04-11 Derek Price <derek@ximbiot.com>
* client.c (call_in_directory): Check paths the server sends us to make
diff --git a/contrib/cvs/src/add.c b/contrib/cvs/src/add.c
index d71716b..4f3f55e 100644
--- a/contrib/cvs/src/add.c
+++ b/contrib/cvs/src/add.c
@@ -187,16 +187,6 @@ add (argc, argv)
/* FIXME: Does this erroneously call Create_Admin in error
conditions which are only detected once the server gets its
hands on things? */
- /* FIXME-also: if filenames are case-insensitive on the
- client, and the directory in the repository already
- exists and is named "foo", and the command is "cvs add
- FOO", this call to Create_Admin puts the wrong thing in
- CVS/Repository and so a subsequent "cvs update" will
- give an error. The fix will be to have the server report
- back what it actually did (e.g. use tagged text for the
- "Directory %s added" message), and then Create_Admin,
- which should also fix the error handling concerns. */
-
if (isdir (argv[j]))
{
char *tag;
@@ -698,9 +688,11 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname);
if (options)
free (options);
- return (err);
+ return err;
}
+
+
/*
* The specified user file is really a directory. So, let's make sure that
* it is created in the RCS source repository, and that the user's directory
@@ -728,12 +720,12 @@ add_directory (finfo)
/* "Can't happen". */
error (0, 0,
"directory %s not added; must be a direct sub-directory", dir);
- return (1);
+ return 1;
}
if (fncmp (dir, CVSADM) == 0)
{
error (0, 0, "cannot add a `%s' directory", CVSADM);
- return (1);
+ return 1;
}
/* before we do anything else, see if we have any per-directory tags */
@@ -875,7 +867,7 @@ out:
free_cwd (&cwd);
if (rcsdir != NULL)
free (rcsdir);
- return (0);
+ return 0;
}
@@ -898,7 +890,7 @@ build_entry (repository, user, options, message, entries, tag)
FILE *fp;
if (noexec)
- return (0);
+ return 0;
/*
* The requested log is read directly from the user and stored in the
@@ -923,5 +915,5 @@ build_entry (repository, user, options, message, entries, tag)
(void) sprintf (line, "Initial %s", user);
Register (entries, user, "0", line, options, tag, (char *) 0, (char *) 0);
free (line);
- return (0);
+ return 0;
}
diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c
index 1b7f7c8..91c61a4 100644
--- a/contrib/cvs/src/client.c
+++ b/contrib/cvs/src/client.c
@@ -4814,7 +4814,6 @@ start_rsh_server (root, to_server, from_server)
const char **p = argv;
*p++ = cvs_rsh;
- *p++ = root->hostname;
/* If the login names differ between client and server
* pass it on to rsh.
@@ -4825,6 +4824,7 @@ start_rsh_server (root, to_server, from_server)
*p++ = root->username;
}
+ *p++ = root->hostname;
*p++ = command;
*p++ = NULL;
diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c
index 1548045..86c8106 100644
--- a/contrib/cvs/src/commit.c
+++ b/contrib/cvs/src/commit.c
@@ -155,7 +155,7 @@ find_dirent_proc (callerdat, dir, repository, update_dir, entries)
is that it (or some variant thereof) should go in all the
dirent procs. Unless someone has some better idea... */
if (!isdir (dir))
- return (R_SKIP_ALL);
+ return R_SKIP_ALL;
/* initialize the ignore list for this directory */
find_data->ignlist = getlist ();
@@ -225,6 +225,8 @@ find_filesdoneproc (callerdat, err, repository, update_dir, entries)
return err;
}
+
+
static int find_fileproc PROTO ((void *callerdat, struct file_info *finfo));
/* Machinery to find out what is modified, added, and removed. It is
@@ -341,6 +343,8 @@ find_fileproc (callerdat, finfo)
return 0;
}
+
+
static int copy_ulist PROTO ((Node *, void *));
static int
@@ -389,15 +393,16 @@ commit (argc, argv)
struct passwd *pw;
if ((pw = (struct passwd *) getpwnam (getcaller ())) == NULL)
- error (1, 0, "your apparent username (%s) is unknown to this system",
- getcaller ());
+ error (1, 0,
+ "your apparent username (%s) is unknown to this system",
+ getcaller ());
if (pw->pw_uid == (uid_t) 0)
error (1, 0, "'root' is not allowed to commit files");
}
#endif /* CVS_BADROOT */
optind = 0;
- while( ( c = getopt( argc, argv, COMMIT_OPTIONS ) ) != -1 )
+ while ((c = getopt (argc, argv, COMMIT_OPTIONS)) != -1)
{
switch (c)
{
@@ -518,7 +523,12 @@ commit (argc, argv)
operate on, and only work with those files in the future.
This saves time--we don't want to search the file system
of the working directory twice. */
- find_args.argv = (char **) xmalloc (find_args.argc * sizeof (char **));
+ if (size_overflow_p (xtimes (find_args.argc, sizeof (char **))))
+ {
+ find_args.argc = 0;
+ return 0;
+ }
+ find_args.argv = xmalloc (xtimes (find_args.argc, sizeof (char **)));
find_args.argc = 0;
walklist (find_args.ulist, copy_ulist, &find_args);
@@ -713,9 +723,11 @@ commit (argc, argv)
sleep_past (last_register_time);
}
- return (err);
+ return err;
}
+
+
/* This routine determines the status of a given file and retrieves
the version information that is associated with that file. */
@@ -803,6 +815,8 @@ classify_file_internal (finfo, vers)
return status;
}
+
+
/*
* Check to see if a file is ok to commit and make sure all files are
* up-to-date
@@ -826,10 +840,11 @@ check_fileproc (callerdat, finfo)
if (!finfo->repository)
{
error (0, 0, "nothing known about `%s'", finfo->fullname);
- return (1);
+ return 1;
}
- if (strncmp (finfo->repository, current_parsed_root->directory, cvsroot_len) == 0
+ if (strncmp (finfo->repository, current_parsed_root->directory,
+ cvsroot_len) == 0
&& ISDIRSEP (finfo->repository[cvsroot_len])
&& strncmp (finfo->repository + cvsroot_len + 1,
CVSROOTADM,
@@ -859,7 +874,7 @@ check_fileproc (callerdat, finfo)
case T_REMOVE_ENTRY:
error (0, 0, "Up-to-date check failed for `%s'", finfo->fullname);
freevers_ts (&vers);
- return (1);
+ return 1;
case T_MODIFIED:
case T_ADDED:
case T_REMOVED:
@@ -885,7 +900,7 @@ check_fileproc (callerdat, finfo)
"cannot commit with sticky date for file `%s'",
finfo->fullname);
freevers_ts (&vers);
- return (1);
+ return 1;
}
if (status == T_MODIFIED && vers->tag &&
!RCS_isbranch (finfo->rcs, vers->tag))
@@ -894,7 +909,7 @@ check_fileproc (callerdat, finfo)
"sticky tag `%s' for file `%s' is not a branch",
vers->tag, finfo->fullname);
freevers_ts (&vers);
- return (1);
+ return 1;
}
}
if (status == T_MODIFIED && !force_ci && vers->ts_conflict)
@@ -911,7 +926,7 @@ check_fileproc (callerdat, finfo)
"file `%s' had a conflict and has not been modified",
finfo->fullname);
freevers_ts (&vers);
- return (1);
+ return 1;
}
if (file_has_markers (finfo))
@@ -955,7 +970,7 @@ warning: file `%s' seems to still contain conflict indicators",
"cannot remove file `%s' which has a numeric sticky"
" tag of `%s'", finfo->fullname, vers->tag);
freevers_ts (&vers);
- return (1);
+ return 1;
}
}
if (status == T_ADDED)
@@ -969,7 +984,7 @@ warning: file `%s' seems to still contain conflict indicators",
"cannot add file `%s' when RCS file `%s' already exists",
finfo->fullname, finfo->rcs->path);
freevers_ts (&vers);
- return (1);
+ return 1;
}
}
else if (isdigit ((unsigned char) *vers->tag) &&
@@ -979,7 +994,7 @@ warning: file `%s' seems to still contain conflict indicators",
"cannot add file `%s' with revision `%s'; must be on trunk",
finfo->fullname, vers->tag);
freevers_ts (&vers);
- return (1);
+ return 1;
}
}
@@ -1082,7 +1097,7 @@ warning: file `%s' seems to still contain conflict indicators",
case T_UNKNOWN:
error (0, 0, "nothing known about `%s'", finfo->fullname);
freevers_ts (&vers);
- return (1);
+ return 1;
case T_UPTODATE:
break;
default:
@@ -1091,7 +1106,7 @@ warning: file `%s' seems to still contain conflict indicators",
}
freevers_ts (&vers);
- return (0);
+ return 0;
}
@@ -1110,14 +1125,16 @@ check_direntproc (callerdat, dir, repos, update_dir, entries)
List *entries;
{
if (!isdir (dir))
- return (R_SKIP_ALL);
+ return R_SKIP_ALL;
if (!quiet)
error (0, 0, "Examining %s", update_dir);
- return (R_PROCESS);
+ return R_PROCESS;
}
+
+
/*
* Walklist proc to run pre-commit checks
*/
@@ -1133,9 +1150,11 @@ precommit_list_proc (p, closure)
{
run_arg (p->key);
}
- return (0);
+ return 0;
}
+
+
/*
* Callback proc for pre-commit checking
*/
@@ -1160,7 +1179,7 @@ precommit_proc (repository, filter)
{
error (0, errno, "cannot find pre-commit filter `%s'", s);
free (s);
- return (1); /* so it fails! */
+ return 1; /* so it fails! */
}
free (s);
}
@@ -1168,9 +1187,11 @@ precommit_proc (repository, filter)
run_setup (filter);
run_arg (repository);
(void) walklist (saved_ulist, precommit_list_proc, NULL);
- return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
+ return run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY);
}
+
+
/*
* Run the pre-commit checks for the dir
*/
@@ -1195,7 +1216,7 @@ check_filesdoneproc (callerdat, err, repos, update_dir, entries)
/* skip the checks if there's nothing to do */
if (saved_ulist == NULL || saved_ulist->list->next == saved_ulist->list)
- return (err);
+ return err;
/* run any pre-commit checks */
if ((n = Parse_Info (CVSROOTADM_COMMITINFO, repos, precommit_proc, 1)) > 0)
@@ -1204,9 +1225,11 @@ check_filesdoneproc (callerdat, err, repos, update_dir, entries)
err += n;
}
- return (err);
+ return err;
}
+
+
/*
* Do the work of committing a file
*/
@@ -1249,7 +1272,7 @@ commit_fileproc (callerdat, finfo)
* all up-to-date so nothing really needs to be done
*/
if (p == NULL)
- return (0);
+ return 0;
ulist = ((struct master_lists *) p->data)->ulist;
cilist = ((struct master_lists *) p->data)->cilist;
@@ -1273,7 +1296,7 @@ commit_fileproc (callerdat, finfo)
p = findnode (cilist, finfo->file);
if (p == NULL)
- return (0);
+ return 0;
ci = p->data;
if (ci->status == T_MODIFIED)
@@ -1431,9 +1454,11 @@ out:
if (SIG_inCrSect ())
SIG_endCrSect ();
- return (err);
+ return err;
}
+
+
/*
* Log the commit and clean up the update list
*/
@@ -1451,7 +1476,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
p = findnode (mulist, update_dir);
if (p == NULL)
- return (err);
+ return err;
ulist = ((struct master_lists *) p->data)->ulist;
@@ -1501,9 +1526,11 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
}
}
- return (err);
+ return err;
}
+
+
/*
* Get the log message for a dir
*/
@@ -1521,7 +1548,7 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
char *real_repos;
if (!isdir (dir))
- return (R_SKIP_ALL);
+ return R_SKIP_ALL;
/* find the update list for this dir */
p = findnode (mulist, update_dir);
@@ -1532,7 +1559,7 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
/* skip the files as an optimization */
if (ulist == NULL || ulist->list->next == ulist->list)
- return (R_SKIP_FILES);
+ return R_SKIP_FILES;
/* get commit message */
real_repos = Name_Repository (dir, update_dir);
@@ -1545,9 +1572,11 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
do_editor (update_dir, &saved_message, real_repos, ulist);
do_verify (&saved_message, real_repos);
free (real_repos);
- return (R_PROCESS);
+ return R_PROCESS;
}
+
+
/*
* Process the post-commit proc if necessary
*/
@@ -1572,9 +1601,11 @@ commit_dirleaveproc (callerdat, dir, err, update_dir, entries)
free (repos);
}
- return (err);
+ return err;
}
+
+
/*
* find the maximum major rev number in an entries file
*/
@@ -1661,7 +1692,7 @@ remove_file (finfo, tag, message)
if (rev == NULL)
{
error (0, 0, "cannot find branch \"%s\".", tag);
- return (1);
+ return 1;
}
branchname = RCS_getbranch (finfo->rcs, rev, 1);
@@ -1693,7 +1724,7 @@ remove_file (finfo, tag, message)
{
error (0, 0, "cannot change branch to default for %s",
finfo->fullname);
- return (1);
+ return 1;
}
RCS_rewrite (finfo->rcs, NULL, NULL);
}
@@ -1707,7 +1738,7 @@ remove_file (finfo, tag, message)
{
error (0, 0,
"failed to check out `%s'", finfo->fullname);
- return (1);
+ return 1;
}
/* Except when we are creating a branch, lock the revision so that
@@ -1728,7 +1759,7 @@ remove_file (finfo, tag, message)
if (!quiet)
error (0, retcode == -1 ? errno : 0,
"failed to commit dead revision for `%s'", finfo->fullname);
- return (1);
+ return 1;
}
/* At this point, the file has been committed as removed. We should
probably tell the history file about it */
@@ -1753,9 +1784,11 @@ remove_file (finfo, tag, message)
free (old_path);
Scratch_Entry (finfo->entries, finfo->file);
- return (0);
+ return 0;
}
+
+
/*
* Do the actual checkin for added files
*/
@@ -1784,9 +1817,11 @@ finaladd (finfo, rev, tag, options)
(void) time (&last_register_time);
- return (ret);
+ return ret;
}
+
+
/*
* Unlock an rcs file
*/
@@ -1852,6 +1887,8 @@ fixbranch (rcs, branch)
}
}
+
+
/*
* do the initial part of a file add for the named file. if adding
* with a tag, put the file in the Attic and point the symbolic tag
@@ -2189,6 +2226,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
return retval;
}
+
+
/*
* Attempt to place a lock on the RCS file; returns 0 if it could and 1 if it
* couldn't. If the RCS file currently has a branch as the head, we must
@@ -2226,7 +2265,7 @@ lock_RCS (user, rcs, rev, repository)
rcs->path);
if (branch)
free (branch);
- return (1);
+ return 1;
}
}
err = RCS_lock (rcs, NULL, 1);
@@ -2260,7 +2299,7 @@ lock_RCS (user, rcs, rev, repository)
if (sbranch != NULL)
free (sbranch);
sbranch = branch;
- return (0);
+ return 0;
}
/* try to restore the branch if we can on error */
@@ -2269,9 +2308,11 @@ lock_RCS (user, rcs, rev, repository)
if (branch)
free (branch);
- return (1);
+ return 1;
}
+
+
/*
* free an UPDATE node's data
*/
diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h
index 42c08f5..9f601ce 100644
--- a/contrib/cvs/src/cvs.h
+++ b/contrib/cvs/src/cvs.h
@@ -40,6 +40,10 @@
#include "popen.h"
#endif
+/* Begin GNULIB headers. */
+#include "xsize.h"
+/* End GNULIB headers. */
+
#ifdef STDC_HEADERS
#include <stdlib.h>
#else
@@ -608,7 +612,6 @@ extern void expand_wild PROTO ((int argc, char **argv,
#ifdef SERVER_SUPPORT
extern int cvs_casecmp PROTO ((const char *, const char *));
-extern int fopen_case PROTO ((char *, char *, FILE **, char **));
#endif
void strip_trailing_slashes PROTO((char *path));
diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c
index 57511f4..8b5990a 100644
--- a/contrib/cvs/src/filesubr.c
+++ b/contrib/cvs/src/filesubr.c
@@ -1029,8 +1029,14 @@ expand_wild (argc, argv, pargc, pargv)
char ***pargv;
{
int i;
+ if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
+ *pargc = 0;
+ *pargv = NULL;
+ error (0, 0, "expand_wild: too many arguments");
+ return;
+ }
*pargc = argc;
- *pargv = (char **) xmalloc (argc * sizeof (char *));
+ *pargv = xmalloc (xtimes (argc, sizeof (char *)));
for (i = 0; i < argc; ++i)
(*pargv)[i] = xstrdup (argv[i]);
}
diff --git a/contrib/cvs/src/history.c b/contrib/cvs/src/history.c
index 8e8d607..154c2de 100644
--- a/contrib/cvs/src/history.c
+++ b/contrib/cvs/src/history.c
@@ -416,8 +416,11 @@ history (argc, argv)
working = 1;
break;
case 'X': /* Undocumented debugging flag */
+#ifdef DEBUG
histfile = optarg;
+#endif
break;
+
case 'D': /* Since specified date */
if (*since_rev || *since_tag || *backto)
{
@@ -906,9 +909,13 @@ save_user (name)
{
if (user_count == user_max)
{
- user_max += USER_INCREMENT;
- user_list = (char **) xrealloc ((char *) user_list,
- (int) user_max * sizeof (char *));
+ user_max = xsum (user_max, USER_INCREMENT);
+ if (size_overflow_p (xtimes (user_max, sizeof (char *))))
+ {
+ error (0, 0, "save_user: too many users");
+ return;
+ }
+ user_list = xrealloc (user_list, xtimes (user_max, sizeof (char *)));
}
user_list[user_count++] = xstrdup (name);
}
@@ -936,9 +943,13 @@ save_file (dir, name, module)
if (file_count == file_max)
{
- file_max += FILE_INCREMENT;
- file_list = (struct file_list_str *) xrealloc ((char *) file_list,
- file_max * sizeof (*fl));
+ file_max = xsum (file_max, FILE_INCREMENT);
+ if (size_overflow_p (xtimes (file_max, sizeof (*fl))))
+ {
+ error (0, 0, "save_file: too many files");
+ return;
+ }
+ file_list = xrealloc (file_list, xtimes (file_max, sizeof (*fl)));
}
fl = &file_list[file_count++];
fl->l_file = cp = xmalloc (strlen (dir) + strlen (name) + 2);
@@ -977,9 +988,13 @@ save_module (module)
{
if (mod_count == mod_max)
{
- mod_max += MODULE_INCREMENT;
- mod_list = (char **) xrealloc ((char *) mod_list,
- mod_max * sizeof (char *));
+ mod_max = xsum (mod_max, MODULE_INCREMENT);
+ if (size_overflow_p (xtimes (mod_max, sizeof (char *))))
+ {
+ error (0, 0, "save_module: too many modules");
+ return;
+ }
+ mod_list = xrealloc (mod_list, xtimes (mod_max, sizeof (char *)));
}
mod_list[mod_count++] = xstrdup (module);
}
diff --git a/contrib/cvs/src/ignore.c b/contrib/cvs/src/ignore.c
index 26c39e7..e9bcf79 100644
--- a/contrib/cvs/src/ignore.c
+++ b/contrib/cvs/src/ignore.c
@@ -44,6 +44,8 @@ const char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state\
no longer ask the server about what is in CVSROOTADM_IGNORE. */
int ign_inhibit_server;
+
+
/*
* To the "ignore list", add the hard-coded default ignored wildcards above,
* the wildcards found in $CVSROOT/CVSROOT/cvsignore, the wildcards found in
@@ -100,6 +102,8 @@ ign_setup ()
/* Later, add ignore entries found in -I arguments */
}
+
+
/*
* Open a file and read lines, feeding each line to a line parser. Arrange
* for keeping a temporary list of wildcards at the end, if the "hold"
diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c
index 1de1b94..9e10bd9 100644
--- a/contrib/cvs/src/log.c
+++ b/contrib/cvs/src/log.c
@@ -1078,7 +1078,7 @@ log_expand_revlist (rcs, revlist, default_branch)
free (branch);
}
}
- if (nr->first == NULL)
+ if (nr->first == NULL && !really_quiet)
{
error (0, 0, "warning: no branch `%s' in `%s'",
r->first, rcs->path);
@@ -1101,7 +1101,7 @@ log_expand_revlist (rcs, revlist, default_branch)
nr->first = RCS_whatbranch (rcs, r->first);
else
nr->first = RCS_gettag (rcs, r->first, 1, (int *) NULL);
- if (nr->first == NULL)
+ if (nr->first == NULL && !really_quiet)
{
error (0, 0, "warning: no revision `%s' in `%s'",
r->first, rcs->path);
@@ -1119,7 +1119,7 @@ log_expand_revlist (rcs, revlist, default_branch)
nr->last = RCS_whatbranch (rcs, r->last);
else
nr->last = RCS_gettag (rcs, r->last, 1, (int *) NULL);
- if (nr->last == NULL)
+ if (nr->last == NULL && !really_quiet)
{
error (0, 0, "warning: no revision `%s' in `%s'",
r->last, rcs->path);
diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh
index 015d83e..acbb8d0 100755
--- a/contrib/cvs/src/sanity.sh
+++ b/contrib/cvs/src/sanity.sh
@@ -792,7 +792,7 @@ if test x"$*" = x; then
tests="${tests} modules modules2 modules3 modules4 modules5 modules6"
tests="${tests} mkmodules co-d"
tests="${tests} cvsadm emptydir abspath abspath2 toplevel toplevel2"
- tests="${tests} top-level checkout_repository"
+ tests="${tests} rstar-toplevel trailingslashes checkout_repository"
# Log messages, error messages.
tests="${tests} mflag editor errmsg1 errmsg2 adderrmsg opterrmsg"
# Watches, binary files, history browsing, &c.
@@ -1920,12 +1920,45 @@ done"
${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
new revision: 2\.0; previous revision: 1\.3
done"
+ dotest basica-8a1a "${testcvs} -q ci -m bump-it -r 2.9" \
+"Checking in ssfile;
+${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
+new revision: 2\.9; previous revision: 2\.0
+done"
+ # Test string-based revion number increment rollover
+ dotest basica-8a1b "${testcvs} -q ci -m bump-it -f -r 2" \
+"Checking in ssfile;
+${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
+new revision: 2\.10; previous revision: 2\.9
+done"
+ dotest basica-8a1c "${testcvs} -q ci -m bump-it -r 2.99" \
+"Checking in ssfile;
+${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
+new revision: 2\.99; previous revision: 2\.10
+done"
+ # Test string-based revion number increment rollover
+ dotest basica-8a1d "${testcvs} -q ci -m bump-it -f -r 2" \
+"Checking in ssfile;
+${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
+new revision: 2\.100; previous revision: 2\.99
+done"
+ dotest basica-8a1e "${testcvs} -q ci -m bump-it -r 2.1099" \
+"Checking in ssfile;
+${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
+new revision: 2\.1099; previous revision: 2\.100
+done"
+ # Test string-based revion number increment rollover
+ dotest basica-8a1f "${testcvs} -q ci -m bump-it -f -r 2" \
+"Checking in ssfile;
+${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
+new revision: 2\.1100; previous revision: 2\.1099
+done"
# -f should not be necessary, but it should be harmless.
# Also test the "-r 3" (rather than "-r 3.0") usage.
dotest basica-8a2 "${testcvs} -q ci -m bump-it -f -r 3" \
"Checking in ssfile;
${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
-new revision: 3\.1; previous revision: 2\.0
+new revision: 3\.1; previous revision: 2\.1100
done"
# Test using -r to create a branch
@@ -1943,9 +1976,8 @@ done"
dotest basica-8a5 "${testcvs} -q up -A ./" "[UP] ssfile"
cd ../..
- dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" ''
- dotest basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd" \
-''
+ dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3"
+ dotest basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd"
# The .* here will normally be "No such file or directory",
# but if memory serves some systems (AIX?) have a different message.
@@ -2013,11 +2045,23 @@ done"
done"
dotest basica-o5a "${testcvs} -n admin -o 1.2::3.1 ssfile" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
+deleting revision 2\.1100
+deleting revision 2\.1099
+deleting revision 2\.100
+deleting revision 2\.99
+deleting revision 2\.10
+deleting revision 2\.9
deleting revision 2\.0
deleting revision 1\.3
done"
dotest basica-o6 "${testcvs} admin -o 1.2::3.1 ssfile" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
+deleting revision 2\.1100
+deleting revision 2\.1099
+deleting revision 2\.100
+deleting revision 2\.99
+deleting revision 2\.10
+deleting revision 2\.9
deleting revision 2\.0
deleting revision 1\.3
done"
@@ -6018,8 +6062,7 @@ ${QUESTION} sdir"
"${QUESTION} sdir
${PROG} \[update aborted\]: no such tag br"
dotest dirs2-10ar \
-"${testcvs} -q rdiff -u -r 1.1 -r br first-dir/sdir/file1" \
-""
+"${testcvs} -q rdiff -u -r 1.1 -r br first-dir/sdir/file1"
dotest_fail dirs2-10-again "${testcvs} update -d -r br" \
"${QUESTION} sdir
${PROG} update: Updating \.
@@ -13849,14 +13892,14 @@ ${PROG} commit: Rebuilding administrative file database"
- top-level)
+ rstar-toplevel)
# FIXCVS:
# This test confirms a bug that exists in the r* commands currently
# when run against the top-level project.
#
# The assertion failure is something like:
# do_recursion: Assertion \`strstr (repository, \"/\./\") == ((void \*)0)' failed\..*"
- dotest_fail top-level-1 "$testcvs rlog ." \
+ dotest_fail rstar-toplevel-1 "$testcvs rlog ." \
"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}"
if $keep; then
@@ -13867,6 +13910,52 @@ ${PROG} commit: Rebuilding administrative file database"
+ trailingslashes)
+ # Some tests of CVS's reactions to path specifications containing
+ # trailing slashes.
+ mkdir trailingslashes; cd trailingslashes
+ dotest trailingslashes-init-1 "$testcvs -Q co -ldt ."
+ dotest trailingslashes-init-2 "$testcvs -Q co -dt2 ."
+ cd t
+ echo "Ahh'll be baaack." >topfile
+ dotest trailingslashes-init-3 "$testcvs -Q add topfile"
+ dotest trailingslashes-init-4 "$testcvs -Q ci -mto-top" \
+"RCS file: $CVSROOT_DIRNAME/topfile,v
+done
+Checking in topfile;
+$CVSROOT_DIRNAME/topfile,v <-- topfile
+initial revision: 1\.1
+done"
+
+ # First, demonstrate the usual case.
+ cd ../t2
+ dotest trailingslashes-1 "$testcvs -q up CVSROOT"
+ dotest_fail trailingslashes-1a "test -f topfile"
+
+ # FIXCVS:
+ # Now the one that fails in remote mode.
+ # This highlights one of the failure cases mentioned in TODO item
+ # #205.
+ if $remote; then
+ dotest trailingslashes-2 "$testcvs -q up CVSROOT/" \
+"U topfile"
+ dotest trailingslashes-2a "test -f topfile"
+ else
+ dotest trailingslashes-2 "$testcvs -q up CVSROOT/"
+ dotest_fail trailingslashes-2a "test -f topfile"
+ fi
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ rm -rf trailingslashes $CVSROOT_DIRNAME/topfile,v
+ ;;
+
+
+
checkout_repository)
dotest_fail checkout_repository-1 \
"${testcvs} co -d ${CVSROOT_DIRNAME} CVSROOT" \
@@ -26973,6 +27062,27 @@ Global_option -l
noop
EOF
+ # There used to be some exploits based on malformed Entry requests
+ dotest server-17 "$testcvs server" \
+"E protocol error: Malformed Entry
+error " <<EOF
+Root $TESTDIR/crerepos
+Directory .
+$TESTDIR/crerepos/dir1
+Entry X/file1/1.1////
+noop
+EOF
+
+ dotest server-18 "$testcvs server" \
+"E protocol error: Malformed Entry
+error " <<EOF
+Root $TESTDIR/crerepos
+Directory .
+$TESTDIR/crerepos/dir1
+Entry /CC/CC/CC
+noop
+EOF
+
if $keep; then
echo Keeping ${TESTDIR} and exiting due to --keep
exit 0
@@ -27494,7 +27604,11 @@ done"
# files. We would like to not leave any behind.
if $remote && ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then
# A true value means ls found files/directories with these names.
- fail "Found cvs-serv* directories in $TMPDIR."
+ # Give the server some time to finish, then retry.
+ sleep 1
+ if ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then
+ fail "Found cvs-serv* directories in $TMPDIR."
+ fi
fi
if ls $TMPDIR/cvs?????? >/dev/null 2>&1; then
# A true value means ls found files/directories with these names.
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c
index 3d36ad6..bc6578d 100644
--- a/contrib/cvs/src/server.c
+++ b/contrib/cvs/src/server.c
@@ -917,7 +917,7 @@ serve_max_dotdot (arg)
int i;
char *p;
- if (lim < 0)
+ if (lim < 0 || lim > 10000)
return;
p = xmalloc (strlen (server_temp_dir) + 2 * lim + 10);
if (p == NULL)
@@ -1622,8 +1622,7 @@ serve_unchanged (arg)
char *cp;
char *timefield;
- if (error_pending ())
- return;
+ if (error_pending ()) return;
if (outside_dir (arg))
return;
@@ -1637,7 +1636,16 @@ serve_unchanged (arg)
&& strlen (arg) == cp - name
&& strncmp (arg, name, cp - name) == 0)
{
- timefield = strchr (cp + 1, '/') + 1;
+ if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
+ {
+ /* We didn't find the record separator or it is followed by
+ * the end of the string, so just exit.
+ */
+ if (alloc_pending (80))
+ sprintf (pending_error_text,
+ "E Malformed Entry encountered.");
+ return;
+ }
/* If the time field is not currently empty, then one of
* serve_modified, serve_is_modified, & serve_unchanged were
* already called for this file. We would like to ignore the
@@ -1684,8 +1692,7 @@ serve_is_modified (arg)
/* Have we found this file in "entries" yet. */
int found;
- if (error_pending ())
- return;
+ if (error_pending ()) return;
if (outside_dir (arg))
return;
@@ -1700,7 +1707,16 @@ serve_is_modified (arg)
&& strlen (arg) == cp - name
&& strncmp (arg, name, cp - name) == 0)
{
- timefield = strchr (cp + 1, '/') + 1;
+ if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
+ {
+ /* We didn't find the record separator or it is followed by
+ * the end of the string, so just exit.
+ */
+ if (alloc_pending (80))
+ sprintf (pending_error_text,
+ "E Malformed Entry encountered.");
+ return;
+ }
/* If the time field is not currently empty, then one of
* serve_modified, serve_is_modified, & serve_unchanged were
* already called for this file. We would like to ignore the
@@ -1785,8 +1801,29 @@ serve_entry (arg)
{
struct an_entry *p;
char *cp;
+ int i = 0;
if (error_pending()) return;
- p = (struct an_entry *) xmalloc (sizeof (struct an_entry));
+
+ /* Verify that the entry is well-formed. This can avoid problems later.
+ * At the moment we only check that the Entry contains five slashes in
+ * approximately the correct locations since some of the code makes
+ * assumptions about this.
+ */
+ cp = arg;
+ if (*cp == 'D') cp++;
+ while (i++ < 5)
+ {
+ if (!cp || *cp != '/')
+ {
+ if (alloc_pending (80))
+ sprintf (pending_error_text,
+ "E protocol error: Malformed Entry");
+ return;
+ }
+ cp = strchr (cp + 1, '/');
+ }
+
+ p = xmalloc (sizeof (struct an_entry));
if (p == NULL)
{
pending_error = ENOMEM;
@@ -2018,6 +2055,9 @@ serve_notify (arg)
{
char *cp;
+ if (!data[0])
+ goto error;
+
if (strchr (data, '+'))
goto error;
@@ -2149,6 +2189,14 @@ serve_argument (arg)
char *p;
if (error_pending()) return;
+
+ if (argument_count >= 10000)
+ {
+ if (alloc_pending (80))
+ sprintf (pending_error_text,
+ "E Protocol error: too many arguments");
+ return;
+ }
if (argument_vector_size <= argument_count)
{
@@ -2179,6 +2227,14 @@ serve_argumentx (arg)
char *p;
if (error_pending()) return;
+
+ if (argument_count <= 1)
+ {
+ if (alloc_pending (80))
+ sprintf (pending_error_text,
+ "E Protocol error: called argumentx without prior call to argument");
+ return;
+ }
p = argument_vector[argument_count - 1];
p = xrealloc (p, strlen (p) + 1 + strlen (arg) + 1);
@@ -2512,7 +2568,7 @@ check_command_legal_p (cmd_name)
save some code here... -kff */
/* Chop newline by hand, for strcmp()'s sake. */
- if (linebuf[num_red - 1] == '\n')
+ if (num_red > 0 && linebuf[num_red - 1] == '\n')
linebuf[num_red - 1] = '\0';
if (strcmp (linebuf, CVS_Username) == 0)
@@ -2567,7 +2623,7 @@ check_command_legal_p (cmd_name)
while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
{
/* Chop newline by hand, for strcmp()'s sake. */
- if (linebuf[num_red - 1] == '\n')
+ if (num_red > 0 && linebuf[num_red - 1] == '\n')
linebuf[num_red - 1] = '\0';
if (strcmp (linebuf, CVS_Username) == 0)
diff --git a/contrib/cvs/src/subr.c b/contrib/cvs/src/subr.c
index 94f5bbd..da8d478 100644
--- a/contrib/cvs/src/subr.c
+++ b/contrib/cvs/src/subr.c
@@ -311,6 +311,9 @@ compare_revnums (rev1, rev2)
return result;
}
+/* Increment a revision number. Working on the string is a bit awkward,
+ but it avoid problems with integer overflow should the revision numbers
+ get really big. */
char *
increment_revnum (rev)
const char *rev;
@@ -319,17 +322,29 @@ increment_revnum (rev)
int lastfield;
size_t len = strlen (rev);
- newrev = (char *) xmalloc (len + 2);
+ newrev = xmalloc (len + 2);
memcpy (newrev, rev, len + 1);
- p = strrchr (newrev, '.');
- if (p == NULL)
+ for (p = newrev + len; p != newrev; )
{
- free (newrev);
- return NULL;
+ --p;
+ if (!isdigit(*p))
+ {
+ ++p;
+ break;
+ }
+ if (*p != '9')
+ {
+ ++*p;
+ return newrev;
+ }
+ *p = '0';
}
- lastfield = atoi (++p);
- sprintf (p, "%d", lastfield + 1);
-
+ /* The number was all 9s, so change the first character to 1 and add
+ a 0 to the end. */
+ *p = '1';
+ p = newrev + len;
+ *p++ = '0';
+ *p = '\0';
return newrev;
}
@@ -659,7 +674,7 @@ file_has_conflict (finfo, ts_conflict)
/* If ts_conflict is NULL, there was no merge since the last
* commit and there can be no conflict.
*/
- assert ( ts_conflict );
+ assert (ts_conflict);
/*
* If the timestamp has changed and no
@@ -668,14 +683,14 @@ file_has_conflict (finfo, ts_conflict)
*/
#ifdef SERVER_SUPPORT
- if ( server_active )
+ if (server_active)
retcode = ts_conflict[0] == '=';
else
#endif /* SERVER_SUPPORT */
{
- filestamp = time_stamp ( finfo->file );
- retcode = !strcmp ( ts_conflict, filestamp );
- free ( filestamp );
+ filestamp = time_stamp (finfo->file);
+ retcode = !strcmp (ts_conflict, filestamp);
+ free (filestamp);
}
return retcode;
diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c
index e245e7b..62a6c63 100644
--- a/contrib/cvs/src/update.c
+++ b/contrib/cvs/src/update.c
@@ -420,9 +420,11 @@ update (argc, argv)
if (date != NULL)
free (date);
- return (err);
+ return err;
}
+
+
/*
* Command line interface to update (used by checkout)
*/
@@ -496,7 +498,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
argc, argv, local, which, aflag, CVS_LOCK_READ,
preload_update_dir, 1, (char *) NULL);
if (err)
- return (err);
+ return err;
/* FIXME-twp: at this point we should walk the hardlist
and update the `links' field of each hardlink_info struct
@@ -523,7 +525,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
sleep_past (last_register_time);
}
- return (err);
+ return err;
}
#ifdef PRESERVE_PERMISSIONS_SUPPORT
@@ -856,7 +858,7 @@ update_filesdone_proc (callerdat, err, repository, update_dir, entries)
Create_Root ((char *) NULL, current_parsed_root->original);
}
- return (err);
+ return err;
}
@@ -889,7 +891,7 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
{
/* if we aren't building dirs, blow it off */
if (!update_build_dirs)
- return (R_SKIP_ALL);
+ return R_SKIP_ALL;
/* Various CVS administrators are in the habit of removing
the repository directory for things they don't want any
@@ -917,7 +919,7 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
{
/* ignore the missing dir if -n is specified */
error (0, 0, "New directory `%s' -- ignored", update_dir);
- return (R_SKIP_ALL);
+ return R_SKIP_ALL;
}
else
{
@@ -1015,7 +1017,7 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
if (!quiet)
error (0, 0, "Updating %s", update_dir);
- return (R_PROCESS);
+ return R_PROCESS;
}
@@ -1075,9 +1077,11 @@ update_dirleave_proc (callerdat, dir, err, update_dir, entries)
}
}
- return (err);
+ return err;
}
+
+
static int isremoved PROTO ((Node *, void *));
/* Returns 1 if the file indicated by node has been removed. */
@@ -1093,6 +1097,8 @@ isremoved (node, closure)
return (entdata->version && entdata->version[0] == '-') ? 1 : 0;
}
+
+
/* Returns 1 if the argument directory is completely empty, other than the
existence of the CVS directory entry. Zero otherwise. If MIGHT_NOT_EXIST
and the directory doesn't exist, then just return 0. */
@@ -1109,7 +1115,7 @@ isemptydir (dir, might_not_exist)
if (might_not_exist && existence_error (errno))
return 0;
error (0, errno, "cannot open directory %s for empty check", dir);
- return (0);
+ return 0;
}
errno = 0;
while ((dp = CVS_READDIR (dirp)) != NULL)
@@ -1122,7 +1128,7 @@ isemptydir (dir, might_not_exist)
/* An entry other than the CVS directory. The directory
is certainly not empty. */
(void) CVS_CLOSEDIR (dirp);
- return (0);
+ return 0;
}
else
{
@@ -1153,7 +1159,7 @@ isemptydir (dir, might_not_exist)
/* There are files that have been removed, but not
committed! Do not consider the directory empty. */
(void) CVS_CLOSEDIR (dirp);
- return (0);
+ return 0;
}
}
}
@@ -1163,12 +1169,14 @@ isemptydir (dir, might_not_exist)
{
error (0, errno, "cannot read directory %s", dir);
(void) CVS_CLOSEDIR (dirp);
- return (0);
+ return 0;
}
(void) CVS_CLOSEDIR (dirp);
- return (1);
+ return 1;
}
+
+
/*
* scratch the Entries file entry associated with a file
*/
@@ -1213,9 +1221,11 @@ scratch_file (finfo, vers)
vers->ts_user = NULL;
}
}
- return (0);
+ return 0;
}
+
+
/*
* Check out a file.
*/
@@ -1503,9 +1513,11 @@ VERS: ", 0);
if (revbuf != NULL)
buf_free (revbuf);
- return (retval);
+ return retval;
}
+
+
#ifdef SERVER_SUPPORT
/* This function is used to write data from a file being checked out
@@ -1847,9 +1859,11 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
free (backup);
free (file1);
free (file2);
- return (retval);
+ return retval;
}
+
+
/* Write data to a file. Record whether the last byte written was a
newline. Optionally compute a checksum. This is called by
patch_file via RCS_checkout. */
@@ -2989,8 +3003,10 @@ special_file_mismatch (finfo, rev1, rev2)
#endif
}
+
+
int
joining ()
{
- return (join_rev1 != NULL);
+ return join_rev1 != NULL;
}
diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c
index 8ad9c4e..69eaa4c 100644
--- a/contrib/cvs/src/vers_ts.c
+++ b/contrib/cvs/src/vers_ts.c
@@ -287,7 +287,7 @@ time_stamp_server (file, vers_ts, entdata)
else if (entdata->timestamp
&& entdata->timestamp[0] == '=')
mark_unchanged (vers_ts);
- else if (entdata->timestamp != NULL
+ else if (entdata->timestamp
&& (entdata->timestamp[0] == 'M'
|| entdata->timestamp[0] == 'D')
&& entdata->timestamp[1] == '\0')
diff --git a/contrib/cvs/src/wrapper.c b/contrib/cvs/src/wrapper.c
index 8d7a8ef..548b3a5 100644
--- a/contrib/cvs/src/wrapper.c
+++ b/contrib/cvs/src/wrapper.c
@@ -237,6 +237,30 @@ wrap_unparse_rcs_options (line, first_call_p)
#endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
/*
+ * Remove fmt str specifier other than %% or %s. And allow
+ * only max_s %s specifiers
+ */
+wrap_clean_fmt_str(char *fmt, int max_s)
+{
+ while (*fmt) {
+ if (fmt[0] == '%' && fmt[1])
+ {
+ if (fmt[1] == '%')
+ fmt++;
+ else
+ if (fmt[1] == 's' && max_s > 0)
+ {
+ max_s--;
+ fmt++;
+ } else
+ *fmt = ' ';
+ }
+ fmt++;
+ }
+ return;
+}
+
+/*
* Open a file and read lines, feeding each line to a line parser. Arrange
* for keeping a temporary list of wrappers at the end, if the "temp"
* argument is set.
@@ -556,9 +580,8 @@ wrap_tocvs_process_file(fileName)
args = xmalloc (strlen (e->tocvsFilter)
+ strlen (fileName)
+ strlen (buf));
- /* FIXME: sprintf will blow up if the format string contains items other
- than %s, or contains too many %s's. We should instead be parsing
- e->tocvsFilter ourselves and giving a real error. */
+
+ wrap_clean_fmt_str(e->tocvsFilter, 2);
sprintf (args, e->tocvsFilter, fileName, buf);
run_setup (args);
run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY );
@@ -590,9 +613,8 @@ wrap_fromcvs_process_file(fileName)
args = xmalloc (strlen (e->fromcvsFilter)
+ strlen (fileName));
- /* FIXME: sprintf will blow up if the format string contains items other
- than %s, or contains too many %s's. We should instead be parsing
- e->fromcvsFilter ourselves and giving a real error. */
+
+ wrap_clean_fmt_str(e->fromcvsFilter, 1);
sprintf (args, e->fromcvsFilter, fileName);
run_setup (args);
run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL );
OpenPOWER on IntegriCloud