Mail Archives: cygwin/2012/03/27/04:12:17
Csaba Raduly skrev 2012-03-27 09:37:
> On Mon, Mar 26, 2012 at 9:29 PM, Richard Gribble wrote:
>> Using rcs 5.8-1:
>>
>> Synopsis:
>> Given two mark symbols, abc (version 1.1) and abcd (version 1.2),
>> executing "co -rabc <file>" will check out version 1.2, when it
>> should check out version 1.1.
>>
>> I set the mark symbols as follows:
>> rcs -nabc:1.1 -nabcd:1.2 <file>
>>
>>
>> I dug into it, and found the following (rcsrev.c):
>>
>> 01: static char const *
>> 02: rev_from_symbol (struct cbuf const *id)
>> 03: /* Look up "id" in the list of symbolic names starting with pointer
>> 04: "GROK (symbols)", and return a pointer to the corresponding
>> 05: revision number. Return NULL if not present. */
>> 06: {
>> 07: for (struct link *ls = GROK (symbols); ls; ls = ls->next)
>> 08: {
>> 09: struct symdef const *d = ls->entry;
>> 10:
>> 11: if (!strncmp (d->meaningful, id->string, id->size))
>> 12: return d->underlying;
>> 13: }
>> 14: return NULL;
>> 15: }
>>
>> Note that line 11 tests the name of the requested mark symbol
>> (id->string) against each element of a linked-list (ls) containing all
>> the mark symbols for the file. The problem is that it will only test
>> the first 'id->size' characters - so R25 (from the command line) matches
>> R25a (from the list) because the first three characters match and it
>> won't test any more than that (strncmp).
>>
>> I recommend modifying line 11 as follows:
>> if ((strlen(d->meaningful) == strlen(id->size)) && !strncmp
>> (d->meaningful, id->string, id->size))
>
> I think strlen(id->size) is overkill :)
>
> If both strings (d->meaningful and id->string) are NULL-terminated ,
> then a simple call to strlen would do the job:
You mean a simple call to strcmp here.
> if (!strcmp(d->meaningful, id->string))
>
> It would do the right thing w.r.t. different lengths.
>
>> Of course, since you now know that the two strings are the same size,
>> you could use strcmp - but that assumes that the && short-circuits, and
>> I don't know if that's guaranteed.
>
> Yes, it required by the C standard.
But...careful! You have to assume that the original authors were not
idiots! Maybe the obvious strcmp was not used for a *good* reason? I
can't tell if d->meaningful is guaranteed to be zero-terminated from the
limited context, but it sure is suspect. Assuming that the original
authors were not idiots but instead made an off-by one error missing a
corner-case, the safer approach is to replace line 11 with:
11: if (!strncmp (d->meaningful, id->string, id->size + 1))
That is, if id->string is guaranteed to be zero-terminated, which is
not clear either, but perhaps easier to verify...
Cheers,
Peter
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -