hjl / source-git / glibc

Forked from source-git/glibc 3 years ago
Clone

Blame posix/tst-regcomp-truncated.c

Packit 8c0394
/* Test compilation of truncated regular expressions.
Packit 8c0394
   Copyright (C) 2018 Free Software Foundation, Inc.
Packit 8c0394
   This file is part of the GNU C Library.
Packit 8c0394
Packit 8c0394
   The GNU C Library is free software; you can redistribute it and/or
Packit 8c0394
   modify it under the terms of the GNU Lesser General Public
Packit 8c0394
   License as published by the Free Software Foundation; either
Packit 8c0394
   version 2.1 of the License, or (at your option) any later version.
Packit 8c0394
Packit 8c0394
   The GNU C Library is distributed in the hope that it will be useful,
Packit 8c0394
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8c0394
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 8c0394
   Lesser General Public License for more details.
Packit 8c0394
Packit 8c0394
   You should have received a copy of the GNU Lesser General Public
Packit 8c0394
   License along with the GNU C Library; if not, see
Packit 8c0394
   <http://www.gnu.org/licenses/>.  */
Packit 8c0394
Packit 8c0394
/* This test constructs various patterns in an attempt to trigger
Packit 8c0394
   over-reading the regular expression compiler, such as bug
Packit 8c0394
   23578.  */
Packit 8c0394
Packit 8c0394
#include <array_length.h>
Packit 8c0394
#include <errno.h>
Packit 8c0394
#include <locale.h>
Packit 8c0394
#include <regex.h>
Packit 8c0394
#include <stdio.h>
Packit 8c0394
#include <stdlib.h>
Packit 8c0394
#include <string.h>
Packit 8c0394
#include <support/check.h>
Packit 8c0394
#include <support/next_to_fault.h>
Packit 8c0394
#include <support/support.h>
Packit 8c0394
#include <support/test-driver.h>
Packit 8c0394
#include <wchar.h>
Packit 8c0394
Packit 8c0394
/* Locales to test.  */
Packit 8c0394
static const char locales[][17] =
Packit 8c0394
  {
Packit 8c0394
    "C",
Packit 8c0394
    "en_US.UTF-8",
Packit 8c0394
    "de_DE.ISO-8859-1",
Packit 8c0394
  };
Packit 8c0394
Packit 8c0394
/* Syntax options.  Will be combined with other flags.  */
Packit 8c0394
static const reg_syntax_t syntaxes[] =
Packit 8c0394
  {
Packit 8c0394
    RE_SYNTAX_EMACS,
Packit 8c0394
    RE_SYNTAX_AWK,
Packit 8c0394
    RE_SYNTAX_GNU_AWK,
Packit 8c0394
    RE_SYNTAX_POSIX_AWK,
Packit 8c0394
    RE_SYNTAX_GREP,
Packit 8c0394
    RE_SYNTAX_EGREP,
Packit 8c0394
    RE_SYNTAX_POSIX_EGREP,
Packit 8c0394
    RE_SYNTAX_POSIX_BASIC,
Packit 8c0394
    RE_SYNTAX_POSIX_EXTENDED,
Packit 8c0394
    RE_SYNTAX_POSIX_MINIMAL_EXTENDED,
Packit 8c0394
  };
Packit 8c0394
Packit 8c0394
/* Trailing characters placed after the initial character.  */
Packit 8c0394
static const char trailing_strings[][4] =
Packit 8c0394
  {
Packit 8c0394
    "",
Packit 8c0394
    "[",
Packit 8c0394
    "\\",
Packit 8c0394
    "[\\",
Packit 8c0394
    "(",
Packit 8c0394
    "(\\",
Packit 8c0394
    "\\(",
Packit 8c0394
  };
Packit 8c0394
Packit 8c0394
static int
Packit 8c0394
do_test (void)
Packit 8c0394
{
Packit 8c0394
  /* Staging buffer for the constructed regular expression.  */
Packit 8c0394
  char buffer[16];
Packit 8c0394
Packit 8c0394
  /* Allocation used to detect over-reading by the regular expression
Packit 8c0394
     compiler.  */
Packit 8c0394
  struct support_next_to_fault ntf
Packit 8c0394
    = support_next_to_fault_allocate (sizeof (buffer));
Packit 8c0394
Packit 8c0394
  /* Arbitrary Unicode codepoint at which we stop generating
Packit 8c0394
     characters.  We do not probe the whole range because that would
Packit 8c0394
     take too long due to combinatorical exploision as the result of
Packit 8c0394
     combination with other flags.  */
Packit 8c0394
  static const wchar_t last_character = 0xfff;
Packit 8c0394
Packit 8c0394
  for (size_t locale_idx = 0; locale_idx < array_length (locales);
Packit 8c0394
       ++ locale_idx)
Packit 8c0394
    {
Packit 8c0394
      if (setlocale (LC_ALL, locales[locale_idx]) == NULL)
Packit 8c0394
        {
Packit 8c0394
          support_record_failure ();
Packit 8c0394
          printf ("error: setlocale (\"%s\"): %m", locales[locale_idx]);
Packit 8c0394
          continue;
Packit 8c0394
        }
Packit 8c0394
      if (test_verbose > 0)
Packit 8c0394
        printf ("info: testing locale \"%s\"\n", locales[locale_idx]);
Packit 8c0394
Packit 8c0394
      for (wchar_t wc = 0; wc <= last_character; ++wc)
Packit 8c0394
        {
Packit 8c0394
          char *after_wc;
Packit 8c0394
          if (wc == 0)
Packit 8c0394
            {
Packit 8c0394
              /* wcrtomb treats L'\0' in a special way.  */
Packit 8c0394
              *buffer = '\0';
Packit 8c0394
              after_wc = &buffer[1];
Packit 8c0394
            }
Packit 8c0394
          else
Packit 8c0394
            {
Packit 8c0394
              mbstate_t ps = { };
Packit 8c0394
              size_t ret = wcrtomb (buffer, wc, &ps);
Packit 8c0394
              if (ret == (size_t) -1)
Packit 8c0394
                {
Packit 8c0394
                  /* EILSEQ means that the target character set
Packit 8c0394
                     cannot encode the character.  */
Packit 8c0394
                  if (errno != EILSEQ)
Packit 8c0394
                    {
Packit 8c0394
                      support_record_failure ();
Packit 8c0394
                      printf ("error: wcrtomb (0x%x) failed: %m\n",
Packit 8c0394
                              (unsigned) wc);
Packit 8c0394
                    }
Packit 8c0394
                  continue;
Packit 8c0394
                }
Packit 8c0394
              TEST_VERIFY_EXIT (ret != 0);
Packit 8c0394
              after_wc = &buffer[ret];
Packit 8c0394
            }
Packit 8c0394
Packit 8c0394
          for (size_t trailing_idx = 0;
Packit 8c0394
               trailing_idx < array_length (trailing_strings);
Packit 8c0394
               ++trailing_idx)
Packit 8c0394
            {
Packit 8c0394
              char *after_trailing
Packit 8c0394
                = stpcpy (after_wc, trailing_strings[trailing_idx]);
Packit 8c0394
Packit 8c0394
              for (int do_nul = 0; do_nul < 2; ++do_nul)
Packit 8c0394
                {
Packit 8c0394
                  char *after_nul;
Packit 8c0394
                  if (do_nul)
Packit 8c0394
                    {
Packit 8c0394
                      *after_trailing = '\0';
Packit 8c0394
                      after_nul = &after_trailing[1];
Packit 8c0394
                    }
Packit 8c0394
                  else
Packit 8c0394
                    after_nul = after_trailing;
Packit 8c0394
Packit 8c0394
                  size_t length = after_nul - buffer;
Packit 8c0394
Packit 8c0394
                  /* Make sure that the faulting region starts
Packit 8c0394
                     after the used portion of the buffer.  */
Packit 8c0394
                  char *ntf_start = ntf.buffer + sizeof (buffer) - length;
Packit 8c0394
                  memcpy (ntf_start, buffer, length);
Packit 8c0394
Packit 8c0394
                  for (const reg_syntax_t *psyntax = syntaxes;
Packit 8c0394
                       psyntax < array_end (syntaxes); ++psyntax)
Packit 8c0394
                    for (int do_icase = 0; do_icase < 2; ++do_icase)
Packit 8c0394
                      {
Packit 8c0394
                        re_syntax_options = *psyntax;
Packit 8c0394
                        if (do_icase)
Packit 8c0394
                          re_syntax_options |= RE_ICASE;
Packit 8c0394
Packit 8c0394
                        regex_t reg;
Packit 8c0394
                        memset (&reg, 0, sizeof (reg));
Packit 8c0394
                        const char *msg = re_compile_pattern
Packit 8c0394
                          (ntf_start, length, ®);
Packit 8c0394
                        if (msg != NULL)
Packit 8c0394
                          {
Packit 8c0394
                            if (test_verbose > 0)
Packit 8c0394
                              {
Packit 8c0394
                                char *quoted = support_quote_blob
Packit 8c0394
                                  (buffer, length);
Packit 8c0394
                                printf ("info: compilation failed for pattern"
Packit 8c0394
                                        " \"%s\", syntax 0x%lx: %s\n",
Packit 8c0394
                                        quoted, re_syntax_options, msg);
Packit 8c0394
                                free (quoted);
Packit 8c0394
                              }
Packit 8c0394
                          }
Packit 8c0394
                        else
Packit 8c0394
                          regfree (®);
Packit 8c0394
                      }
Packit 8c0394
                }
Packit 8c0394
            }
Packit 8c0394
        }
Packit 8c0394
    }
Packit 8c0394
Packit 8c0394
  support_next_to_fault_free (&ntf;;
Packit 8c0394
Packit 8c0394
  return 0;
Packit 8c0394
}
Packit 8c0394
Packit 8c0394
#include <support/test-driver.c>