Index: head/contrib/netbsd-tests/lib/libc/string/t_memmem.c =================================================================== --- head/contrib/netbsd-tests/lib/libc/string/t_memmem.c (revision 283583) +++ head/contrib/netbsd-tests/lib/libc/string/t_memmem.c (revision 283584) @@ -1,105 +1,105 @@ /* $NetBSD: t_memmem.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */ /*- * Copyright (c) 2005 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include char p0[] = ""; int lp0 = 0; char p1[] = "0123"; int lp1 = 4; char p2[] = "456"; int lp2 = 3; char p3[] = "789"; int lp3 = 3; char p4[] = "abc"; int lp4 = 3; char p5[] = "0"; int lp5 = 1; char p6[] = "9"; int lp6 = 1; char p7[] = "654"; int lp7 = 3; char b0[] = ""; int lb0 = 0; char b1[] = "0"; int lb1 = 1; char b2[] = "0123456789"; int lb2 = 10; #define expect(b) \ if (!(b)) { \ fprintf(stderr, "failed on line %d\n", __LINE__); \ atf_tc_fail("Check stderr for test id/line"); \ } ATF_TC(memmem_basic); ATF_TC_HEAD(memmem_basic, tc) { atf_tc_set_md_var(tc, "descr", "Test memmem results"); } 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 expect(memmem(b2, lb2, p0, lp0) == b2); expect(memmem(b0, lb0, p0, lp0) == b0); #endif expect(memmem(b0, lb0, p1, lp1) == NULL); expect(memmem(b1, lb1, p1, lp1) == NULL); expect(memmem(b2, lb2, p1, lp1) == b2); expect(memmem(b2, lb2, p2, lp2) == (b2 + 4)); expect(memmem(b2, lb2, p3, lp3) == (b2 + 7)); expect(memmem(b2, lb2, p5, lp5) == b2); expect(memmem(b2, lb2, p6, lp6) == (b2 + 9)); expect(memmem(b2, lb2, p4, lp4) == NULL); expect(memmem(b2, lb2, p7, lp7) == NULL); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, memmem_basic); return atf_no_error(); } Index: head/lib/libc/string/memmem.3 =================================================================== --- head/lib/libc/string/memmem.3 (revision 283583) +++ head/lib/libc/string/memmem.3 (revision 283584) @@ -1,86 +1,92 @@ .\" Copyright (c) 2005 Pascal Gloor .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. The name of the author may not be used to endorse or promote .\" products derived from this software without specific prior written .\" permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd August 24, 2005 +.Dd May 26, 2015 .Dt MEMMEM 3 .Os .Sh NAME .Nm memmem .Nd "locate a byte substring in a byte string" .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In string.h .Ft "void *" .Fo memmem .Fa "const void *big" "size_t big_len" .Fa "const void *little" "size_t little_len" .Fc .Sh DESCRIPTION The .Fn memmem function locates the first occurrence of the byte string .Fa little 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 , .Dv NULL is returned; otherwise a pointer to the first character of the first occurrence of .Fa little is returned. .Sh SEE ALSO .Xr memchr 3 , .Xr strchr 3 , .Xr strstr 3 .Sh CONFORMING TO .Fn memmem is a GNU extension. .Sh HISTORY The .Fn memmem function first appeared in .Fx 6.0 . .Sh AUTHORS .An Pascal Gloor Aq Mt pascal.gloor@spale.com .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. Index: head/lib/libc/string/memmem.c =================================================================== --- head/lib/libc/string/memmem.c (revision 283583) +++ head/lib/libc/string/memmem.c (revision 283584) @@ -1,65 +1,65 @@ /*- * Copyright (c) 2005 Pascal Gloor * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include /* * Find the first occurrence of the byte string s in byte string l. */ void * memmem(const void *l, size_t l_len, const void *s, size_t s_len) { register char *cur, *last; 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) return NULL; /* special case where s_len == 1 */ if (s_len == 1) return memchr(l, (int)*cs, l_len); /* the last position where its possible to find "s" in "l" */ last = (char *)cl + l_len - s_len; for (cur = (char *)cl; cur <= last; cur++) if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) return cur; return NULL; }