test-memmem.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /* Test and measure memmem functions.
  2. Copyright (C) 2008-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Written by Ulrich Drepper <drepper@redhat.com>, 2008.
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, see
  15. <http://www.gnu.org/licenses/>. */
  16. #define TEST_MAIN
  17. #define TEST_NAME "memmem"
  18. #define BUF1PAGES 20
  19. #define ITERATIONS 500
  20. #include "test-string.h"
  21. typedef char *(*proto_t) (const void *, size_t, const void *, size_t);
  22. void *simple_memmem (const void *, size_t, const void *, size_t);
  23. IMPL (simple_memmem, 0)
  24. IMPL (memmem, 1)
  25. void *
  26. simple_memmem (const void *haystack, size_t haystack_len, const void *needle,
  27. size_t needle_len)
  28. {
  29. const char *begin;
  30. const char *const last_possible
  31. = (const char *) haystack + haystack_len - needle_len;
  32. if (needle_len == 0)
  33. /* The first occurrence of the empty string is deemed to occur at
  34. the beginning of the string. */
  35. return (void *) haystack;
  36. /* Sanity check, otherwise the loop might search through the whole
  37. memory. */
  38. if (__glibc_unlikely (haystack_len < needle_len))
  39. return NULL;
  40. for (begin = (const char *) haystack; begin <= last_possible; ++begin)
  41. if (begin[0] == ((const char *) needle)[0] &&
  42. !memcmp ((const void *) &begin[1],
  43. (const void *) ((const char *) needle + 1),
  44. needle_len - 1))
  45. return (void *) begin;
  46. return NULL;
  47. }
  48. static int
  49. check_result (impl_t *impl, const void *haystack, size_t haystack_len,
  50. const void *needle, size_t needle_len, const void *expected)
  51. {
  52. void *res;
  53. res = CALL (impl, haystack, haystack_len, needle, needle_len);
  54. if (res != expected)
  55. {
  56. error (0, 0, "Wrong result in function %s %p %p", impl->name,
  57. res, expected);
  58. ret = 1;
  59. return -1;
  60. }
  61. return 0;
  62. }
  63. static void
  64. do_one_test (impl_t *impl, const void *haystack, size_t haystack_len,
  65. const void *needle, size_t needle_len, const void *expected)
  66. {
  67. if (check_result (impl, haystack, haystack_len, needle, needle_len,
  68. expected) < 0)
  69. return;
  70. }
  71. static void
  72. do_test (const char *str, size_t len, size_t idx)
  73. {
  74. char tmpbuf[len];
  75. memcpy (tmpbuf, buf1 + idx, len);
  76. memcpy (buf1 + idx, str, len);
  77. FOR_EACH_IMPL (impl, 0)
  78. do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx);
  79. memcpy (buf1 + idx, tmpbuf, len);
  80. }
  81. static void
  82. do_random_tests (void)
  83. {
  84. for (size_t n = 0; n < ITERATIONS; ++n)
  85. {
  86. char tmpbuf[32];
  87. size_t shift = random () % 11;
  88. size_t rel = random () % ((2 << (shift + 1)) * 64);
  89. size_t idx = MIN ((2 << shift) * 64 + rel, BUF1PAGES * page_size - 2);
  90. size_t len = random () % (sizeof (tmpbuf) - 1) + 1;
  91. len = MIN (len, BUF1PAGES * page_size - idx - 1);
  92. memcpy (tmpbuf, buf1 + idx, len);
  93. for (size_t i = random () % len / 2 + 1; i > 0; --i)
  94. {
  95. size_t off = random () % len;
  96. char ch = '0' + random () % 10;
  97. buf1[idx + off] = ch;
  98. }
  99. FOR_EACH_IMPL (impl, 0)
  100. do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len,
  101. buf1 + idx);
  102. memcpy (buf1 + idx, tmpbuf, len);
  103. }
  104. }
  105. static void
  106. check1 (void)
  107. {
  108. const char search_buf_data[5] = { 0x56, 0x34, 0x12, 0x78, 0x78 };
  109. const char pattern[2] = { 0x78, 0x56 };
  110. void *search_buf = (void *) buf1 + page_size - sizeof search_buf_data;
  111. void *exp_result;
  112. memcpy (search_buf, search_buf_data, sizeof search_buf_data);
  113. exp_result = simple_memmem (search_buf, sizeof search_buf_data,
  114. pattern, sizeof pattern);
  115. FOR_EACH_IMPL (impl, 0)
  116. check_result (impl, search_buf, sizeof search_buf_data,
  117. pattern, sizeof pattern, exp_result);
  118. }
  119. static const char *const strs[] =
  120. {
  121. "00000", "00112233", "0123456789", "0000111100001111",
  122. "00000111110000022222", "012345678901234567890",
  123. "abc0", "aaaa0", "abcabc0"
  124. };
  125. int
  126. test_main (void)
  127. {
  128. size_t i;
  129. test_init ();
  130. check1 ();
  131. printf ("%23s", "");
  132. FOR_EACH_IMPL (impl, 0)
  133. printf ("\t%s", impl->name);
  134. putchar ('\n');
  135. for (i = 0; i < BUF1PAGES * page_size; ++i)
  136. buf1[i] = 60 + random () % 32;
  137. for (i = 0; i < sizeof (strs) / sizeof (strs[0]); ++i)
  138. for (size_t j = 0; j < 120; j += 7)
  139. {
  140. size_t len = strlen (strs[i]);
  141. do_test (strs[i], len, j);
  142. }
  143. do_random_tests ();
  144. return ret;
  145. }
  146. #include <support/test-driver.c>