A bug in perl3. With a fix.
Michael Greim
greim at sbsvax.UUCP
Tue Sep 12 22:35:21 AEST 1989
Here's a bug report for perl3 and a fix for the bug.
This is only ment as an unofficial "quick fix".
I sent this report to Larry Wall too, who will probably include a bug fix of
his own in one of his next suit of patches.
A Bug in perl3.
Priority : medium
Symptoms:
perl failed the test in base.term.
The test
$x = "\n";
if ($x lt ' ') {print "ok 1\n";} else {print "not ok 1\n";}
said "not ok 1".
With the debug flag turned on, one sees that the result of
the comparison "$s lt ' '" yields false.
Diagnosis:
In several places bcmp is used. At least in one place, viz. the
evaluation of the result of the O_SLT operator, the code relies
on bcmp to return a value
- less 0 if str1 < str2
- 0 if str1 == str2
- greater 0 if str1 > str2
To cite the 4BSD manual page:
bcmp(b1, b2, length)
char *b1, *b2;
int length;
``bcmp compares sbyte string b1 against byte string b2, returning
zero if they are identical, nonzero otherwise. Both strings are
assumed to be length bytes long.''
The code for O_SLT operator in eval.c:
case O_SLT:
tmps = str_get(st[1]);
value = (double) (str_cmp(st[1],st[2]) < 0);
goto donumset;
In routine str_cmp in str.c:
if (str1->str_cur < str2->str_cur) {
--> if (retval = bcmp(str1->str_ptr, str2->str_ptr, str1->str_cur))
return retval;
else
return 1;
}
--> else if (retval = bcmp(str1->str_ptr, str2->str_ptr, str2->str_cur))
return retval;
else if (str1->str_cur == str2->str_cur)
return 0;
else
return -1;
The return of bcmp is returned as the result of str_cmp and tested
if it is less than 0. Unfortunately according to the man page it is not
guaranteed that the result of bcmp will be less than 0 .
Therapy:
The best would be to examine the code for occurances of bcmp and
rewrite it as necessary.
A quick fix is to include a "handmade" bcmp. Here it is:
------ cut here ----------
bcmp (s1, s2, n)
register unsigned char * s1;
register unsigned char * s2;
register int n;
/*
* If bcmp returns always a number > 0 if s1 is not identical to s2 one
* has to include this bcmp.
*
* Here is one which returns a number < 0 if s1 < s2 and a number > 0 if
* s1 > s2.
* ("unsigned char" to get subtraction correct)
*/
{
while (n--) {
if (*s1 != *s2)
return ((int)(*s1 - *s2));
s1++;
s2++;
}
return (0);
}
------ cut here ----------
Absorb, apply and enjoy,
-mg
--
Michael Greim Email : greim at sbsvax.informatik.uni-saarland.dbp.de
or : ...!uunet!unido!sbsvax!greim
[.signature removed by the board of censors for electronic mail's main
executive computer because it contained a four letter word ("word")]
More information about the Comp.sources.bugs
mailing list