public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* gcc 4.9.1 Bug or not
@ 2014-10-09  5:55 Rongqing Li
  2014-10-09  7:15 ` Jakub Jelinek
  0 siblings, 1 reply; 2+ messages in thread
From: Rongqing Li @ 2014-10-09  5:55 UTC (permalink / raw)
  To: gcc-bugs

[-- Attachment #1: Type: text/plain, Size: 1720 bytes --]

The attachment is a piece of C code.
When compile it with -O2 option, a segfault occurs:
##################
root@qemux86-64:~# gcc -o test test.c
root@qemux86-64:~# ./test
192.168.1.1
root@qemux86-64:~#
root@qemux86-64:~# gcc -O2 -o test test.c
root@qemux86-64:~# ./test
test[893]: segfault at 0 ip 0000000000400944 sp 00007fff87c8f0f0 error 4 
in test[400000+1000]
Segmentation fault
root@qemux86-64:~#
##################




I also test it on some linux distributions, it works well on all of them:
Ubuntu 12.04 x86_64:
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

Ubuntu 14.04 x86_64:
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

Fedora 20 x86 and x86_64:
gcc version 4.8.3 20140624 (Red Hat 4.8.3-1) (GCC)

----------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int name_cmp(const char *a, const char *b)
{
	/* compare strings a and b, but only upto ',' in a */
	while (*a && *b && *a != ',' && *a == *b)
		a++, b++;
	if (!*b && (!*a || *a == ','))
		return 0;
	if (!*b) return 1;
	if (!*a || *a == ',') return -1;
	return *a - *b;
}

char *add_name(char *old, const char *add)
{
	int len = strlen(add) + 2;
	char *new;
	char *cp;

	if (old)
		len += strlen(old);

	new = (char *)malloc(len);
	if (!new)
		return NULL;

	cp = old;
	while (cp && *cp && name_cmp(cp, add) < 0) {
		/* step cp forward over a name */
		char *e = strchr(cp, ',');
		if (e)
			cp = e+1;
		else
			cp = cp + strlen(cp);
	}

	strncpy(new, old, cp-old);
	new[cp-old] = 0;

	if (cp != old && !*cp)
		strcat(new, ",");

	strcat(new, add);

	if (cp && *cp) {
		strcat(new, ",");
		strcat(new, cp);
	}

	return new;
}

int main()
{
	printf("%s\n", add_name(0,"192.168.1.1"));
	return 0;
}

[-- Attachment #2: test.c --]
[-- Type: text/x-csrc, Size: 966 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int name_cmp(const char *a, const char *b)
{
	/* compare strings a and b, but only upto ',' in a */
	while (*a && *b && *a != ',' && *a == *b)
		a++, b++;
	if (!*b && (!*a || *a == ','))
		return 0;
	if (!*b) return 1;
	if (!*a || *a == ',') return -1;
	return *a - *b;
}

char *add_name(char *old, const char *add)
{
	int len = strlen(add) + 2;
	char *new;
	char *cp;

	if (old)
		len += strlen(old);

	new = (char *)malloc(len);
	if (!new) 
		return NULL;

	cp = old;
	while (cp && *cp && name_cmp(cp, add) < 0) {
		/* step cp forward over a name */
		char *e = strchr(cp, ',');
		if (e)
			cp = e+1;
		else
			cp = cp + strlen(cp);
	}

	strncpy(new, old, cp-old);
	new[cp-old] = 0;

	if (cp != old && !*cp)
		strcat(new, ",");

	strcat(new, add);

	if (cp && *cp) {
		strcat(new, ",");
		strcat(new, cp);
	}

	return new;
}

int main()
{
	printf("%s\n", add_name(0,"192.168.1.1"));
	return 0;
} 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: gcc 4.9.1 Bug or not
  2014-10-09  5:55 gcc 4.9.1 Bug or not Rongqing Li
@ 2014-10-09  7:15 ` Jakub Jelinek
  0 siblings, 0 replies; 2+ messages in thread
From: Jakub Jelinek @ 2014-10-09  7:15 UTC (permalink / raw)
  To: Rongqing Li; +Cc: gcc-bugs

On Thu, Oct 09, 2014 at 01:54:57PM +0800, Rongqing Li wrote:
> The attachment is a piece of C code.
> When compile it with -O2 option, a segfault occurs:
> 
> 	strncpy(new, old, cp-old);

It is a bug of course, but in the testcase.
Calling strncpy with NULL second argument, even when the size is 0,
is undefined behavior.
See http://gcc.gnu.org/gcc-4.9/porting_to.html


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-10-09  7:15 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-09  5:55 gcc 4.9.1 Bug or not Rongqing Li
2014-10-09  7:15 ` Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).