[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Patch to protect spaces in diff arguments.
From: |
Derek Price |
Subject: |
Patch to protect spaces in diff arguments. |
Date: |
Fri, 27 May 2005 13:16:13 -0400 |
User-agent: |
Mozilla Thunderbird 1.0.2 (Windows/20050317) |
I just committed the attached patch to the stable branch. This problem
has been listed in BUGS for some time, so I felt justified despite it
being a fairly large patch. I went to some lengths to keep it clean and
I think that it mostly actually simplifes the code.
Cheers,
Derek
Index: BUGS
===================================================================
RCS file: /cvs/ccvs/BUGS,v
retrieving revision 1.55.6.18
retrieving revision 1.55.6.19
diff -u -p -r1.55.6.18 -r1.55.6.19
--- BUGS 25 Aug 2004 03:14:01 -0000 1.55.6.18
+++ BUGS 27 May 2005 16:25:41 -0000 1.55.6.19
@@ -88,13 +88,6 @@ an incorrect value, though this does not
noticed under BSDI.
-* Spaces in arguments to `cvs diff' are currently split on spaces and tabs
-before being passed to diff. This can often cause diff to abort since it can
-no longer interpret its options string and if it can, coincidentally,
-interpret its option string, then the problem may be output in unexpected
-formats.
-
-
* Status
/*-------.
Index: ChangeLog
===================================================================
RCS file: /cvs/ccvs/ChangeLog,v
retrieving revision 1.692.2.209
retrieving revision 1.692.2.210
diff -u -p -r1.692.2.209 -r1.692.2.210
--- ChangeLog 4 May 2005 02:35:14 -0000 1.692.2.209
+++ ChangeLog 27 May 2005 16:25:41 -0000 1.692.2.210
@@ -1,3 +1,8 @@
+2005-05-27 Derek Price <derek@ximbiot.com>
+
+ * NEWS: Note diff space split fix.
+ * BUGS: Remove diff space split note.
+
2005-05-03 Derek Price <derek@ximbiot.com>
* INSTALL: Add footnote about compiling a CVS checkout of CVS on a
Index: NEWS
===================================================================
RCS file: /cvs/ccvs/NEWS,v
retrieving revision 1.116.2.131
retrieving revision 1.116.2.132
diff -u -p -r1.116.2.131 -r1.116.2.132
--- NEWS 2 May 2005 17:07:20 -0000 1.116.2.131
+++ NEWS 27 May 2005 16:25:41 -0000 1.116.2.132
@@ -3,6 +3,8 @@ Changes since 1.11.20:
BUG FIXES
+* `cvs diff' no longer splits its arguments on spaces.
+
* Thanks to an old report and patch from Stewart Brodie <stewart@eh.org>, a
potential crash in response to a corrupt RCS file has been fixed.
Index: src/ChangeLog
===================================================================
RCS file: /cvs/ccvs/src/ChangeLog,v
retrieving revision 1.2336.2.371
retrieving revision 1.2336.2.373
diff -u -p -r1.2336.2.371 -r1.2336.2.373
--- src/ChangeLog 2 May 2005 19:39:10 -0000 1.2336.2.371
+++ src/ChangeLog 27 May 2005 16:28:00 -0000 1.2336.2.373
@@ -1,3 +1,25 @@
+2005-05-27 Derek Price <derek@ximbiot.com>
+
+ * client.c (send_arg): Make arg const.
+ (send_option_string): Rename to...
+ (send_options): ...this and accept argc/argv in place of string.
+ * client.h: Update protos to match the changes to client.c.
+ * cvs.h (RCS_exec_rcsdiff, diff_exec): Update protos.
+ (run_add_arg_p, run_arg_free_p): New protos.
+ * diff.c (opts, opts_allocated): Replace with...
+ (diff_argv, diff_argc, diff_arg_allocated): ...these.
+ (add_diff_args): New convenience function.
+ (diff): Use new constructs and APIs.
+ * patch.c (patch_fileproc, RCS_checkin, RCS_delete_revs), rcscmds.c
+ (call_diff_add_arg, call_diff_setup, RCS_merge, RCS_exec_rcsdiff,
+ diff_exec, RCS_output_diff_options), update.c (patch_file): Use new
+ APIs.
+ * run.c (run_add_arg_p, run_arg_free_p): New functions.
+ (run_argc_allocated): Make size_t.
+ (run_setup, run_add_arg): Use new functions.
+ * sanity.sh: Accomodate above changes.
+ (rcslib-diffrgx-3): Slip in test for space splitting.
+
2005-05-02 Derek Price <derek@ximbiot.com>
Remove unnecessary level of indirection.
Index: src/client.c
===================================================================
RCS file: /cvs/ccvs/src/client.c,v
retrieving revision 1.318.4.27
retrieving revision 1.318.4.28
diff -u -p -r1.318.4.27 -r1.318.4.28
--- src/client.c 17 Mar 2005 15:39:09 -0000 1.318.4.27
+++ src/client.c 27 May 2005 16:25:10 -0000 1.318.4.28
@@ -4903,10 +4903,10 @@ start_rsh_server (root, to_server, from_
/* Send an argument STRING. */
void
send_arg (string)
- char *string;
+ const char *string;
{
char buf[1];
- char *p = string;
+ const char *p = string;
send_to_server ("Argument ", 0);
@@ -5404,36 +5404,15 @@ send_dirleave_proc (callerdat, dir, err,
}
/*
- * Send each option in a string to the server, one by one.
- * This assumes that the options are separated by spaces, for example
- * STRING might be "--foo -C5 -y".
+ * Send each option in an array to the server, one by one.
+ * argv might be "--foo=bar", "-C", "5", "-y".
*/
-
void
-send_option_string (string)
- char *string;
+send_options (int argc, char *const *argv)
{
- char *copy;
- char *p;
-
- copy = xstrdup (string);
- p = copy;
- while (1)
- {
- char *s;
- char l;
-
- for (s = p; *s != ' ' && *s != '\0'; s++)
- ;
- l = *s;
- *s = '\0';
- if (s != p)
- send_arg (p);
- if (l == '\0')
- break;
- p = s + 1;
- }
- free (copy);
+ int i;
+ for (i = 0; i < argc; i++)
+ send_arg (argv[i]);
}
Index: src/client.h
===================================================================
RCS file: /cvs/ccvs/src/client.h,v
retrieving revision 1.39.6.2
retrieving revision 1.39.6.3
diff -u -p -r1.39.6.2 -r1.39.6.3
--- src/client.h 20 Mar 2004 18:14:56 -0000 1.39.6.2
+++ src/client.h 27 May 2005 16:25:10 -0000 1.39.6.3
@@ -119,11 +119,10 @@ send_files PROTO((int argc, char **argv,
/* Send an argument to the remote server. */
void
-send_arg PROTO((char *string));
+send_arg PROTO((const char *string));
/* Send a string of single-char options to the remote server, one by one. */
-void
-send_option_string PROTO((char *string));
+void send_options PROTO ((int argc, char * const *argv));
extern void send_a_repository PROTO ((const char *, const char *,
const char *));
Index: src/cvs.h
===================================================================
RCS file: /cvs/ccvs/src/cvs.h,v
retrieving revision 1.235.4.31
retrieving revision 1.235.4.32
diff -u -p -r1.235.4.31 -r1.235.4.32
--- src/cvs.h 2 May 2005 17:06:56 -0000 1.235.4.31
+++ src/cvs.h 27 May 2005 16:25:10 -0000 1.235.4.32
@@ -431,14 +431,16 @@ int RCS_merge PROTO((RCSNode *, const ch
#define RCS_FLAGS_KEEPFILE 16
#define RCS_FLAGS_USETIME 32
-extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile,
- const char *opts, const char *options,
+extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile, int diff_argc,
+ char *const *diff_argv,
+ const char *options,
const char *rev1, const char *rev1_cache,
const char *rev2, const char *label1,
const char *label2, const char *workfile));
extern int diff_exec PROTO ((const char *file1, const char *file2,
const char *label1, const char *label2,
- const char *options, const char *out));
+ int diff_argc, char *const *diff_argv,
+ const char *out));
#include "error.h"
@@ -696,6 +698,8 @@ void sleep_past PROTO ((time_t desttime)
#define RUN_SIGIGNORE 0x0010 /* ignore interrupts for
command */
#define RUN_TTY (char *)0 /* for the benefit of lint */
+void run_add_arg_p PROTO ((int *, size_t *, char ***, const char *s));
+void run_arg_free_p PROTO ((int, char **));
void run_arg PROTO((const char *s));
void run_print PROTO((FILE * fp));
void run_setup PROTO ((const char *prog));
Index: src/diff.c
===================================================================
RCS file: /cvs/ccvs/src/diff.c,v
retrieving revision 1.94.2.9
retrieving revision 1.94.2.10
diff -u -p -r1.94.2.9 -r1.94.2.10
--- src/diff.c 31 Jan 2005 22:15:11 -0000 1.94.2.9
+++ src/diff.c 27 May 2005 16:25:11 -0000 1.94.2.10
@@ -65,8 +65,9 @@ static int have_rev1_label, have_rev2_la
static char *user_file_rev;
static char *options;
-static char *opts;
-static size_t opts_allocated = 1;
+static char **diff_argv;
+static int diff_argc;
+static size_t diff_arg_allocated;
static int diff_errors;
static int empty_files = 0;
@@ -211,6 +212,54 @@ static struct option const longopts[] =
{0, 0, 0, 0}
};
+
+
+/* Add one of OPT or LONGOPT, and ARGUMENT, when present, to global DIFF_ARGV.
+ *
+ * INPUTS
+ * opt A character option representation.
+ * longopt A long option name.
+ * argument Optional option argument.
+ *
+ * GLOBALS
+ * diff_argc The number of arguments in DIFF_ARGV.
+ * diff_argv Array of argument strings.
+ * diff_arg_allocated Allocated length of DIFF_ARGV.
+ *
+ * NOTES
+ * Behavior when both OPT & LONGOPT are provided is undefined.
+ *
+ * RETURNS
+ * Nothing.
+ */
+static void
+add_diff_args (char opt, const char *longopt, const char *argument)
+{
+ char *tmp;
+
+ /* Add opt or longopt to diff_arv. */
+ assert (opt || (longopt && *longopt));
+ assert (!(opt && (longopt && *longopt)));
+ if (opt)
+ {
+ tmp = xmalloc (3);
+ sprintf (tmp, "-%c", opt);
+ }
+ else
+ {
+ tmp = xmalloc (3 + strlen (longopt));
+ sprintf (tmp, "--%s", longopt);
+ }
+ run_add_arg_p (&diff_argc, &diff_arg_allocated, &diff_argv, tmp);
+ free (tmp);
+
+ /* When present, add ARGUMENT to DIFF_ARGV. */
+ if (argument)
+ run_add_arg_p (&diff_argc, &diff_arg_allocated, &diff_argv, argument);
+}
+
+
+
/* CVS 1.9 and similar versions seemed to have pretty weird handling
of -y and -T. In the cases where it called rcsdiff,
they would have the meanings mentioned below. In the cases where it
@@ -247,7 +296,6 @@ diff (argc, argv)
int argc;
char **argv;
{
- char tmp[50];
int c, err = 0;
int local = 0;
int which;
@@ -267,12 +315,11 @@ diff (argc, argv)
/* Clean out our global variables (multiroot can call us multiple
times and the server can too, if the client sends several
diff commands). */
- if (opts == NULL)
+ if (diff_argc)
{
- opts_allocated = 1;
- opts = xmalloc (opts_allocated);
+ run_arg_free_p (diff_argc, diff_argv);
+ diff_argc = 0;
}
- opts[0] = '\0';
diff_rev1 = NULL;
diff_rev2 = NULL;
diff_date1 = NULL;
@@ -293,7 +340,7 @@ diff (argc, argv)
switch (c)
{
case 'y':
- xrealloc_and_strcat (&opts, &opts_allocated, " --side-by-side");
+ add_diff_args (0, "side-by-side", NULL);
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'i': case 'n': case 'p': case 's': case 't':
@@ -301,8 +348,7 @@ diff (argc, argv)
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
case 'B': case 'H': case 'T':
- (void) sprintf (tmp, " -%c", (char) c);
- xrealloc_and_strcat (&opts, &opts_allocated, tmp);
+ add_diff_args (c, NULL, NULL);
break;
case 'L':
if (have_rev1_label++)
@@ -311,33 +357,15 @@ diff (argc, argv)
error (0, 0, "extra -L arguments ignored");
break;
}
-
- xrealloc_and_strcat (&opts, &opts_allocated, " -L");
- xrealloc_and_strcat (&opts, &opts_allocated, optarg);
- break;
+ /* Fall through. */
case 'C': case 'F': case 'I': case 'U': case 'W':
- (void) sprintf (tmp, " -%c", (char) c);
- xrealloc_and_strcat (&opts, &opts_allocated, tmp);
- xrealloc_and_strcat (&opts, &opts_allocated, optarg);
+ add_diff_args (c, NULL, optarg);
break;
- case 131:
- /* --ifdef. */
- xrealloc_and_strcat (&opts, &opts_allocated, " --ifdef=");
- xrealloc_and_strcat (&opts, &opts_allocated, optarg);
- break;
- case 129: case 130: case 132: case 133: case 134:
+ case 129: case 130: case 131: case 132: case 133: case 134:
case 135: case 136: case 137: case 138: case 139: case 140:
case 141: case 142: case 143: case 145: case 146:
- xrealloc_and_strcat (&opts, &opts_allocated, " --");
- xrealloc_and_strcat (&opts, &opts_allocated,
- longopts[option_index].name);
- if (longopts[option_index].has_arg == 1
- || (longopts[option_index].has_arg == 2
- && optarg != NULL))
- {
- xrealloc_and_strcat (&opts, &opts_allocated, "=");
- xrealloc_and_strcat (&opts, &opts_allocated, optarg);
- }
+ add_diff_args (0, longopts[option_index].name,
+ longopts[option_index].has_arg ? optarg : NULL);
break;
case 'R':
local = 0;
@@ -395,7 +423,7 @@ diff (argc, argv)
send_arg("-l");
if (empty_files)
send_arg("-N");
- send_option_string (opts);
+ send_options (diff_argc, diff_argv);
if (options[0] != '\0')
send_arg (options);
if (diff_rev1)
@@ -705,8 +733,8 @@ RCS file: ", 0);
if (empty_file == DIFF_ADDED)
{
if (use_rev2 == NULL)
- status = diff_exec (DEVNULL, finfo->file, label1, label2, opts,
- RUN_TTY);
+ status = diff_exec (DEVNULL, finfo->file, label1, label2,
+ diff_argc, diff_argv, RUN_TTY);
else
{
int retcode;
@@ -722,7 +750,8 @@ RCS file: ", 0);
if( retcode != 0 )
goto out;
- status = diff_exec (DEVNULL, tmp, label1, label2, opts,
RUN_TTY);
+ status = diff_exec (DEVNULL, tmp, label1, label2,
+ diff_argc, diff_argv, RUN_TTY);
}
}
else
@@ -738,16 +767,16 @@ RCS file: ", 0);
if (retcode != 0)
goto out;
- status = diff_exec (tmp, DEVNULL, label1, label2, opts, RUN_TTY);
+ status = diff_exec (tmp, DEVNULL, label1, label2,
+ diff_argc, diff_argv, RUN_TTY);
}
}
else
{
- status = RCS_exec_rcsdiff(vers->srcfile, opts,
- *options ? options : vers->options,
- use_rev1, rev1_cache, use_rev2,
- label1, label2,
- finfo->file);
+ status = RCS_exec_rcsdiff (vers->srcfile, diff_argc, diff_argv,
+ *options ? options : vers->options,
+ use_rev1, rev1_cache, use_rev2,
+ label1, label2, finfo->file);
}
Index: src/patch.c
===================================================================
RCS file: /cvs/ccvs/src/patch.c,v
retrieving revision 1.80.4.11
retrieving revision 1.80.4.12
diff -u -p -r1.80.4.11 -r1.80.4.12
--- src/patch.c 18 Apr 2005 17:36:45 -0000 1.80.4.11
+++ src/patch.c 27 May 2005 16:25:11 -0000 1.80.4.12
@@ -406,6 +406,9 @@ patch_fileproc (callerdat, finfo)
char *cp1, *cp2;
FILE *fp;
int line_length;
+ int dargc = 0;
+ size_t darg_allocated = 0;
+ char **dargv = NULL;
line1 = NULL;
line1_chars_allocated = 0;
@@ -585,8 +588,10 @@ patch_fileproc (callerdat, finfo)
(void)utime (tmpfile2, &t);
}
- switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, unidiff ? "-u" : "-c",
- tmpfile3))
+ if (unidiff) run_add_arg_p (&dargc, &darg_allocated, &dargv, "-u");
+ else run_add_arg_p (&dargc, &darg_allocated, &dargv, "-c");
+ switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, dargc, dargv,
+ tmpfile3))
{
case -1: /* fork/wait failure */
error (1, errno, "fork for diff failed on %s", rcs);
@@ -758,6 +763,11 @@ failed to read diff file header %s for %
free (tmpfile2);
free (tmpfile3);
tmpfile1 = tmpfile2 = tmpfile3 = NULL;
+ if (dargc)
+ {
+ run_arg_free_p (dargc, dargv);
+ free (dargv);
+ }
out2:
if (vers_tag != NULL)
Index: src/rcs.c
===================================================================
RCS file: /cvs/ccvs/src/rcs.c,v
retrieving revision 1.262.4.37
retrieving revision 1.262.4.38
diff -u -p -r1.262.4.37 -r1.262.4.38
--- src/rcs.c 20 Apr 2005 20:40:42 -0000 1.262.4.37
+++ src/rcs.c 27 May 2005 16:25:11 -0000 1.262.4.38
@@ -5049,7 +5049,9 @@ RCS_checkin (rcs, workfile_in, message,
Deltatext *dtext;
Node *nodep;
char *tmpfile, *changefile;
- char *diffopts;
+ int dargc = 0;
+ size_t darg_allocated = 0;
+ char **dargv = NULL;
size_t bufsize;
int status, checkin_quiet;
struct tm *ftm;
@@ -5478,9 +5480,10 @@ workfile);
/* Diff options should include --binary if the RCS file has -kb set
in its `expand' field. */
- diffopts = (rcs->expand != NULL && STREQ (rcs->expand, "b")
- ? "-a -n --binary"
- : "-a -n");
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-a");
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-n");
+ if (rcs->expand && STREQ (rcs->expand, "b"))
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "--binary");
if (STREQ (commitpt->version, rcs->head) &&
numdots (delta->version) == 1)
@@ -5503,7 +5506,8 @@ workfile);
memset (commitpt->text, 0, sizeof (Deltatext));
bufsize = 0;
- switch (diff_exec (workfile, tmpfile, NULL, NULL, diffopts, changefile))
+ switch (diff_exec (workfile, tmpfile, NULL, NULL,
+ dargc, dargv, changefile))
{
case 0:
case 1:
@@ -5551,7 +5555,8 @@ workfile);
/* This file is not being inserted at the head, but on a side
branch somewhere. Make a diff from the previous revision
to the working file. */
- switch (diff_exec (tmpfile, workfile, NULL, NULL, diffopts, changefile))
+ switch (diff_exec (tmpfile, workfile, NULL, NULL,
+ dargc, dargv, changefile))
{
case 0:
case 1:
@@ -5578,6 +5583,9 @@ workfile);
}
}
+ run_arg_free_p (dargc, dargv);
+ free (dargv);
+
/* Update DELTA linkage. It is important not to do this before
the very end of RCS_checkin; if an error arises that forces
us to abort checking in, we must not have malformed deltas
@@ -6651,6 +6659,10 @@ RCS_delete_revs (rcs, tag1, tag2, inclus
}
else
{
+ int dargc = 0;
+ size_t darg_allocated = 0;
+ char **dargv = NULL;
+
beforefile = cvs_temp_name();
status = RCS_checkout (rcs, NULL, before, NULL, "-ko", beforefile,
(RCSCHECKOUTPROC)0, NULL);
@@ -6658,7 +6670,12 @@ RCS_delete_revs (rcs, tag1, tag2, inclus
goto delrev_done;
outfile = cvs_temp_name();
- status = diff_exec (beforefile, afterfile, NULL, NULL, "-an",
outfile);
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-a");
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-n");
+ status = diff_exec (beforefile, afterfile, NULL, NULL,
+ dargc, dargv, outfile);
+ run_arg_free_p (dargc, dargv);
+ free (dargv);
if (status == 2)
{
Index: src/rcscmds.c
===================================================================
RCS file: /cvs/ccvs/src/rcscmds.c,v
retrieving revision 1.52.4.5
retrieving revision 1.52.4.6
diff -u -p -r1.52.4.5 -r1.52.4.6
--- src/rcscmds.c 16 Mar 2005 22:00:45 -0000 1.52.4.5
+++ src/rcscmds.c 27 May 2005 16:25:11 -0000 1.52.4.6
@@ -56,8 +56,8 @@
On a related note, see the comments at diff_exec, later in this file,
for more on the diff library. */
-static void RCS_output_diff_options PROTO ((const char *, const char *,
- const char *, const char *));
+static void RCS_output_diff_options PROTO ((int, char *const *, const char *,
+ const char *, const char *));
/* Stuff to deal with passing arguments the way libdiff.a wants to deal
@@ -69,7 +69,7 @@ static void RCS_output_diff_options PROT
argument will be parsed into whitespace separated words and added
to the global call_diff_argv list.
- Then, optionally, call call_diff_arg for each additional argument
+ Then, optionally, call call_diff_add_arg for each additional argument
that you'd like to pass to the diff library.
Finally, call call_diff or call_diff3 to produce the diffs. */
@@ -79,7 +79,8 @@ static int call_diff_argc;
static int call_diff_argc_allocated;
static void call_diff_add_arg PROTO ((const char *));
-static void call_diff_setup PROTO ((const char *prog));
+static void call_diff_setup PROTO ((const char *prog,
+ int argc, char * const *argv));
static int call_diff PROTO ((const char *out));
static int call_diff3 PROTO ((char *out));
@@ -88,62 +89,37 @@ static void call_diff_flush_output PROTO
static void call_diff_write_stdout PROTO((const char *));
static void call_diff_error PROTO((const char *, const char *, const char *));
+
+
+static void
+call_diff_add_arg (s)
+ const char *s;
+{
+ run_add_arg_p (&call_diff_argc, &call_diff_argc_allocated, &call_diff_argv,
+ s);
+}
+
+
+
/* VARARGS */
static void
-call_diff_setup (prog)
+call_diff_setup (prog, argc, argv)
const char *prog;
+ int argc;
+ char * const *argv;
{
- char *cp;
int i;
- char *call_diff_prog;
/* clean out any malloc'ed values from call_diff_argv */
- for (i = 0; i < call_diff_argc; i++)
- {
- if (call_diff_argv[i])
- {
- free (call_diff_argv[i]);
- call_diff_argv[i] = (char *) 0;
- }
- }
+ run_arg_free_p (call_diff_argc, call_diff_argv);
call_diff_argc = 0;
- call_diff_prog = xstrdup (prog);
-
/* put each word into call_diff_argv, allocating it as we go */
- for (cp = strtok (call_diff_prog, " \t");
- cp != NULL;
- cp = strtok ((char *) NULL, " \t"))
- call_diff_add_arg (cp);
- free (call_diff_prog);
-}
-
-static void
-call_diff_arg (s)
- const char *s;
-{
- call_diff_add_arg (s);
+ call_diff_add_arg (prog);
+ for (i = 0; i < argc; i++)
+ call_diff_add_arg (argv[i]);
}
-static void
-call_diff_add_arg (s)
- const char *s;
-{
- /* allocate more argv entries if we've run out */
- if (call_diff_argc >= call_diff_argc_allocated)
- {
- call_diff_argc_allocated += 50;
- call_diff_argv = (char **)
- xrealloc ((char *) call_diff_argv,
- call_diff_argc_allocated * sizeof (char **));
- }
-
- if (s)
- call_diff_argv[call_diff_argc++] = xstrdup (s);
- else
- /* Not post-incremented on purpose! */
- call_diff_argv[call_diff_argc] = (char *) 0;
-}
/* Callback function for the diff library to write data to the output
file. This is used when we are producing output to stdout. */
@@ -216,6 +192,8 @@ static int
call_diff (out)
const char *out;
{
+ call_diff_add_arg (NULL);
+
if (out == RUN_TTY)
return diff_run (call_diff_argc, call_diff_argv, NULL,
&call_diff_stdout_callbacks);
@@ -308,21 +286,21 @@ RCS_merge(rcs, path, workfile, options,
/* Remember that the first word in the `call_diff_setup' string is used now
only for diagnostic messages -- CVS no longer forks to run diff3. */
diffout = cvs_temp_name();
- call_diff_setup ("diff3");
- call_diff_arg ("-E");
- call_diff_arg ("-am");
-
- call_diff_arg ("-L");
- call_diff_arg (workfile);
- call_diff_arg ("-L");
- call_diff_arg (xrev1);
- call_diff_arg ("-L");
- call_diff_arg (xrev2);
-
- call_diff_arg ("--");
- call_diff_arg (workfile);
- call_diff_arg (tmp1);
- call_diff_arg (tmp2);
+ call_diff_setup ("diff3", 0, NULL);
+ call_diff_add_arg ("-E");
+ call_diff_add_arg ("-am");
+
+ call_diff_add_arg ("-L");
+ call_diff_add_arg (workfile);
+ call_diff_add_arg ("-L");
+ call_diff_add_arg (xrev1);
+ call_diff_add_arg ("-L");
+ call_diff_add_arg (xrev2);
+
+ call_diff_add_arg ("--");
+ call_diff_add_arg (workfile);
+ call_diff_add_arg (tmp1);
+ call_diff_add_arg (tmp2);
retval = call_diff3 (diffout);
@@ -388,10 +366,11 @@ RCS_merge(rcs, path, workfile, options,
about this--any such features are undocumented in the context of
CVS, and I'm not sure how important to users. */
int
-RCS_exec_rcsdiff(rcsfile, opts, options, rev1, rev1_cache, rev2,
- label1, label2, workfile )
+RCS_exec_rcsdiff (rcsfile, diff_argc, diff_argv, options, rev1, rev1_cache,
+ rev2, label1, label2, workfile)
RCSNode *rcsfile;
- const char *opts;
+ int diff_argc;
+ char * const *diff_argv;
const char *options;
const char *rev1;
const char *rev1_cache;
@@ -471,8 +450,9 @@ RCS file: ", 0);
use_file2 = tmpfile2;
}
- RCS_output_diff_options (opts, rev1, rev2, workfile);
- status = diff_exec( use_file1, use_file2, label1, label2, opts, RUN_TTY );
+ RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile);
+ status = diff_exec (use_file1, use_file2, label1, label2,
+ diff_argc, diff_argv, RUN_TTY);
if (status >= 0)
{
retval = status;
@@ -551,16 +531,15 @@ RCS file: ", 0);
message on stderr. */
int
-diff_exec (file1, file2, label1, label2, options, out)
+diff_exec (file1, file2, label1, label2, dargc, dargv, out)
const char *file1;
const char *file2;
const char *label1;
const char *label2;
- const char *options;
+ int dargc;
+ char * const *dargv;
const char *out;
{
- char *args;
-
#ifdef PRESERVE_PERMISSIONS_SUPPORT
/* If either file1 or file2 are special files, pretend they are
/dev/null. Reason: suppose a file that represents a block
@@ -594,18 +573,15 @@ diff_exec (file1, file2, label1, label2,
}
#endif
- args = xmalloc (strlen (options) + 10);
- /* The first word in this string is used only for error reporting. */
- sprintf (args, "diff %s", options);
- call_diff_setup (args);
+ /* The first arg to call_diff_setup is used only for error reporting. */
+ call_diff_setup ("diff", dargc, dargv);
if (label1)
- call_diff_arg (label1);
+ call_diff_add_arg (label1);
if (label2)
- call_diff_arg (label2);
- call_diff_arg ("--");
- call_diff_arg (file1);
- call_diff_arg (file2);
- free (args);
+ call_diff_add_arg (label2);
+ call_diff_add_arg ("--");
+ call_diff_add_arg (file1);
+ call_diff_add_arg (file2);
return call_diff (out);
}
@@ -617,19 +593,23 @@ diff_exec (file1, file2, label1, label2,
that I have seen. */
static void
-RCS_output_diff_options (opts, rev1, rev2, workfile)
- const char *opts;
+RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile)
+ int diff_argc;
+ char * const *diff_argv;
const char *rev1;
const char *rev2;
const char *workfile;
{
- char *tmp;
-
- tmp = (char *) xmalloc (strlen (opts) + strlen (rev1) + 10);
-
- sprintf (tmp, "diff%s -r%s", opts, rev1);
- cvs_output (tmp, 0);
- free (tmp);
+ int i;
+
+ cvs_output ("diff", 0);
+ for (i = 0; i < diff_argc; i++)
+ {
+ cvs_output (" ", 1);
+ cvs_output (diff_argv[i], 0);
+ }
+ cvs_output (" -r", 3);
+ cvs_output (rev1, 0);
if (rev2)
{
Index: src/run.c
===================================================================
RCS file: /cvs/ccvs/src/run.c,v
retrieving revision 1.33.6.3
retrieving revision 1.33.6.4
diff -u -p -r1.33.6.3 -r1.33.6.4
--- src/run.c 1 Apr 2004 19:07:51 -0000 1.33.6.3
+++ src/run.c 27 May 2005 16:25:11 -0000 1.33.6.4
@@ -36,7 +36,19 @@ extern char *strtok ();
*/
static char **run_argv;
static int run_argc;
-static int run_argc_allocated;
+static size_t run_argc_allocated;
+
+
+
+void
+run_arg_free_p (int argc, char **argv)
+{
+ int i;
+ for (i = 0; i < argc; i++)
+ free (argv[i]);
+}
+
+
/* VARARGS */
void
@@ -44,18 +56,10 @@ run_setup (prog)
const char *prog;
{
char *cp;
- int i;
char *run_prog;
/* clean out any malloc'ed values from run_argv */
- for (i = 0; i < run_argc; i++)
- {
- if (run_argv[i])
- {
- free (run_argv[i]);
- run_argv[i] = (char *) 0;
- }
- }
+ run_arg_free_p (run_argc, run_argv);
run_argc = 0;
run_prog = xstrdup (prog);
@@ -73,22 +77,35 @@ run_arg (s)
run_add_arg (s);
}
-static void
-run_add_arg (s)
+
+
+void
+run_add_arg_p (iargc, iarg_allocated, iargv, s)
+ int *iargc;
+ size_t *iarg_allocated;
+ char ***iargv;
const char *s;
{
/* allocate more argv entries if we've run out */
- if (run_argc >= run_argc_allocated)
+ if (*iargc >= *iarg_allocated)
{
- run_argc_allocated += 50;
- run_argv = (char **) xrealloc ((char *) run_argv,
- run_argc_allocated * sizeof (char **));
+ *iarg_allocated += 50;
+ *iargv = xrealloc (*iargv, *iarg_allocated * sizeof (char **));
}
if (s)
- run_argv[run_argc++] = xstrdup (s);
+ (*iargv)[(*iargc)++] = xstrdup (s);
else
- run_argv[run_argc] = (char *) 0; /* not post-incremented on
purpose! */
+ (*iargv)[*iargc] = NULL; /* not post-incremented on purpose! */
+}
+
+
+
+static void
+run_add_arg (s)
+ const char *s;
+{
+ run_add_arg_p (&run_argc, &run_argc_allocated, &run_argv, s);
}
Index: src/sanity.sh
===================================================================
RCS file: /cvs/ccvs/src/sanity.sh,v
retrieving revision 1.752.2.170
retrieving revision 1.752.2.171
diff -u -p -r1.752.2.170 -r1.752.2.171
--- src/sanity.sh 2 May 2005 17:06:56 -0000 1.752.2.170
+++ src/sanity.sh 27 May 2005 16:25:11 -0000 1.752.2.171
@@ -2204,7 +2204,7 @@ ${PLUS} ssfile line 2"
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
retrieving revision 1\.1
-diff -c -C3isacrowd -r1\.1 ssfile
+diff -c -C 3isacrowd -r1\.1 ssfile
${PROG} diff: invalid context length argument"
dotest basica-7 "${testcvs} -q ci -m modify-it" \
"Checking in sdir/ssdir/ssfile;
@@ -4813,7 +4813,7 @@ done"
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
retrieving revision 1\.2
-diff --ifdef=HAVE_WINSOCK_H -r1\.2 abc
+diff --ifdef HAVE_WINSOCK_H -r1\.2 abc
#ifndef HAVE_WINSOCK_H
extern int gethostname ();
#else /\* HAVE_WINSOCK_H \*/
@@ -7623,12 +7623,12 @@ mumble;
}
EOF
# Use dotest_fail because exit status from `cvs diff' must be 1.
- dotest_fail rcslib-diffrgx-3 "${testcvs} diff -c -F'.*(' rgx.c" \
+ dotest_fail rcslib-diffrgx-3 "${testcvs} diff -c -F'.* (' rgx.c" \
"Index: rgx\.c
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/rgx\.c,v
retrieving revision 1\.1
-diff -c -F\.\*( -r1\.1 rgx\.c
+diff -c -F \.\* ( -r1\.1 rgx\.c
\*\*\* rgx\.c ${RFCDATE} 1\.1
--- rgx\.c ${RFCDATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* test_regex (whiz, bang)
Index: src/update.c
===================================================================
RCS file: /cvs/ccvs/src/update.c,v
retrieving revision 1.202.4.24
retrieving revision 1.202.4.25
diff -u -p -r1.202.4.24 -r1.202.4.25
--- src/update.c 16 Mar 2005 22:00:45 -0000 1.202.4.24
+++ src/update.c 27 May 2005 16:25:14 -0000 1.202.4.25
@@ -1724,7 +1724,9 @@ patch_file (finfo, vers_ts, docheckout,
retcode = 0;
if (! fail)
{
- char *diff_options;
+ int dargc = 0;
+ size_t darg_allocated = 0;
+ char **dargv = NULL;
/* If the client does not support the Rcs-diff command, we
send a context diff, and the client must invoke patch.
@@ -1732,16 +1734,13 @@ patch_file (finfo, vers_ts, docheckout,
new approach only requires running diff in the server; the
client can handle everything without invoking an external
program. */
- if (! rcs_diff_patches)
- {
+ if (!rcs_diff_patches)
/* We use -c, not -u, because that is what CVS has
traditionally used. Kind of a moot point, now that
Rcs-diff is preferred, so there is no point in making
the compatibility issues worse. */
- diff_options = "-c";
- }
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-c");
else
- {
/* Now that diff is librarified, we could be passing -a if
we wanted to. However, it is unclear to me whether we
would want to. Does diff -a, in any significant
@@ -1751,10 +1750,11 @@ patch_file (finfo, vers_ts, docheckout,
'binary'. Conversely, do they tend to be much larger
in the bad cases? This needs some more
thought/investigation, I suspect. */
-
- diff_options = "-n";
- }
- retcode = diff_exec (file1, file2, NULL, NULL, diff_options,
finfo->file);
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-n");
+ retcode = diff_exec (file1, file2, NULL, NULL, dargc, dargv,
+ finfo->file);
+ run_arg_free_p (dargc, dargv);
+ free (dargv);
/* A retcode of 0 means no differences. 1 means some differences. */
if (retcode != 0
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Patch to protect spaces in diff arguments.,
Derek Price <=