int
main (void)
{
  size_t n = 0x100000;
  char *input = malloc (n + 1);
  ASSERT (input);

  input[0] = 'a';
  input[1] = 'b';
  memset (input + 2, 'c', 1024);
  memset (input + 1026, 'd', n - 1028);
  input[n - 2] = 'e';
  input[n - 1] = 'a';
  input[n] = '\0';

  /* Basic behavior tests.  */
  ASSERT (RAWMEMCHR (input, 'a') == input);
  ASSERT (RAWMEMCHR (input, 'b') == input + 1);
  ASSERT (RAWMEMCHR (input, 'c') == input + 2);
  ASSERT (RAWMEMCHR (input, 'd') == input + 1026);

  ASSERT (RAWMEMCHR (input + 1, 'a') == input + n - 1);
  ASSERT (RAWMEMCHR (input + 1, 'e') == input + n - 2);
  ASSERT (RAWMEMCHR (input + 1, 0x789abc00 | 'e') == input + n - 2);

  ASSERT (RAWMEMCHR (input, '\0') == input + n);

  /* Alignment tests.  */
  {
    int i, j;
    for (i = 0; i < 32; i++)
      {
        for (j = 0; j < 256; j++)
          input[i + j] = j;
        for (j = 0; j < 256; j++)
          {
            ASSERT (RAWMEMCHR (input + i, j) == input + i + j);
          }
      }
  }

  /* Ensure that no unaligned oversized reads occur.  */
  {
    char *page_boundary = (char *) zerosize_ptr ();
    size_t i;

    if (!page_boundary)
      page_boundary = input + 4096;
    memset (page_boundary - 512, '1', 511);
    page_boundary[-1] = '2';
    for (i = 1; i <= 512; i++)
      ASSERT (RAWMEMCHR (page_boundary - i, (i * 0x01010100) | '2')
              == page_boundary - 1);
  }

  free (input);

  return 0;
}
Exemple #2
0
int
main (void)
{
  size_t n = 0x100000;
  char *input = malloc (n);
  ASSERT (input);

  input[n - 1] = 'a';
  input[n - 2] = 'b';
  memset (input + n - 1026, 'c', 1024);
  memset (input + 2, 'd', n - 1028);
  input[1] = 'e';
  input[0] = 'a';

  /* Basic behavior tests.  */
  ASSERT (MEMRCHR (input, 'a', n) == input + n - 1);

  ASSERT (MEMRCHR (input, 'a', 0) == NULL);
  ASSERT (MEMRCHR (zerosize_ptr (), 'a', 0) == NULL);

  ASSERT (MEMRCHR (input, 'b', n) == input + n - 2);
  ASSERT (MEMRCHR (input, 'c', n) == input + n - 3);
  ASSERT (MEMRCHR (input, 'd', n) == input + n - 1027);

  ASSERT (MEMRCHR (input, 'a', n - 1) == input);
  ASSERT (MEMRCHR (input, 'e', n - 1) == input + 1);

  ASSERT (MEMRCHR (input, 'f', n) == NULL);
  ASSERT (MEMRCHR (input, '\0', n) == NULL);

  /* Check that a very long haystack is handled quickly if the byte is
     found near the end.  */
  {
    size_t repeat = 10000;
    for (; repeat > 0; repeat--)
      {
        ASSERT (MEMRCHR (input, 'c', n) == input + n - 3);
      }
  }

  /* Alignment tests.  */
  {
    int i, j;
    for (i = 0; i < 32; i++)
      {
        for (j = 0; j < 256; j++)
          input[i + j] = j;
        for (j = 0; j < 256; j++)
          {
            ASSERT (MEMRCHR (input + i, j, 256) == input + i + j);
          }
      }
  }

  free (input);

  return 0;
}
Exemple #3
0
int
main (void)
{
  /* Test equal / not equal distinction.  */
  ASSERT (memcmp (zerosize_ptr (), zerosize_ptr (), 0) == 0);
  ASSERT (memcmp ("foo", "foobar", 2) == 0);
  ASSERT (memcmp ("foo", "foobar", 3) == 0);
  ASSERT (memcmp ("foo", "foobar", 4) != 0);
  ASSERT (memcmp ("foo", "bar", 1) != 0);
  ASSERT (memcmp ("foo", "bar", 3) != 0);

  /* Test less / equal / greater distinction.  */
  ASSERT (memcmp ("foo", "moo", 4) < 0);
  ASSERT (memcmp ("moo", "foo", 4) > 0);
  ASSERT (memcmp ("oomph", "oops", 3) < 0);
  ASSERT (memcmp ("oops", "oomph", 3) > 0);
  ASSERT (memcmp ("foo", "foobar", 4) < 0);
  ASSERT (memcmp ("foobar", "foo", 4) > 0);

  /* Some old versions of memcmp were not 8-bit clean.  */
  ASSERT (memcmp ("\100", "\201", 1) < 0);
  ASSERT (memcmp ("\201", "\100", 1) > 0);
  ASSERT (memcmp ("\200", "\201", 1) < 0);
  ASSERT (memcmp ("\201", "\200", 1) > 0);

  /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
     or more and with at least one buffer not starting on a 4-byte boundary.
     William Lewis provided this test program.   */
  {
    char foo[21];
    char bar[21];
    int i;
    for (i = 0; i < 4; i++)
      {
        char *a = foo + i;
        char *b = bar + i;
        strcpy (a, "--------01111111");
        strcpy (b, "--------10000000");
        ASSERT (memcmp (a, b, 16) < 0);
      }
  }

  return 0;
}
Exemple #4
0
int
main (void)
{
  size_t i;
  char *page_boundary = (char *) zerosize_ptr ();
  if (!page_boundary)
    {
      page_boundary = malloc (0x1000);
      ASSERT (page_boundary);
      page_boundary += 0x1000;
    }

  /* Basic behavior tests.  */
  ASSERT (strnlen ("a", 0) == 0);
  ASSERT (strnlen ("a", 1) == 1);
  ASSERT (strnlen ("a", 2) == 1);
  ASSERT (strnlen ("", 0x100000) == 0);

  /* Memory fence and alignment testing.  */
  for (i = 0; i < 512; i++)
    {
      char *start = page_boundary - i;
      size_t j = i;
      memset (start, 'x', i);
      do
        {
          if (i != j)
            {
              start[j] = 0;
              ASSERT (strnlen (start, i + j) == j);
            }
          ASSERT (strnlen (start, i) == j);
          ASSERT (strnlen (start, j) == j);
        }
      while (j--);
    }

  return 0;
}
Exemple #5
0
int
main (void)
{
    size_t n = 0x100000;
    char *input = malloc (n);
    ASSERT (input);

    input[0] = 'a';
    input[1] = 'b';
    memset (input + 2, 'c', 1024);
    memset (input + 1026, 'd', n - 1028);
    input[n - 2] = 'e';
    input[n - 1] = 'a';

    /* Basic behavior tests.  */
    ASSERT (MEMCHR (input, 'a', n) == input);

    ASSERT (MEMCHR (input, 'a', 0) == NULL);
    ASSERT (MEMCHR (zerosize_ptr (), 'a', 0) == NULL);

    ASSERT (MEMCHR (input, 'b', n) == input + 1);
    ASSERT (MEMCHR (input, 'c', n) == input + 2);
    ASSERT (MEMCHR (input, 'd', n) == input + 1026);

    ASSERT (MEMCHR (input + 1, 'a', n - 1) == input + n - 1);
    ASSERT (MEMCHR (input + 1, 'e', n - 1) == input + n - 2);
    ASSERT (MEMCHR (input + 1, 0x789abc00 | 'e', n - 1) == input + n - 2);

    ASSERT (MEMCHR (input, 'f', n) == NULL);
    ASSERT (MEMCHR (input, '\0', n) == NULL);

    /* Check that a very long haystack is handled quickly if the byte is
       found near the beginning.  */
    {
        size_t repeat = 10000;
        for (; repeat > 0; repeat--)
        {
            ASSERT (MEMCHR (input, 'c', n) == input + 2);
        }
    }

    /* Alignment tests.  */
    {
        int i, j;
        for (i = 0; i < 32; i++)
        {
            for (j = 0; j < 256; j++)
                input[i + j] = j;
            for (j = 0; j < 256; j++)
            {
                ASSERT (MEMCHR (input + i, j, 256) == input + i + j);
            }
        }
    }

    /* Check that memchr() does not read past the first occurrence of the
       byte being searched.  See the Austin Group's clarification
       <http://www.opengroup.org/austin/docs/austin_454.txt>.
       Test both '\0' and something else, since some implementations
       special-case searching for NUL.
    */
    {
        char *page_boundary = (char *) zerosize_ptr ();
        /* Too small, and we miss cache line boundary tests; too large,
           and the test takes cubically longer to complete.  */
        int limit = 257;

        if (page_boundary != NULL)
        {
            for (n = 1; n <= limit; n++)
            {
                char *mem = page_boundary - n;
                memset (mem, 'X', n);
                ASSERT (MEMCHR (mem, 'U', n) == NULL);
                ASSERT (MEMCHR (mem, 0, n) == NULL);

                {
                    size_t i;
                    size_t k;

                    for (i = 0; i < n; i++)
                    {
                        mem[i] = 'U';
                        for (k = i + 1; k < n + limit; k++)
                            ASSERT (MEMCHR (mem, 'U', k) == mem + i);
                        mem[i] = 0;
                        for (k = i + 1; k < n + limit; k++)
                            ASSERT (MEMCHR (mem, 0, k) == mem + i);
                        mem[i] = 'X';
                    }
                }
            }
        }
    }

    free (input);

    return 0;
}
Exemple #6
0
int
main (int argc, char *argv[])
{
#if HAVE_DECL_ALARM
  /* Declare failure if test takes too long, by using default abort
     caused by SIGALRM.  All known platforms that lack alarm also lack
     memmem, and the replacement memmem is known to not take too
     long.  */
  signal (SIGALRM, SIG_DFL);
  alarm (100);
#endif

  {
    const char input[] = "foo";
    const char *result = memmem (input, strlen (input), "", 0);
    ASSERT (result == input);
  }

  {
    const char input[] = "foo";
    const char *result = memmem (input, strlen (input), "o", 1);
    ASSERT (result == input + 1);
  }

  {
    const char input[] = "ABC ABCDAB ABCDABCDABDE";
    const char *result = memmem (input, strlen (input), "ABCDABD", 7);
    ASSERT (result == input + 15);
  }

  {
    const char input[] = "ABC ABCDAB ABCDABCDABDE";
    const char *result = memmem (input, strlen (input), "ABCDABE", 7);
    ASSERT (result == NULL);
  }

  {
    const char input[] = "ABC ABCDAB ABCDABCDABDE";
    const char *result = memmem (input, strlen (input), "ABCDABCD", 8);
    ASSERT (result == input + 11);
  }

  /* Check that length 0 does not dereference the pointer.  */
  {
    const char *result = memmem (zerosize_ptr (), 0, "foo", 3);
    ASSERT (result == NULL);
  }

  {
    const char input[] = "foo";
    const char *result = memmem (input, strlen (input), null_ptr (), 0);
    ASSERT (result == input);
  }

  /* Check that a long periodic needle does not cause false positives.  */
  {
    const char input[] = ("F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                          "_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                          "_C3_A7_20_EF_BF_BD");
    const char need[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
    const char *result = memmem (input, strlen (input), need, strlen (need));
    ASSERT (result == NULL);
  }
  {
    const char input[] = ("F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                          "_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                          "_C3_A7_20_EF_BF_BD_DA_B5_C2_A6_20"
                          "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD");
    const char need[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
    const char *result = memmem (input, strlen (input), need, strlen (need));
    ASSERT (result == input + 115);
  }

  /* Check that a very long haystack is handled quickly if the needle is
     short and occurs near the beginning.  */
  {
    size_t repeat = 10000;
    size_t m = 1000000;
    const char *needle =
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    size_t n = strlen (needle);
    char *haystack = (char *) malloc (m + 1);
    if (haystack != NULL)
      {
        memset (haystack, 'A', m);
        haystack[0] = 'B';

        for (; repeat > 0; repeat--)
          {
            ASSERT (memmem (haystack, m, needle, n) == haystack + 1);
          }

        free (haystack);
      }
  }

  /* Check that a very long needle is discarded quickly if the haystack is
     short.  */
  {
    size_t repeat = 10000;
    size_t m = 1000000;
    const char *haystack =
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
      "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB";
    size_t n = strlen (haystack);
    char *needle = (char *) malloc (m + 1);
    if (needle != NULL)
      {
        memset (needle, 'A', m);

        for (; repeat > 0; repeat--)
          {
            ASSERT (memmem (haystack, n, needle, m) == NULL);
          }

        free (needle);
      }
  }

  /* Check that the asymptotic worst-case complexity is not quadratic.  */
  {
    size_t m = 1000000;
    char *haystack = (char *) malloc (2 * m + 1);
    char *needle = (char *) malloc (m + 1);
    if (haystack != NULL && needle != NULL)
      {
        const char *result;

        memset (haystack, 'A', 2 * m);
        haystack[2 * m] = 'B';

        memset (needle, 'A', m);
        needle[m] = 'B';

        result = memmem (haystack, 2 * m + 1, needle, m + 1);
        ASSERT (result == haystack + m);
      }
    free (needle);
    free (haystack);
  }

  /* Check that long needles not present in a haystack can be handled
     with sublinear speed.  */
  {
    size_t repeat = 10000;
    size_t m = 1000000;
    size_t n = 1000;
    char *haystack = (char *) malloc (m);
    char *needle = (char *) malloc (n);
    if (haystack != NULL && needle != NULL)
      {
        const char *result;

        memset (haystack, 'A', m);
        memset (needle, 'B', n);

        for (; repeat > 0; repeat--)
          {
            result = memmem (haystack, m, needle, n);
            ASSERT (result == NULL);
          }
      }
    free (haystack);
    free (needle);
  }

  return 0;
}
int
main (void)
{
    test_strchr ();

    /* Check that u8_strchr() does not read past the end of the string.  */
    {
        char *page_boundary = (char *) zerosize_ptr ();

        if (page_boundary != NULL)
        {
            UNIT *mem;

            mem = (UNIT *) (page_boundary - 1 * sizeof (UNIT));
            mem[0] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);

            mem = (UNIT *) (page_boundary - 2 * sizeof (UNIT));
            mem[0] = 0x50;
            mem[1] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);

            mem = (UNIT *) (page_boundary - 3 * sizeof (UNIT));
            mem[0] = 0x50;
            mem[1] = 0x50;
            mem[2] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);

            mem = (UNIT *) (page_boundary - 3 * sizeof (UNIT));
            mem[0] = 0xC4;
            mem[1] = 0xA0; /* U+0120 */
            mem[2] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);

            mem = (UNIT *) (page_boundary - 3 * sizeof (UNIT));
            mem[0] = 0xC5;
            mem[1] = 0xA3; /* U+0163 */
            mem[2] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);

            mem = (UNIT *) (page_boundary - 4 * sizeof (UNIT));
            mem[0] = 0x50;
            mem[1] = 0x50;
            mem[2] = 0x50;
            mem[3] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);

            mem = (UNIT *) (page_boundary - 4 * sizeof (UNIT));
            mem[0] = 0x50;
            mem[1] = 0xC5;
            mem[2] = 0xA3; /* U+0163 */
            mem[3] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);
            ASSERT (u8_strchr (mem, 0x163) == mem + 1);

            mem = (UNIT *) (page_boundary - 4 * sizeof (UNIT));
            mem[0] = 0xE3;
            mem[1] = 0x91;
            mem[2] = 0x00; /* U+3450 */
            mem[3] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);

            mem = (UNIT *) (page_boundary - 4 * sizeof (UNIT));
            mem[0] = 0xE3;
            mem[1] = 0x92;
            mem[2] = 0x96; /* U+3496 */
            mem[3] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);

            mem = (UNIT *) (page_boundary - 5 * sizeof (UNIT));
            mem[0] = 0x50;
            mem[1] = 0x50;
            mem[2] = 0x50;
            mem[3] = 0x50;
            mem[4] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);

            mem = (UNIT *) (page_boundary - 5 * sizeof (UNIT));
            mem[0] = 0x50;
            mem[1] = 0xE3;
            mem[2] = 0x92;
            mem[3] = 0x96; /* U+3496 */
            mem[4] = 0;
            ASSERT (u8_strchr (mem, 0x55) == NULL);
            ASSERT (u8_strchr (mem, 0x123) == NULL);
            ASSERT (u8_strchr (mem, 0x3456) == NULL);
            ASSERT (u8_strchr (mem, 0x23456) == NULL);
            ASSERT (u8_strchr (mem, 0x3496) == mem + 1);
        }
    }

    return 0;
}
int
main (int argc _GL_UNUSED, char *argv[])
{
  int i;
  bool ascii_only = MB_CUR_MAX == 1 && !isprint ((unsigned char) LQ[0]);

  set_program_name (argv[0]);

  /* This part of the program is hard-wired to the C locale since it
     does not call setlocale.  However, according to POSIX, the use of
     8-bit bytes in a character context in the C locale gives
     unspecified results (that is, the C locale charset is allowed to
     be unibyte with 8-bit bytes rejected [ASCII], unibyte with 8-bit
     bytes being characters [often ISO-8859-1], or multibyte [often
     UTF-8]).  We assume that the latter two cases will be
     indistinguishable in this test - that is, the LQ and RQ sequences
     will pass through unchanged in either type of charset.  So when
     testing for quoting of str7, use the ascii_only flag to decide
     what to expect for the 8-bit data being quoted.  */
  ASSERT (!isprint ('\033'));
  for (i = literal_quoting_style; i <= clocale_quoting_style; i++)
    {
      set_quoting_style (NULL, (enum quoting_style) i);
      if (!(i == locale_quoting_style || i == clocale_quoting_style)
          || (strcmp (locale_charset (), "ASCII") == 0
              || strcmp (locale_charset (), "ANSI_X3.4-1968") == 0))
        {
          compare_strings (use_quotearg_buffer, &results_g[i].group1,
                           ascii_only);
          compare_strings (use_quotearg, &results_g[i].group2,
                           ascii_only);
          if (i == c_quoting_style)
            compare_strings (use_quote_double_quotes, &results_g[i].group2,
                             ascii_only);
          compare_strings (use_quotearg_colon, &results_g[i].group3,
                           ascii_only);
        }
    }

  set_quoting_style (NULL, literal_quoting_style);
  ASSERT (set_quoting_flags (NULL, QA_ELIDE_NULL_BYTES) == 0);
  compare_strings (use_quotearg_buffer, &flag_results[0].group1, ascii_only);
  compare_strings (use_quotearg, &flag_results[0].group2, ascii_only);
  compare_strings (use_quotearg_colon, &flag_results[0].group3, ascii_only);

  set_quoting_style (NULL, c_quoting_style);
  ASSERT (set_quoting_flags (NULL, QA_ELIDE_OUTER_QUOTES)
          == QA_ELIDE_NULL_BYTES);
  compare_strings (use_quotearg_buffer, &flag_results[1].group1, ascii_only);
  compare_strings (use_quotearg, &flag_results[1].group2, ascii_only);
  compare_strings (use_quote_double_quotes, &flag_results[1].group2,
                   ascii_only);
  compare_strings (use_quotearg_colon, &flag_results[1].group3, ascii_only);

  ASSERT (set_quoting_flags (NULL, QA_SPLIT_TRIGRAPHS)
          == QA_ELIDE_OUTER_QUOTES);
  compare_strings (use_quotearg_buffer, &flag_results[2].group1, ascii_only);
  compare_strings (use_quotearg, &flag_results[2].group2, ascii_only);
  compare_strings (use_quote_double_quotes, &flag_results[2].group2,
                   ascii_only);
  compare_strings (use_quotearg_colon, &flag_results[2].group3, ascii_only);

  ASSERT (set_quoting_flags (NULL, 0) == QA_SPLIT_TRIGRAPHS);

  for (i = 0; i < sizeof custom_quotes / sizeof *custom_quotes; ++i)
    {
      set_custom_quoting (NULL,
                          custom_quotes[i][0], custom_quotes[i][1]);
      compare_strings (use_quotearg_buffer, &custom_results[i].group1,
                       ascii_only);
      compare_strings (use_quotearg, &custom_results[i].group2, ascii_only);
      compare_strings (use_quotearg_colon, &custom_results[i].group3,
                       ascii_only);
    }

  {
    /* Trigger the bug whereby quotearg_buffer would read beyond the NUL
       that defines the end of the string being quoted.  Use an input
       string whose NUL is the last byte before an unreadable page.  */
    char *z = zerosize_ptr ();

    if (z)
      {
        size_t q_len = 1024;
        char *q = malloc (q_len + 1);
        char buf[10];
        memset (q, 'Q', q_len);
        q[q_len] = 0;

        /* Z points to the boundary between a readable/writable page
           and one that is neither readable nor writable.  Position
           our string so its NUL is at the end of the writable one.  */
        char const *str = "____";
        size_t s_len = strlen (str);
        z -= s_len + 1;
        memcpy (z, str, s_len + 1);

        set_custom_quoting (NULL, q, q);
        /* Whether this actually triggers a SEGV depends on the
           implementation of memcmp: whether it compares only byte-at-
           a-time, and from left to right (no SEGV) or some other way.  */
        size_t n = quotearg_buffer (buf, sizeof buf, z, SIZE_MAX, NULL);
        ASSERT (n == s_len + 2 * q_len);
        ASSERT (memcmp (buf, q, sizeof buf) == 0);
        free (q);
      }
  }

  quotearg_free ();

  return 0;
}
Exemple #9
0
int
main (void)
{
    size_t n = 0x100000;
    char *input = malloc (n);
    ASSERT (input);

    input[0] = 'a';
    input[1] = 'b';
    memset (input + 2, 'c', 1024);
    memset (input + 1026, 'd', n - 1028);
    input[n - 2] = 'e';
    input[n - 1] = 'a';

    /* Basic behavior tests.  */
    ASSERT (MEMCHR (input, 'a', n) == input);

    ASSERT (MEMCHR (input, 'a', 0) == NULL);
    ASSERT (MEMCHR (zerosize_ptr (), 'a', 0) == NULL);

    ASSERT (MEMCHR (input, 'b', n) == input + 1);
    ASSERT (MEMCHR (input, 'c', n) == input + 2);
    ASSERT (MEMCHR (input, 'd', n) == input + 1026);

    ASSERT (MEMCHR (input + 1, 'a', n - 1) == input + n - 1);
    ASSERT (MEMCHR (input + 1, 'e', n - 1) == input + n - 2);

    ASSERT (MEMCHR (input, 'f', n) == NULL);
    ASSERT (MEMCHR (input, '\0', n) == NULL);

    /* Check that a very long haystack is handled quickly if the byte is
       found near the beginning.  */
    {
        size_t repeat = 10000;
        for (; repeat > 0; repeat--)
        {
            ASSERT (MEMCHR (input, 'c', n) == input + 2);
        }
    }

    /* Alignment tests.  */
    {
        int i, j;
        for (i = 0; i < 32; i++)
        {
            for (j = 0; j < 256; j++)
                input[i + j] = j;
            for (j = 0; j < 256; j++)
            {
                ASSERT (MEMCHR (input + i, j, 256) == input + i + j);
            }
        }
    }

    /* Check that memchr() does not read past the first occurrence of the
       byte being searched.  See the Austin Group's clarification
       <http://www.opengroup.org/austin/docs/austin_454.txt>.  */
    {
        char *page_boundary = (char *) zerosize_ptr ();

        if (page_boundary != NULL)
        {
            for (n = 1; n <= 500; n++)
            {
                char *mem = page_boundary - n;
                memset (mem, 'X', n);
                ASSERT (MEMCHR (mem, 'U', n) == NULL);

                {
                    size_t i;

                    for (i = 0; i < n; i++)
                    {
                        mem[i] = 'U';
                        ASSERT (MEMCHR (mem, 'U', 4000) == mem + i);
                        mem[i] = 'X';
                    }
                }
            }
        }
    }

    free (input);

    return 0;
}
Exemple #10
0
int
main (int argc, char *argv[])
{
#if HAVE_DECL_ALARM
  /* Declare failure if test takes too long, by using default abort
     caused by SIGALRM.  All known platforms that lack alarm also have
     a quadratic strstr, and the replacement strstr is known to not
     take too long.  */
  signal (SIGALRM, SIG_DFL);
  alarm (50);
#endif

  {
    const char input[] = "foo";
    const char *result = strstr (input, "");
    ASSERT (result == input);
  }

  {
    const char input[] = "foo";
    const char *result = strstr (input, "o");
    ASSERT (result == input + 1);
  }

  {
    /* On some platforms, the memchr() functions reads past the first
       occurrence of the byte to be searched, leading to an out-of-bounds
       read access for strstr().
       See <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737>.
       This is a bug in memchr(), see the Austin Group's clarification
       <http://www.opengroup.org/austin/docs/austin_454.txt>.  */
    const char *fix = "aBaaaaaaaaaaax";
    char *page_boundary = (char *) zerosize_ptr ();
    size_t len = strlen (fix) + 1;
    char *input = page_boundary ? page_boundary - len : malloc (len);
    const char *result;

    strcpy (input, fix);
    result = strstr (input, "B1x");
    ASSERT (result == NULL);
    if (!page_boundary)
      free (input);
  }

  {
    const char input[] = "ABC ABCDAB ABCDABCDABDE";
    const char *result = strstr (input, "ABCDABD");
    ASSERT (result == input + 15);
  }

  {
    const char input[] = "ABC ABCDAB ABCDABCDABDE";
    const char *result = strstr (input, "ABCDABE");
    ASSERT (result == NULL);
  }

  {
    const char input[] = "ABC ABCDAB ABCDABCDABDE";
    const char *result = strstr (input, "ABCDABCD");
    ASSERT (result == input + 11);
  }

  /* Check that a long periodic needle does not cause false positives.  */
  {
    const char input[] = "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                         "_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                         "_C3_A7_20_EF_BF_BD";
    const char need[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
    const char *result = strstr (input, need);
    ASSERT (result == NULL);
  }
  {
    const char input[] = "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                         "_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                         "_C3_A7_20_EF_BF_BD_DA_B5_C2_A6_20"
                         "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
    const char need[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
    const char *result = strstr (input, need);
    ASSERT (result == input + 115);
  }

  /* Check that a very long haystack is handled quickly if the needle is
     short and occurs near the beginning.  */
  {
    size_t repeat = 10000;
    size_t m = 1000000;
    const char *needle =
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    char *haystack = (char *) malloc (m + 1);
    if (haystack != NULL)
      {
        memset (haystack, 'A', m);
        haystack[0] = 'B';
        haystack[m] = '\0';

        for (; repeat > 0; repeat--)
          {
            ASSERT (strstr (haystack, needle) == haystack + 1);
          }

        free (haystack);
      }
  }

  /* Check that a very long needle is discarded quickly if the haystack is
     short.  */
  {
    size_t repeat = 10000;
    size_t m = 1000000;
    const char *haystack =
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
      "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB";
    char *needle = (char *) malloc (m + 1);
    if (needle != NULL)
      {
        memset (needle, 'A', m);
        needle[m] = '\0';

        for (; repeat > 0; repeat--)
          {
            ASSERT (strstr (haystack, needle) == NULL);
          }

        free (needle);
      }
  }

  /* Check that the asymptotic worst-case complexity is not quadratic.  */
  {
    size_t m = 1000000;
    char *haystack = (char *) malloc (2 * m + 2);
    char *needle = (char *) malloc (m + 2);
    if (haystack != NULL && needle != NULL)
      {
        const char *result;

        memset (haystack, 'A', 2 * m);
        haystack[2 * m] = 'B';
        haystack[2 * m + 1] = '\0';

        memset (needle, 'A', m);
        needle[m] = 'B';
        needle[m + 1] = '\0';

        result = strstr (haystack, needle);
        ASSERT (result == haystack + m);
      }
    free (needle);
    free (haystack);
  }

  /* Sublinear speed is only possible in memmem; strstr must examine
     every character of haystack to find its length.  */


  {
    /* Ensure that with a barely periodic "short" needle, strstr's
       search does not mistakenly skip just past the match point.
       This use of strstr would mistakenly return NULL before
       gnulib v0.0-4927.  */
    const char *haystack =
      "\n"
      "with_build_libsubdir\n"
      "with_local_prefix\n"
      "with_gxx_include_dir\n"
      "with_cpp_install_dir\n"
      "enable_generated_files_in_srcdir\n"
      "with_gnu_ld\n"
      "with_ld\n"
      "with_demangler_in_ld\n"
      "with_gnu_as\n"
      "with_as\n"
      "enable_largefile\n"
      "enable_werror_always\n"
      "enable_checking\n"
      "enable_coverage\n"
      "enable_gather_detailed_mem_stats\n"
      "enable_build_with_cxx\n"
      "with_stabs\n"
      "enable_multilib\n"
      "enable___cxa_atexit\n"
      "enable_decimal_float\n"
      "enable_fixed_point\n"
      "enable_threads\n"
      "enable_tls\n"
      "enable_objc_gc\n"
      "with_dwarf2\n"
      "enable_shared\n"
      "with_build_sysroot\n"
      "with_sysroot\n"
      "with_specs\n"
      "with_pkgversion\n"
      "with_bugurl\n"
      "enable_languages\n"
      "with_multilib_list\n";
    const char *needle = "\n"
      "with_gnu_ld\n";
    const char* p = strstr (haystack, needle);
    ASSERT (p - haystack == 114);
  }

  {
    /* Same bug, shorter trigger.  */
    const char *haystack = "..wi.d.";
    const char *needle = ".d.";
    const char* p = strstr (haystack, needle);
    ASSERT (p - haystack == 4);
  }

  {
    /* Like the above, but trigger the flaw in two_way_long_needle
       by using a needle of length LONG_NEEDLE_THRESHOLD (32) or greater.
       Rather than trying to find the right alignment manually, I've
       arbitrarily chosen the following needle and template for the
       haystack, and ensure that for each placement of the needle in
       that haystack, strstr finds it.  */
    const char *needle = "\nwith_gnu_ld-extend-to-len-32-b\n";
    const char *h =
      "\n"
      "with_build_libsubdir\n"
      "with_local_prefix\n"
      "with_gxx_include_dir\n"
      "with_cpp_install_dir\n"
      "with_e_\n"
      "..............................\n"
      "with_FGHIJKLMNOPQRSTUVWXYZ\n"
      "with_567890123456789\n"
      "with_multilib_list\n";
    size_t h_len = strlen (h);
    char *haystack = malloc (h_len + 1);
    size_t i;
    ASSERT (haystack);
    for (i = 0; i < h_len - strlen (needle); i++)
      {
        const char *p;
        memcpy (haystack, h, h_len + 1);
        memcpy (haystack + i, needle, strlen (needle) + 1);
        p = strstr (haystack, needle);
        ASSERT (p);
        ASSERT (p - haystack == i);
      }
  }

  return 0;
}
Exemple #11
0
int
main (int argc, char *argv[])
{
#if HAVE_DECL_ALARM
  /* Declare failure if test takes too long, by using default abort
     caused by SIGALRM.  All known platforms that lack alarm also lack
     memmem, and the replacement memmem is known to not take too
     long.  */
  int alarm_value = 100;
  signal (SIGALRM, SIG_DFL);
  alarm (alarm_value);
#endif

  {
    const char input[] = "foo";
    const char *result = memmem (input, strlen (input), "", 0);
    ASSERT (result == input);
  }

  {
    const char input[] = "foo";
    const char *result = memmem (input, strlen (input), "o", 1);
    ASSERT (result == input + 1);
  }

  {
    const char input[] = "ABC ABCDAB ABCDABCDABDE";
    const char *result = memmem (input, strlen (input), "ABCDABD", 7);
    ASSERT (result == input + 15);
  }

  {
    const char input[] = "ABC ABCDAB ABCDABCDABDE";
    const char *result = memmem (input, strlen (input), "ABCDABE", 7);
    ASSERT (result == NULL);
  }

  {
    const char input[] = "ABC ABCDAB ABCDABCDABDE";
    const char *result = memmem (input, strlen (input), "ABCDABCD", 8);
    ASSERT (result == input + 11);
  }

  /* Check that length 0 does not dereference the pointer.  */
  {
    const char *result = memmem (zerosize_ptr (), 0, "foo", 3);
    ASSERT (result == NULL);
  }

  {
    const char input[] = "foo";
    const char *result = memmem (input, strlen (input), null_ptr (), 0);
    ASSERT (result == input);
  }

  /* Check that a long periodic needle does not cause false positives.  */
  {
    const char input[] = ("F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                          "_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                          "_C3_A7_20_EF_BF_BD");
    const char need[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
    const char *result = memmem (input, strlen (input), need, strlen (need));
    ASSERT (result == NULL);
  }
  {
    const char input[] = ("F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                          "_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD"
                          "_C3_A7_20_EF_BF_BD_DA_B5_C2_A6_20"
                          "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD");
    const char need[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
    const char *result = memmem (input, strlen (input), need, strlen (need));
    ASSERT (result == input + 115);
  }

  /* Check that a very long haystack is handled quickly if the needle is
     short and occurs near the beginning.  */
  {
    size_t repeat = 10000;
    size_t m = 1000000;
    const char *needle =
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    size_t n = strlen (needle);
    char *haystack = (char *) malloc (m + 1);
    if (haystack != NULL)
      {
        memset (haystack, 'A', m);
        haystack[0] = 'B';

        for (; repeat > 0; repeat--)
          {
            ASSERT (memmem (haystack, m, needle, n) == haystack + 1);
          }

        free (haystack);
      }
  }

  /* Check that a very long needle is discarded quickly if the haystack is
     short.  */
  {
    size_t repeat = 10000;
    size_t m = 1000000;
    const char *haystack =
      "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
      "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB";
    size_t n = strlen (haystack);
    char *needle = (char *) malloc (m + 1);
    if (needle != NULL)
      {
        memset (needle, 'A', m);

        for (; repeat > 0; repeat--)
          {
            ASSERT (memmem (haystack, n, needle, m) == NULL);
          }

        free (needle);
      }
  }

  /* Check that the asymptotic worst-case complexity is not quadratic.  */
  {
    size_t m = 1000000;
    char *haystack = (char *) malloc (2 * m + 1);
    char *needle = (char *) malloc (m + 1);
    if (haystack != NULL && needle != NULL)
      {
        const char *result;

        memset (haystack, 'A', 2 * m);
        haystack[2 * m] = 'B';

        memset (needle, 'A', m);
        needle[m] = 'B';

        result = memmem (haystack, 2 * m + 1, needle, m + 1);
        ASSERT (result == haystack + m);
      }
    free (needle);
    free (haystack);
  }

  /* Check that long needles not present in a haystack can be handled
     with sublinear speed.  */
  {
    size_t repeat = 10000;
    size_t m = 1000000;
    size_t n = 1000;
    char *haystack = (char *) malloc (m);
    char *needle = (char *) malloc (n);
    if (haystack != NULL && needle != NULL)
      {
        const char *result;

        memset (haystack, 'A', m);
        memset (needle, 'B', n);

        for (; repeat > 0; repeat--)
          {
            result = memmem (haystack, m, needle, n);
            ASSERT (result == NULL);
          }
      }
    free (haystack);
    free (needle);
  }

  {
    /* Ensure that with a barely periodic "short" needle, memmem's
       search does not mistakenly skip just past the match point.
       This use of memmem would mistakenly return NULL before
       gnulib v0.0-4927.  */
    const char *haystack =
      "\n"
      "with_build_libsubdir\n"
      "with_local_prefix\n"
      "with_gxx_include_dir\n"
      "with_cpp_install_dir\n"
      "enable_generated_files_in_srcdir\n"
      "with_gnu_ld\n"
      "with_ld\n"
      "with_demangler_in_ld\n"
      "with_gnu_as\n"
      "with_as\n"
      "enable_largefile\n"
      "enable_werror_always\n"
      "enable_checking\n"
      "enable_coverage\n"
      "enable_gather_detailed_mem_stats\n"
      "enable_build_with_cxx\n"
      "with_stabs\n"
      "enable_multilib\n"
      "enable___cxa_atexit\n"
      "enable_decimal_float\n"
      "enable_fixed_point\n"
      "enable_threads\n"
      "enable_tls\n"
      "enable_objc_gc\n"
      "with_dwarf2\n"
      "enable_shared\n"
      "with_build_sysroot\n"
      "with_sysroot\n"
      "with_specs\n"
      "with_pkgversion\n"
      "with_bugurl\n"
      "enable_languages\n"
      "with_multilib_list\n";
    const char *needle = "\n"
      "with_gnu_ld\n";
    const char* p = memmem (haystack, strlen (haystack),
                            needle, strlen (needle));
    ASSERT (p - haystack == 114);
  }

  {
    /* Same bug, shorter trigger.  */
    const char *haystack = "..wi.d.";
    const char *needle = ".d.";
    const char* p = memmem (haystack, strlen (haystack),
                            needle, strlen (needle));
    ASSERT (p - haystack == 4);
  }

  {
    /* Like the above, but trigger the flaw in two_way_long_needle
       by using a needle of length LONG_NEEDLE_THRESHOLD (32) or greater.
       Rather than trying to find the right alignment manually, I've
       arbitrarily chosen the following needle and template for the
       haystack, and ensure that for each placement of the needle in
       that haystack, memmem finds it.  */
    const char *needle = "\nwith_gnu_ld-extend-to-len-32-b\n";
    const char *h =
      "\n"
      "with_build_libsubdir\n"
      "with_local_prefix\n"
      "with_gxx_include_dir\n"
      "with_cpp_install_dir\n"
      "with_e_\n"
      "..............................\n"
      "with_FGHIJKLMNOPQRSTUVWXYZ\n"
      "with_567890123456789\n"
      "with_multilib_list\n";
    size_t h_len = strlen (h);
    char *haystack = malloc (h_len + 1);
    size_t i;
    ASSERT (haystack);
    for (i = 0; i < h_len - strlen (needle); i++)
      {
        const char *p;
        memcpy (haystack, h, h_len + 1);
        memcpy (haystack + i, needle, strlen (needle) + 1);
        p = memmem (haystack, strlen (haystack), needle, strlen (needle));
        ASSERT (p);
        ASSERT (p - haystack == i);
      }
  }

  return 0;
}