diff options
author | peter <peter@FreeBSD.org> | 2004-06-10 19:12:50 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2004-06-10 19:12:50 +0000 |
commit | b04a2d6a7a439dce932f5799009e4ff4e3e29e18 (patch) | |
tree | 535be444311d48c9bcacc8d5224f809d39b3c52a /contrib/cvs/src | |
parent | 1ca65160a61129882a143f867124863e87679616 (diff) | |
download | FreeBSD-src-b04a2d6a7a439dce932f5799009e4ff4e3e29e18.zip FreeBSD-src-b04a2d6a7a439dce932f5799009e4ff4e3e29e18.tar.gz |
Merge 1.11.15+ -> 1.11.17 changes onto mainline. I've left cvs.1 alone
for now.
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r-- | contrib/cvs/src/client.c | 2 | ||||
-rw-r--r-- | contrib/cvs/src/commit.c | 125 | ||||
-rw-r--r-- | contrib/cvs/src/cvs.h | 5 | ||||
-rw-r--r-- | contrib/cvs/src/filesubr.c | 8 | ||||
-rw-r--r-- | contrib/cvs/src/server.c | 76 | ||||
-rw-r--r-- | contrib/cvs/src/update.c | 50 |
6 files changed, 194 insertions, 72 deletions
diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c index ef2155f..aae404a 100644 --- a/contrib/cvs/src/client.c +++ b/contrib/cvs/src/client.c @@ -4818,7 +4818,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. @@ -4829,6 +4828,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 4a5b1fb..1edb95d 100644 --- a/contrib/cvs/src/commit.c +++ b/contrib/cvs/src/commit.c @@ -156,7 +156,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 (); @@ -226,6 +226,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 @@ -342,6 +344,8 @@ find_fileproc (callerdat, finfo) return 0; } + + static int copy_ulist PROTO ((Node *, void *)); static int @@ -390,15 +394,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) { @@ -519,7 +524,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); @@ -714,9 +724,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. */ @@ -804,6 +816,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 @@ -827,10 +841,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, @@ -860,7 +875,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: @@ -886,7 +901,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)) @@ -895,7 +910,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) @@ -912,7 +927,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)) @@ -956,7 +971,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) @@ -970,7 +985,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) && @@ -980,7 +995,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; } } @@ -1083,7 +1098,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: @@ -1092,7 +1107,7 @@ warning: file `%s' seems to still contain conflict indicators", } freevers_ts (&vers); - return (0); + return 0; } @@ -1111,14 +1126,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 */ @@ -1134,9 +1151,11 @@ precommit_list_proc (p, closure) { run_arg (p->key); } - return (0); + return 0; } + + /* * Callback proc for pre-commit checking */ @@ -1161,7 +1180,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); } @@ -1169,9 +1188,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 */ @@ -1196,7 +1217,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) @@ -1205,9 +1226,11 @@ check_filesdoneproc (callerdat, err, repos, update_dir, entries) err += n; } - return (err); + return err; } + + /* * Do the work of committing a file */ @@ -1250,7 +1273,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; @@ -1274,7 +1297,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) @@ -1432,9 +1455,11 @@ out: if (SIG_inCrSect ()) SIG_endCrSect (); - return (err); + return err; } + + /* * Log the commit and clean up the update list */ @@ -1452,7 +1477,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; @@ -1502,9 +1527,11 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries) } } - return (err); + return err; } + + /* * Get the log message for a dir */ @@ -1522,7 +1549,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); @@ -1533,7 +1560,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); @@ -1546,9 +1573,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 */ @@ -1573,9 +1602,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 */ @@ -1662,7 +1693,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); @@ -1694,7 +1725,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); } @@ -1708,7 +1739,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 @@ -1729,7 +1760,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 */ @@ -1754,9 +1785,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 */ @@ -1785,9 +1818,11 @@ finaladd (finfo, rev, tag, options) (void) time (&last_register_time); - return (ret); + return ret; } + + /* * Unlock an rcs file */ @@ -1853,6 +1888,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 @@ -2190,6 +2227,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 @@ -2227,7 +2266,7 @@ lock_RCS (user, rcs, rev, repository) rcs->path); if (branch) free (branch); - return (1); + return 1; } } err = RCS_lock (rcs, NULL, 1); @@ -2261,7 +2300,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 */ @@ -2270,9 +2309,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 f59a9ca..c47cdcf 100644 --- a/contrib/cvs/src/cvs.h +++ b/contrib/cvs/src/cvs.h @@ -41,6 +41,10 @@ #include "popen.h" #endif +/* Begin GNULIB headers. */ +#include "xsize.h" +/* End GNULIB headers. */ + #ifdef STDC_HEADERS #include <stdlib.h> #else @@ -617,7 +621,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 bf5be5e..b9f9bd5 100644 --- a/contrib/cvs/src/filesubr.c +++ b/contrib/cvs/src/filesubr.c @@ -1033,8 +1033,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/server.c b/contrib/cvs/src/server.c index 27debb9..e186c34 100644 --- a/contrib/cvs/src/server.c +++ b/contrib/cvs/src/server.c @@ -924,7 +924,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) @@ -1629,8 +1629,7 @@ serve_unchanged (arg) char *cp; char *timefield; - if (error_pending ()) - return; + if (error_pending ()) return; if (outside_dir (arg)) return; @@ -1644,7 +1643,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 @@ -1691,8 +1699,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; @@ -1707,7 +1714,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 @@ -1792,8 +1808,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; @@ -2025,6 +2062,9 @@ serve_notify (arg) { char *cp; + if (!data[0]) + goto error; + if (strchr (data, '+')) goto error; @@ -2156,6 +2196,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) { @@ -2186,6 +2234,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); @@ -2519,7 +2575,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) @@ -2574,7 +2630,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/update.c b/contrib/cvs/src/update.c index 479dde0..0ddf3bc 100644 --- a/contrib/cvs/src/update.c +++ b/contrib/cvs/src/update.c @@ -427,9 +427,11 @@ update (argc, argv) if (date != NULL) free (date); - return (err); + return err; } + + /* * Command line interface to update (used by checkout) */ @@ -503,7 +505,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 @@ -530,7 +532,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 @@ -863,7 +865,7 @@ update_filesdone_proc (callerdat, err, repository, update_dir, entries) Create_Root ((char *) NULL, current_parsed_root->original); } - return (err); + return err; } @@ -896,7 +898,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 @@ -924,7 +926,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 { @@ -1028,7 +1030,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; } @@ -1088,9 +1090,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. */ @@ -1106,6 +1110,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. */ @@ -1122,7 +1128,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) @@ -1135,7 +1141,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 { @@ -1166,7 +1172,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; } } } @@ -1176,12 +1182,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 */ @@ -1226,9 +1234,11 @@ scratch_file (finfo, vers) vers->ts_user = NULL; } } - return (0); + return 0; } + + /* * Check out a file. */ @@ -1516,9 +1526,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 @@ -1860,9 +1872,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. */ @@ -3002,8 +3016,10 @@ special_file_mismatch (finfo, rev1, rev2) #endif } + + int joining () { - return (join_rev1 != NULL); + return join_rev1 != NULL; } |