brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · e143c6c Raw
69 lines · cpp
1// RUN: %clangxx -O0 -g %s -o %t && %run %t2/// Check that REG_STARTEND is handled correctly.3/// This is a regression test for https://github.com/google/sanitizers/issues/13714/// Previously, on GLibc systems, the interceptor was calling __compat_regexec5/// (regexec@GLIBC_2.2.5) insead of the newer __regexec (regexec@GLIBC_2.3.4).6/// The __compat_regexec strips the REG_STARTEND flag but does not report an error7/// if other flags are present. This can result in infinite loops for programs that8/// use REG_STARTEND to find all matches inside a buffer (since ignoring REG_STARTEND9/// means that the search always starts from the first character).10 11#include <assert.h>12#include <regex.h>13#include <stdio.h>14#include <stdlib.h>15#include <string.h>16 17/// REG_STARTEND is a BSD extension not supported everywhere.18#ifdef REG_STARTEND19void test_matched(const regex_t *preg, const char *string, size_t start,20                  size_t end, const char *expected) {21  regmatch_t match[1];22  match[0].rm_so = start;23  match[0].rm_eo = end;24  int rv = regexec(preg, string, 1, match, REG_STARTEND);25  int matchlen = (int)(match[0].rm_eo - match[0].rm_so);26  const char *matchstart = string + match[0].rm_so;27  if (rv == 0) {28    if (expected == nullptr) {29      fprintf(stderr, "ERROR: expected no match but got '%.*s'\n",30              matchlen, matchstart);31      abort();32    } else if ((size_t)matchlen != strlen(expected) ||33               memcmp(matchstart, expected, strlen(expected)) != 0) {34      fprintf(stderr, "ERROR: expected '%s' match but got '%.*s'\n",35              expected, matchlen, matchstart);36      abort();37    }38  } else if (rv == REG_NOMATCH) {39    if (expected != nullptr) {40      fprintf(stderr, "ERROR: expected '%s' match but got no match\n", expected);41      abort();42    }43  } else {44    printf("ERROR: unexpected regexec return value %d\n", rv);45    abort();46  }47}48 49int main(void) {50  regex_t regex;51  int rv = regcomp(&regex, "[A-Z][A-Z]", 0);52  assert(!rv);53  test_matched(&regex, "ABCD", 0, 4, "AB");54  test_matched(&regex, "ABCD", 0, 1, nullptr); // Not long enough55  test_matched(&regex, "ABCD", 1, 4, "BC");56  test_matched(&regex, "ABCD", 1, 2, nullptr); // Not long enough57  test_matched(&regex, "ABCD", 2, 4, "CD");58  test_matched(&regex, "ABCD", 2, 3, nullptr); // Not long enough59  test_matched(&regex, "ABCD", 3, 4, nullptr); // Not long enough60  regfree(&regex);61  printf("Successful test\n");62  return 0;63}64#else65int main(void) {66  return 0;67}68#endif69