[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#635885: libc6: strchr() behavior changed



Package: libc6
Version: 2.11.2-10

strchr(3) doesn't return correct value on certain input. Here is a test
case that describes the problem:

	$ cat test_strchr.c
	#include <stdlib.h>
	#include <stdio.h>
	#include <string.h>

	void my_strchr(const char *s, int c)
	{
	        char *r = strchr(s, c);
	        printf("strchr(%d [%d]) = [%d]\n",
	                        (int) (unsigned char) c, c,
        	                (int) (unsigned char) (r ? *r : 0));
	}

	int main()
	{
	        static const char s[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0};

	        char ch = 228;
	        int d = 228;

        	my_strchr(s, ch);
	        my_strchr(s, (int) ch);
	        my_strchr(s, (unsigned int) ch);
	        my_strchr(s, (unsigned char) ch);
	        my_strchr(s, d);

        	return 0;
	}

When running this application on Debian with libc6 2.7-18lenny2 and on my
Gentoo machine I get:

	$ ./test_strchr
	strchr(228 [-28]) = [0]
	strchr(228 [-28]) = [0]
	strchr(228 [-28]) = [0]
	strchr(228 [228]) = [0]
	strchr(228 [228]) = [0]

When running it on Debian with libc6 2.11.2-10:

	strchr(228 [-28]) = [255]
	strchr(228 [-28]) = [255]
	strchr(228 [-28]) = [255]
	strchr(228 [228]) = [0]
	strchr(228 [228]) = [0]

When the second argument passed to strchr() is negative (i.e. it's a char
with value greater than 127), strchr() incorrectly matches it to
character with value of -1.

Passing positive int or char cast to (unsigned char) fixes this problem,
but I don't think this is a solution. I would expect strchr() to behave
consistently accross different versions and I don't think that invoking

	char c = 228 /* or "-28" or some latin9 character with diacritics */
	char *r = strchr(s, c);

should lead to r containing something other than NULL.

From strchr() manpage

	Here "character" means "byte"; these functions do not work with
	wide or multibyte characters.

So I would expect strchr() to work correctly with _bytes_, not only bytes
lower than 128.



Reply to: