>Submitter-Id: net
>Originator: Craig Metz
>Organization: net
>Confidential: no
>Synopsis: Segfault on checkout if RCS log is empty
>Severity: serious
>Priority: medium
>Category: CVS
>Class: sw-bug
>Release: cvs-1.10.8
>Environment: Doesn't appear to matter
System: Linux ministry-of-love 2.2.16 #13 Fri Jul 7 00:48:58 EDT 2000 i686 unknown
Architecture: i686
>Description:
I have a source tree built with a slightly hacked RCS.
If I point CVS 1.10.8 at the resulting source tree, CVS will core dump during
the checkout.
If I point a flavor of CVS 1.9 that used RCS as its back-end at the same
files, the checkout works fine. Ditto with using RCS by hand on these files.
A very quick look at the problem shows that the segfault is happenning inside
the strcmp() inside expand_keywords. log is NULL, ergo segfault when you
strcmp() it to a string.
A quick look at the RCS file shows this interesting tidbit:
1.12
log
@@
text
@#
If I change this to:
1.12
log
@foo@
text
@#
No segfault.
>How-To-Repeat:
ministry-of-love$ echo '$Log$' >foo
ministry-of-love$ echo | ci -mx foo
foo,v <-- foo
initial revision: 1.1
done
ministry-of-love$ mv foo,v foo,v~
ministry-of-love$ cat foo,v~ | perl -e 'L1: while(<>) { /^\@x$/ && do { print "@@\n";
$i = 1; next L1; }; $i && do { $i = 0; next L1; }; print; };' > foo,v
ministry-of-love$ co foo,v
foo,v --> foo
revision 1.1
done
ministry-of-love$ mkdir cvs
ministry-of-love$ export CVSROOT=`pwd`/cvs
ministry-of-love$ cvs init
cvs init: notice: main loop with CVSROOT=/tmp/test/cvs
-> checkout (modules,v, , , .#12713)
-> unlink(.#modules)
-> unlink(.#12713)
-> checkout (loginfo,v, , , .#12714)
-> unlink(.#loginfo)
-> unlink(.#12714)
-> checkout (rcsinfo,v, , , .#12715)
-> unlink(.#rcsinfo)
-> unlink(.#12715)
-> checkout (editinfo,v, , , .#12716)
-> unlink(.#editinfo)
-> unlink(.#12716)
-> checkout (verifymsg,v, , , .#12717)
-> unlink(.#verifymsg)
-> unlink(.#12717)
-> checkout (commitinfo,v, , , .#12718)
-> unlink(.#commitinfo)
-> unlink(.#12718)
-> checkout (taginfo,v, , , .#12719)
-> unlink(.#taginfo)
-> unlink(.#12719)
-> unlink(.#12720)
-> checkout (checkoutlist,v, , , .#12721)
-> unlink(.#checkoutlist)
-> unlink(.#12721)
-> checkout (cvswrappers,v, , , .#12722)
-> unlink(.#cvswrappers)
-> unlink(.#12722)
-> checkout (notify,v, , , .#12723)
-> unlink(.#notify)
-> unlink(.#12723)
-> unlink(.#12724)
-> unlink(.#12725)
-> checkout (config,v, , , .#12726)
-> unlink(.#config)
-> unlink(.#12726)
ministry-of-love$ cp foo,v cvs
ministry-of-love$ cvs co .
cvs checkout: notice: main loop with CVSROOT=/tmp/test/cvs
-> do_module (., Updating, , )
-> Create_Admin (., ., /tmp/test/cvs, , , 0, 0)
-> unlink(./CVS/Tag)
<- Create_Admin
-> fopen(/tmp/test/cvs/CVSROOT/history,a)
-> unlink(./CVS/Entries.Static)
cvs checkout: Updating .
-> checkout (/tmp/test/cvs/foo,v, , , (function))
Segmentation fault
>Fix:
The kluge I used was to force log to be non-NULL, and I gave it a nice
red-flag value that turns out not to actually show up in the output.
--- cvs-1.10.8/src/rcs.c Wed Jan 5 11:35:46 2000
+++ cvs-1.10.8/src/rcs.c Fri Aug 11 02:39:10 2000
@@ -3864,6 +3864,9 @@
char *srch, *srch_next;
size_t srch_len;
+ if (log == NULL)
+ log = "XXX - Log missing due to internal CVS error - XXX";
+
if (expand == KFLAG_O || expand == KFLAG_B)
{
*retbuf = buf;
ministry-of-love$ rm foo
ministry-of-love$ /usr/src/cvs-1.10.8/src/cvs co .
cvs checkout: Updating .
U foo
? foo,v
? cvs
cvs checkout: Updating CVSROOT
ministry-of-love$ cat foo
$Log: foo,v $
Revision 1.1 2000/08/11 07:19:12 cmetz