Go to the documentation of this file.
18 #include "util/util.h"
19 #include "util/flags.h"
20 #include "util/logging.h"
21 #include "util/pcre.h"
22 #include "util/strutil.h"
26 #if defined(__clang__)
27 #elif defined(__GNUC__) && __GNUC__ >= 6
28 #pragma GCC diagnostic ignored "-Wmisleading-indentation"
31 #define PCREPORT(level) LOG(level)
38 DEFINE_int32(regexp_stack_limit, 256<<10,
"default PCRE stack limit (bytes)");
40 "default PCRE match limit (function calls)");
52 #define PCRE_EXTRA_MATCH_LIMIT 0
53 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0
54 #define PCRE_ANCHORED 0
55 #define PCRE_NOTEMPTY 0
56 #define PCRE_ERROR_NOMATCH 1
57 #define PCRE_ERROR_MATCHLIMIT 2
58 #define PCRE_ERROR_RECURSIONLIMIT 3
59 #define PCRE_INFO_CAPTURECOUNT 0
64 pcre*
pcre_compile(
const char*,
int,
const char**,
int*,
const unsigned char*) {
105 int stack_limit,
bool report_errors) {
119 <<
"Error compiling '" <<
pattern <<
"': illegal regexp option";
169 const char*
error =
"";
175 &
error, &eoffset, NULL);
184 &
error, &eoffset, NULL);
212 const Arg& a15)
const {
255 const Arg& a15)
const {
298 const Arg& a15)
const {
323 input->remove_prefix(consumed);
347 const Arg& a15)
const {
372 input->remove_prefix(consumed);
388 if (!
pattern.Rewrite(&s, rewrite, *
str, vec, matches))
393 str->replace(vec[0], vec[1] - vec[0], s);
404 bool last_match_was_empty_string =
false;
406 while (start <= str->
size()) {
418 if (last_match_was_empty_string) {
422 if (start < str->
size())
425 last_match_was_empty_string =
false;
434 size_t matchstart = vec[0], matchend = vec[1];
435 assert(matchstart >=
start);
436 assert(matchend >= matchstart);
442 last_match_was_empty_string = (matchstart == matchend);
448 if (start < str->
size())
478 for (
size_t ii = 0; ii < unquoted.
size(); ++ii) {
481 if ((unquoted[ii] <
'a' || unquoted[ii] >
'z') &&
482 (unquoted[ii] <
'A' || unquoted[ii] >
'Z') &&
483 (unquoted[ii] <
'0' || unquoted[ii] >
'9') &&
484 unquoted[ii] !=
'_' &&
488 !(unquoted[ii] & 128)) {
489 if (unquoted[ii] ==
'\0') {
525 if (match_limit <= 0) {
526 match_limit = FLAGS_regexp_match_limit;
530 if (stack_limit <= 0) {
531 stack_limit = FLAGS_regexp_stack_limit;
535 if (match_limit > 0) {
539 if (stack_limit > 0) {
552 (
text.data() == NULL) ?
"" :
text.data(),
553 static_cast<int>(
text.size()),
554 static_cast<int>(startpos),
576 <<
" when matching '" <<
pattern_ <<
"'"
577 <<
" against text that is " <<
text.size() <<
" bytes.";
583 <<
" when matching '" <<
pattern_ <<
"'"
584 <<
" against text that is " <<
text.size() <<
" bytes.";
596 <<
" when matching '" <<
pattern_ <<
"'"
600 <<
", vecsize=" << vecsize;
615 assert((1 + n) * 3 <= vecsize);
621 int matches =
TryMatch(
text, 0, anchor,
true, vec, vecsize);
622 assert(matches >= 0);
628 if (n == 0 ||
args == NULL) {
636 for (
int i = 0;
i <
n;
i++) {
637 const int start = vec[2*(
i+1)];
638 const int limit = vec[2*(
i+1)+1];
644 const char*
addr = NULL;
664 const int vecsize = (1 +
n) * 3;
666 int* vec =
new int[vecsize];
675 for (
const char *s = rewrite.
data(), *
end = s + rewrite.
size();
683 if (
n <= number_of_capturing_groups) {
688 <<
" in regexp " << rewrite.
data();
695 }
else if (c ==
'\\') {
696 out->push_back(
'\\');
711 for (
const char *s = rewrite.
data(), *
end = s + rewrite.
size();
718 *
error =
"Rewrite schema error: '\\' not allowed at end.";
726 *
error =
"Rewrite schema error: "
727 "'\\' must be followed by a digit or '\\'.";
738 "Rewrite schema requests %d matches, but the regexp only has %d "
739 "parenthesized subexpressions.",
769 return (
dest == NULL);
773 if (
dest == NULL)
return true;
779 if (
dest == NULL)
return true;
785 if (
n != 1)
return false;
786 if (
dest == NULL)
return true;
787 *(
reinterpret_cast<char*
>(
dest)) =
str[0];
792 if (
n != 1)
return false;
793 if (
dest == NULL)
return true;
794 *(
reinterpret_cast<signed char*
>(
dest)) =
str[0];
799 if (
n != 1)
return false;
800 if (
dest == NULL)
return true;
801 *(
reinterpret_cast<unsigned char*
>(
dest)) =
str[0];
816 if ((
n > 0) && isspace(*
str)) {
824 if (isdigit(
str[
n]) ||
825 ((
str[
n] >=
'a') && (
str[
n] <=
'f')) ||
826 ((
str[
n] >=
'A') && (
str[
n] <=
'F'))) {
837 bool PCRE::Arg::parse_long_radix(
const char*
str,
841 if (n == 0)
return false;
847 if (
end !=
str + n)
return false;
848 if (errno)
return false;
849 if (
dest == NULL)
return true;
850 *(
reinterpret_cast<long*
>(
dest)) =
r;
854 bool PCRE::Arg::parse_ulong_radix(
const char*
str,
858 if (n == 0)
return false;
870 if (
end !=
str + n)
return false;
871 if (errno)
return false;
872 if (
dest == NULL)
return true;
873 *(
reinterpret_cast<unsigned long*
>(
dest)) =
r;
877 bool PCRE::Arg::parse_short_radix(
const char*
str,
882 if (!parse_long_radix(
str, n, &
r,
radix))
return false;
883 if ((
short)
r !=
r)
return false;
884 if (
dest == NULL)
return true;
885 *(
reinterpret_cast<short*
>(
dest)) = (short)
r;
889 bool PCRE::Arg::parse_ushort_radix(
const char*
str,
894 if (!parse_ulong_radix(
str, n, &
r,
radix))
return false;
895 if ((
unsigned short)
r !=
r)
return false;
896 if (
dest == NULL)
return true;
897 *(
reinterpret_cast<unsigned short*
>(
dest)) = (
unsigned short)
r;
901 bool PCRE::Arg::parse_int_radix(
const char*
str,
906 if (!parse_long_radix(
str, n, &
r,
radix))
return false;
907 if ((
int)
r !=
r)
return false;
908 if (
dest == NULL)
return true;
909 *(
reinterpret_cast<int*
>(
dest)) = (
int)
r;
913 bool PCRE::Arg::parse_uint_radix(
const char*
str,
918 if (!parse_ulong_radix(
str, n, &
r,
radix))
return false;
919 if ((
unsigned int)
r !=
r)
return false;
920 if (
dest == NULL)
return true;
921 *(
reinterpret_cast<unsigned int*
>(
dest)) = (
unsigned int)
r;
925 bool PCRE::Arg::parse_longlong_radix(
const char*
str,
929 if (n == 0)
return false;
935 if (
end !=
str + n)
return false;
936 if (errno)
return false;
937 if (
dest == NULL)
return true;
938 *(
reinterpret_cast<long long*
>(
dest)) =
r;
942 bool PCRE::Arg::parse_ulonglong_radix(
const char*
str,
946 if (n == 0)
return false;
957 if (
end !=
str + n)
return false;
958 if (errno)
return false;
959 if (
dest == NULL)
return true;
960 *(
reinterpret_cast<unsigned long long*
>(
dest)) =
r;
966 if (
n == 0)
return false;
967 static const int kMaxLength = 200;
968 char buf[kMaxLength];
969 if (
n >= kMaxLength)
return false;
990 }
else if (
'+' == *
i) {
993 if (0 == _stricmp(
i,
"inf") || 0 == _stricmp(
i,
"infinity")) {
994 r = std::numeric_limits<double>::infinity();
997 }
else if (0 == _stricmp(
i,
"nan")) {
998 r = std::numeric_limits<double>::quiet_NaN();
1006 if (errno)
return false;
1007 if (
dest == NULL)
return true;
1009 *(
reinterpret_cast<float*
>(
dest)) = (float)
r;
1011 *(
reinterpret_cast<double*
>(
dest)) =
r;
1024 #define DEFINE_INTEGER_PARSER(name) \
1025 bool PCRE::Arg::parse_##name(const char* str, size_t n, void* dest) { \
1026 return parse_##name##_radix(str, n, dest, 10); \
1028 bool PCRE::Arg::parse_##name##_hex(const char* str, size_t n, void* dest) { \
1029 return parse_##name##_radix(str, n, dest, 16); \
1031 bool PCRE::Arg::parse_##name##_octal(const char* str, size_t n, \
1033 return parse_##name##_radix(str, n, dest, 8); \
1035 bool PCRE::Arg::parse_##name##_cradix(const char* str, size_t n, \
1037 return parse_##name##_radix(str, n, dest, 0); \
1049 #undef DEFINE_INTEGER_PARSER
static bool parse_null(const char *str, size_t n, void *dest)
#define PCRE_EXTRA_MATCH_LIMIT
static bool parse_stringpiece(const char *str, size_t n, void *dest)
#define PCRE_ERROR_RECURSIONLIMIT
static int GlobalReplace(std::string *str, const PCRE &pattern, const StringPiece &rewrite)
bool operator()(const StringPiece &text, const PCRE &re, const Arg &ptr1=no_more_args, const Arg &ptr2=no_more_args, const Arg &ptr3=no_more_args, const Arg &ptr4=no_more_args, const Arg &ptr5=no_more_args, const Arg &ptr6=no_more_args, const Arg &ptr7=no_more_args, const Arg &ptr8=no_more_args, const Arg &ptr9=no_more_args, const Arg &ptr10=no_more_args, const Arg &ptr11=no_more_args, const Arg &ptr12=no_more_args, const Arg &ptr13=no_more_args, const Arg &ptr14=no_more_args, const Arg &ptr15=no_more_args, const Arg &ptr16=no_more_args) const
static const PartialMatchFunctor PartialMatch
bool Rewrite(std::string *out, const StringPiece &rewrite, const StringPiece &text, int *vec, int veclen) const
const std::string & error() const
static bool parse_string(const char *str, size_t n, void *dest)
bool report_errors() const
Arg(64) -> Arg(128) ->Arg(256) ->Arg(512) ->Arg(1024) ->Arg(1536) ->Arg(2048) ->Arg(3072) ->Arg(4096) ->Arg(5120) ->Arg(6144) ->Arg(7168)
static bool parse_float(const char *str, size_t n, void *dest)
#define PCRE_EXTRA_MATCH_LIMIT_RECURSION
static bool parse_double(const char *str, size_t n, void *dest)
static std::string QuoteMeta(const StringPiece &unquoted)
int NumberOfCapturingGroups() const
static const FullMatchFunctor FullMatch
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
PCRE::Option option() const
static const int kVecSize
std::string StringPrintf(const char *format,...)
bool operator()(const StringPiece &text, const PCRE &re, const Arg &ptr1=no_more_args, const Arg &ptr2=no_more_args, const Arg &ptr3=no_more_args, const Arg &ptr4=no_more_args, const Arg &ptr5=no_more_args, const Arg &ptr6=no_more_args, const Arg &ptr7=no_more_args, const Arg &ptr8=no_more_args, const Arg &ptr9=no_more_args, const Arg &ptr10=no_more_args, const Arg &ptr11=no_more_args, const Arg &ptr12=no_more_args, const Arg &ptr13=no_more_args, const Arg &ptr14=no_more_args, const Arg &ptr15=no_more_args, const Arg &ptr16=no_more_args) const
static bool parse_double_float(const char *str, size_t n, bool isfloat, void *dest)
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
bool operator()(StringPiece *input, const PCRE &pattern, const Arg &ptr1=no_more_args, const Arg &ptr2=no_more_args, const Arg &ptr3=no_more_args, const Arg &ptr4=no_more_args, const Arg &ptr5=no_more_args, const Arg &ptr6=no_more_args, const Arg &ptr7=no_more_args, const Arg &ptr8=no_more_args, const Arg &ptr9=no_more_args, const Arg &ptr10=no_more_args, const Arg &ptr11=no_more_args, const Arg &ptr12=no_more_args, const Arg &ptr13=no_more_args, const Arg &ptr14=no_more_args, const Arg &ptr15=no_more_args, const Arg &ptr16=no_more_args) const
bool Parse(FlagOpFn op, absl::string_view text, void *dst, std::string *error)
static const LogLevel WARNING
static const LogLevel ERROR
int pcre_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int)
#define PCRE_INFO_CAPTURECOUNT
bool DoMatch(const StringPiece &text, Anchor anchor, size_t *consumed, const Arg *const *args, int n) const
static const int kPCREFrameSize
pcre * Compile(Anchor anchor)
DEFINE_INTEGER_PARSER(short)
const_pointer data() const
static bool parse_char(const char *str, size_t n, void *dest)
PCRE(const char *pattern)
DEFINE_int32(regexp_stack_limit, 256<< 10, "default PCRE stack limit (bytes)")
static bool Extract(const StringPiece &text, const PCRE &pattern, const StringPiece &rewrite, std::string *out)
static const int kMaxNumberLength
pcre * pcre_compile(const char *, int, const char **, int *, const unsigned char *)
#define PCRE_ERROR_MATCHLIMIT
int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *)
#define PCRE_ERROR_NOMATCH
static bool parse_schar(const char *str, size_t n, void *dest)
const std::string & pattern() const
static const std::string * empty_string
static const int kMaxArgs
static const FindAndConsumeFunctor FindAndConsume
bool operator()(StringPiece *input, const PCRE &pattern, const Arg &ptr1=no_more_args, const Arg &ptr2=no_more_args, const Arg &ptr3=no_more_args, const Arg &ptr4=no_more_args, const Arg &ptr5=no_more_args, const Arg &ptr6=no_more_args, const Arg &ptr7=no_more_args, const Arg &ptr8=no_more_args, const Arg &ptr9=no_more_args, const Arg &ptr10=no_more_args, const Arg &ptr11=no_more_args, const Arg &ptr12=no_more_args, const Arg &ptr13=no_more_args, const Arg &ptr14=no_more_args, const Arg &ptr15=no_more_args, const Arg &ptr16=no_more_args) const
static const char * TerminateNumber(char *buf, size_t nbuf, const char *str, size_t *np, bool accept_spaces)
static const ConsumeFunctor Consume
bool DoMatchImpl(const StringPiece &text, Anchor anchor, size_t *consumed, const Arg *const args[], int n, int *vec, int vecsize) const
const std::string * error_
int TryMatch(const StringPiece &text, size_t startpos, Anchor anchor, bool empty_ok, int *vec, int vecsize) const
void Init(const char *pattern, Option option, int match_limit, int stack_limit, bool report_errors)
static bool Replace(std::string *str, const PCRE &pattern, const StringPiece &rewrite)
bool CheckRewriteString(const StringPiece &rewrite, std::string *error) const
static bool parse_uchar(const char *str, size_t n, void *dest)
grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:41