memmem(3): empty little string matches the beginning of the big string

This function originated in glibc, and this matches their behaviour
(and NetBSD, OpenBSD, and musl).

An empty big string (arg "l") is handled by the existing
l_len < s_len test.

Reviewed by:	bapt, ngie
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D2657
This commit is contained in:
emaste 2015-05-26 21:16:07 +00:00
parent 2f93a7904f
commit d45a21328b
3 changed files with 18 additions and 12 deletions
contrib/netbsd-tests/lib/libc/string
lib/libc/string

@ -75,7 +75,7 @@ ATF_TC_HEAD(memmem_basic, tc)
ATF_TC_BODY(memmem_basic, tc)
{
#if defined(__darwin__) || defined(__FreeBSD__)
#if defined(__darwin__)
expect(memmem(b2, lb2, p0, lp0) == NULL);
expect(memmem(b0, lb0, p0, lp0) == NULL);
#else

@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd August 24, 2005
.Dd May 26, 2015
.Dt MEMMEM 3
.Os
.Sh NAME
@ -51,14 +51,12 @@ in the byte string
.Fa big .
.Sh RETURN VALUES
If
.Fa big_len
is smaller than
.Fa little_len ,
if
.Fa little_len
is 0, if
.Fa big_len
is 0 or if
is zero
.Fa big
is returned (that is, an empty little is deemed to match at the beginning of
big);
if
.Fa little
occurs nowhere in
.Fa big ,
@ -84,3 +82,11 @@ function first appeared in
.Sh BUGS
This function was broken in Linux libc up to and including version 5.0.9
and in GNU libc prior to version 2.1.
Prior to
.Fx 11.0
.Nm
returned
.Dv NULL
when
.Fa little_len
equals 0.

@ -42,9 +42,9 @@ memmem(const void *l, size_t l_len, const void *s, size_t s_len)
const char *cl = (const char *)l;
const char *cs = (const char *)s;
/* we need something to compare */
if (l_len == 0 || s_len == 0)
return NULL;
/* empty "s" matches the beginning of "l" */
if (s_len == 0)
return (void *)cl;
/* "s" must be smaller or equal to "l" */
if (l_len < s_len)