@@ -53,6 +53,9 @@ void *T_mempcpy(void *__restrict dest, const void *__restrict src, size_t n)
5353void * T_memrchr (const void * s , int c , size_t n )
5454 __attribute__((nonnull (1 )));
5555
56+ void * T_memmem (const void * haystack , size_t haystack_len , const void * needle , size_t needle_len )
57+ __attribute__((nonnull (1 , 3 )));
58+
5659char * T_stpcpy (char * __restrict dest , const char * __restrict src )
5760 __attribute__((nonnull (1 , 2 )));
5861
@@ -82,6 +85,7 @@ void T_bzero(void* s, size_t n);
8285#define T_memccpy memccpy
8386#define T_mempcpy mempcpy
8487#define T_memrchr memrchr
88+ #define T_memmem memmem
8589#define T_stpcpy stpcpy
8690#define T_stpncpy stpncpy
8791#define T_strlcat strlcat
@@ -700,6 +704,98 @@ int stpncpy_test(void) {
700704 return 0 ;
701705}
702706
707+ int memmem_test (void ) {
708+ const char str1 [] = "abcdef123\0aababc123" ;
709+ const char str2 [] = "wxyz" ;
710+
711+ /* Test NULL */
712+
713+ C (T_memmem (NULL_ptr , 0 , NULL_ptr , 0 ) == NULL_ptr );
714+ C (T_memmem (NULL_ptr , 0 , SINK , 0 ) == NULL_ptr );
715+ C (T_memmem (NULL_ptr , 0 , SINK , 1 ) == NULL_ptr );
716+ C (T_memmem (NULL_ptr , 0 , SINK , 2 ) == NULL_ptr );
717+ C (T_memmem (SINK , 0 , NULL_ptr , 0 ) == SINK );
718+ C (T_memmem (SINK , 1 , NULL_ptr , 0 ) == SINK );
719+ C (T_memmem (SINK , 2 , NULL_ptr , 0 ) == SINK );
720+
721+ /* Test same */
722+
723+ C (T_memmem (SINK , 0 , SINK , 0 ) == SINK );
724+ C (T_memmem (SINK , 1 , SINK , 0 ) == SINK );
725+ C (T_memmem (SINK , 2 , SINK , 0 ) == SINK );
726+ C (T_memmem (SINK , 0 , SINK , 1 ) == NULL );
727+ C (T_memmem (SINK , 1 , SINK , 1 ) == SINK );
728+ C (T_memmem (SINK , 2 , SINK , 1 ) == SINK );
729+ C (T_memmem (SINK , 0 , SINK , 2 ) == NULL );
730+ C (T_memmem (SINK , 1 , SINK , 2 ) == NULL );
731+ C (T_memmem (SINK , 2 , SINK , 2 ) == SINK );
732+
733+ C (T_memmem (SINK , 300 , SINK , 300 ) == SINK );
734+ C (T_memmem (SINK , 300 , SINK , 301 ) == NULL );
735+ C (T_memmem (SINK , 300 , SINK , 299 ) == SINK );
736+ C (T_memmem (SINK , 300 , SINK , 30 ) == SINK );
737+ C (T_memmem (SINK , 30 , SINK , 300 ) == NULL );
738+
739+ C (T_memmem (SINK + 30 , 60 , SINK + 0 , 60 ) == SINK + 30 );
740+ C (T_memmem (SINK + 0 , 60 , SINK + 30 , 60 ) == SINK + 0 );
741+ C (T_memmem (SINK + 30 , 60 , SINK + 0 , 59 ) == SINK + 30 );
742+ C (T_memmem (SINK + 0 , 60 , SINK + 30 , 59 ) == SINK + 0 );
743+
744+ C (T_memmem (str1 , 20 , str1 , 0 ) == str1 );
745+ C (T_memmem (str1 , 20 , str1 , 1 ) == str1 );
746+ C (T_memmem (str1 , 20 , str1 , 2 ) == str1 );
747+ C (T_memmem (str1 , 20 , str1 , 3 ) == str1 );
748+ C (T_memmem (str1 , 20 , str1 , 9 ) == str1 );
749+ C (T_memmem (str1 , 20 , str1 , 10 ) == str1 );
750+ C (T_memmem (str1 , 20 , str1 , 20 ) == str1 );
751+
752+ /* Test different */
753+
754+ C (T_memmem (str1 , 0 , SINK , 0 ) == str1 );
755+ C (T_memmem (str1 , 1 , SINK , 0 ) == str1 );
756+ C (T_memmem (str1 , 2 , SINK , 0 ) == str1 );
757+ C (T_memmem (str1 , 0 , SINK , 1 ) == NULL );
758+ C (T_memmem (str1 , 1 , SINK , 1 ) == NULL );
759+ C (T_memmem (str1 , 2 , SINK , 1 ) == NULL );
760+ C (T_memmem (str1 , 0 , SINK , 2 ) == NULL );
761+ C (T_memmem (str1 , 1 , SINK , 2 ) == NULL );
762+ C (T_memmem (str1 , 2 , SINK , 2 ) == NULL );
763+
764+ /* Other tests */
765+
766+ C (T_memmem (str1 + 1 , 19 , "abc" , 3 ) == str1 + 13 );
767+ C (T_memmem (str1 + 0 , 20 , "123" , 4 ) == str1 + 6 );
768+ C (T_memmem (str1 + 7 , 13 , "123" , 4 ) == str1 + 16 );
769+
770+ C (T_memmem (str1 + 0 , 20 , "aabaab" , 6 ) == NULL );
771+ C (T_memmem (str1 + 0 , 20 , "\xff\x00\xff" , 4 ) == NULL );
772+ C (T_memmem (str1 + 0 , 20 , "\xff" , 1 ) == NULL );
773+
774+ C (T_memmem (SINK , 300 , "\xff" , 1 ) == NULL );
775+ C (T_memmem (SINK , 300 , "\xff\xff" , 2 ) == NULL );
776+ C (T_memmem (SINK , 300 , "\xff\0" , 2 ) == NULL );
777+ C (T_memmem (SINK , 300 , "\0\xff" , 2 ) == NULL );
778+
779+ C (T_memmem (str2 + 0 , 5 , "" , 1 ) == str2 + 4 );
780+ C (T_memmem (str2 + 4 , 1 , "" , 1 ) == str2 + 4 );
781+ C (T_memmem (str2 + 0 , 5 , "z" , 1 ) == str2 + 3 );
782+ C (T_memmem (str2 + 0 , 5 , "z" , 2 ) == str2 + 3 );
783+ C (T_memmem (str2 + 2 , 5 , "z" , 1 ) == str2 + 3 );
784+ C (T_memmem (str2 + 2 , 5 , "z" , 2 ) == str2 + 3 );
785+ C (T_memmem (str2 + 0 , 3 , "z" , 1 ) == NULL );
786+ C (T_memmem (str2 + 0 , 4 , "z" , 2 ) == NULL );
787+ C (T_memmem (str2 + 0 , 5 , "w" , 1 ) == str2 + 0 );
788+ C (T_memmem (str2 + 0 , 5 , "x" , 1 ) == str2 + 1 );
789+ C (T_memmem (str2 + 0 , 5 , "wx" , 2 ) == str2 + 0 );
790+ C (T_memmem (str2 + 0 , 5 , "xy" , 2 ) == str2 + 1 );
791+ C (T_memmem (str2 + 0 , 5 , "w" , 2 ) == NULL );
792+ C (T_memmem (str2 + 0 , 5 , "x" , 2 ) == NULL );
793+ C (T_memmem (str2 + 0 , 5 , "wx" , 3 ) == NULL );
794+ C (T_memmem (str2 + 0 , 5 , "xy" , 3 ) == NULL );
795+
796+ return 0 ;
797+ }
798+
703799int run_tests (void ) {
704800 int ret = 0 ;
705801 /* boot_asprintf */
@@ -728,6 +824,7 @@ int run_tests(void) {
728824 TEST (memmove_test ());
729825 TEST (strlcat_test ());
730826 TEST (stpncpy_test ());
827+ TEST (memmem_test ());
731828
732829 return 0 ;
733830}
0 commit comments