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"
25 #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 6
26 #pragma GCC diagnostic ignored "-Wmisleading-indentation"
29 #define PCREPORT(level) LOG(level)
37 "default PCRE stack limit (bytes)");
39 "default PCRE match limit (function calls)");
51 #define PCRE_EXTRA_MATCH_LIMIT 0
52 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0
53 #define PCRE_ANCHORED 0
54 #define PCRE_NOTEMPTY 0
55 #define PCRE_ERROR_NOMATCH 1
56 #define PCRE_ERROR_MATCHLIMIT 2
57 #define PCRE_ERROR_RECURSIONLIMIT 3
58 #define PCRE_INFO_CAPTURECOUNT 0
63 pcre*
pcre_compile(
const char*,
int,
const char**,
int*,
const unsigned char*) {
104 int stack_limit,
bool report_errors) {
118 <<
"Error compiling '" <<
pattern <<
"': illegal regexp option";
140 Init(
pattern.c_str(), re_option.option(), re_option.match_limit(),
141 re_option.stack_limit(), re_option.report_errors());
145 Init(
pattern, re_option.option(), re_option.match_limit(),
146 re_option.stack_limit(), re_option.report_errors());
168 const char*
error =
"";
174 &
error, &eoffset, NULL);
183 &
error, &eoffset, NULL);
211 const Arg& a15)
const {
254 const Arg& a15)
const {
297 const Arg& a15)
const {
322 input->remove_prefix(consumed);
346 const Arg& a15)
const {
371 input->remove_prefix(consumed);
380 const StringPiece& rewrite) {
387 if (!
pattern.Rewrite(&s, rewrite, *
str, vec, matches))
392 str->replace(vec[0], vec[1] - vec[0], s);
398 const StringPiece& rewrite) {
403 bool last_match_was_empty_string =
false;
405 while (start <= str->
size()) {
417 if (last_match_was_empty_string) {
421 if (start < str->
size())
424 last_match_was_empty_string =
false;
433 size_t matchstart = vec[0], matchend = vec[1];
434 assert(matchstart >=
start);
435 assert(matchend >= matchstart);
441 last_match_was_empty_string = (matchstart == matchend);
447 if (start < str->
size())
456 const StringPiece &rewrite,
468 result.reserve(unquoted.size() << 1);
477 for (
size_t ii = 0; ii < unquoted.size(); ++ii) {
480 if ((unquoted[ii] <
'a' || unquoted[ii] >
'z') &&
481 (unquoted[ii] <
'A' || unquoted[ii] >
'Z') &&
482 (unquoted[ii] <
'0' || unquoted[ii] >
'9') &&
483 unquoted[ii] !=
'_' &&
487 !(unquoted[ii] & 128)) {
488 if (unquoted[ii] ==
'\0') {
524 if (match_limit <= 0) {
525 match_limit =
GetFlag(FLAGS_regexp_match_limit);
529 if (stack_limit <= 0) {
530 stack_limit =
GetFlag(FLAGS_regexp_stack_limit);
534 if (match_limit > 0) {
538 if (stack_limit > 0) {
551 (
text.data() == NULL) ?
"" :
text.data(),
552 static_cast<int>(
text.size()),
553 static_cast<int>(startpos),
575 <<
" when matching '" <<
pattern_ <<
"'"
576 <<
" against text that is " <<
text.size() <<
" bytes.";
582 <<
" when matching '" <<
pattern_ <<
"'"
583 <<
" against text that is " <<
text.size() <<
" bytes.";
595 <<
" when matching '" <<
pattern_ <<
"'"
599 <<
", vecsize=" << vecsize;
614 assert((1 + n) * 3 <= vecsize);
620 int matches =
TryMatch(
text, 0, anchor,
true, vec, vecsize);
621 assert(matches >= 0);
627 if (n == 0 ||
args == NULL) {
635 for (
int i = 0;
i <
n;
i++) {
636 const int start = vec[2*(
i+1)];
637 const int limit = vec[2*(
i+1)+1];
643 const char*
addr = NULL;
663 const int vecsize = (1 +
n) * 3;
665 int* vec =
new int[vecsize];
672 const StringPiece &
text,
int *vec,
int veclen)
const {
674 for (
const char *s = rewrite.data(), *
end = s + rewrite.size();
682 if (n <= number_of_capturing_groups) {
687 <<
" in regexp " << rewrite.data();
694 }
else if (c ==
'\\') {
695 out->push_back(
'\\');
697 PCREPORT(
ERROR) <<
"invalid rewrite pattern: " << rewrite.data();
710 for (
const char *s = rewrite.data(), *
end = s + rewrite.size();
717 *
error =
"Rewrite schema error: '\\' not allowed at end.";
725 *
error =
"Rewrite schema error: "
726 "'\\' must be followed by a digit or '\\'.";
737 "Rewrite schema requests %d matches, but the regexp only has %d "
738 "parenthesized subexpressions.",
768 return (
dest == NULL);
772 if (
dest == NULL)
return true;
778 if (
dest == NULL)
return true;
779 *(
reinterpret_cast<StringPiece*
>(
dest)) = StringPiece(
str, n);
784 if (n != 1)
return false;
785 if (
dest == NULL)
return true;
786 *(
reinterpret_cast<char*
>(
dest)) =
str[0];
791 if (n != 1)
return false;
792 if (
dest == NULL)
return true;
793 *(
reinterpret_cast<signed char*
>(
dest)) =
str[0];
798 if (n != 1)
return false;
799 if (
dest == NULL)
return true;
800 *(
reinterpret_cast<unsigned char*
>(
dest)) =
str[0];
815 if ((
n > 0) && isspace(*
str)) {
823 if (isdigit(
str[
n]) ||
824 ((
str[
n] >=
'a') && (
str[
n] <=
'f')) ||
825 ((
str[
n] >=
'A') && (
str[
n] <=
'F'))) {
836 bool PCRE::Arg::parse_long_radix(
const char*
str,
840 if (n == 0)
return false;
846 if (
end !=
str + n)
return false;
847 if (errno)
return false;
848 if (
dest == NULL)
return true;
849 *(
reinterpret_cast<long*
>(
dest)) =
r;
853 bool PCRE::Arg::parse_ulong_radix(
const char*
str,
857 if (n == 0)
return false;
869 if (
end !=
str + n)
return false;
870 if (errno)
return false;
871 if (
dest == NULL)
return true;
872 *(
reinterpret_cast<unsigned long*
>(
dest)) =
r;
876 bool PCRE::Arg::parse_short_radix(
const char*
str,
881 if (!parse_long_radix(
str, n, &
r,
radix))
return false;
882 if ((
short)
r !=
r)
return false;
883 if (
dest == NULL)
return true;
884 *(
reinterpret_cast<short*
>(
dest)) = (short)
r;
888 bool PCRE::Arg::parse_ushort_radix(
const char*
str,
893 if (!parse_ulong_radix(
str, n, &
r,
radix))
return false;
894 if ((
unsigned short)
r !=
r)
return false;
895 if (
dest == NULL)
return true;
896 *(
reinterpret_cast<unsigned short*
>(
dest)) = (
unsigned short)
r;
900 bool PCRE::Arg::parse_int_radix(
const char*
str,
905 if (!parse_long_radix(
str, n, &
r,
radix))
return false;
906 if ((
int)
r !=
r)
return false;
907 if (
dest == NULL)
return true;
908 *(
reinterpret_cast<int*
>(
dest)) = (
int)
r;
912 bool PCRE::Arg::parse_uint_radix(
const char*
str,
917 if (!parse_ulong_radix(
str, n, &
r,
radix))
return false;
918 if ((
unsigned int)
r !=
r)
return false;
919 if (
dest == NULL)
return true;
920 *(
reinterpret_cast<unsigned int*
>(
dest)) = (
unsigned int)
r;
924 bool PCRE::Arg::parse_longlong_radix(
const char*
str,
928 if (n == 0)
return false;
934 if (
end !=
str + n)
return false;
935 if (errno)
return false;
936 if (
dest == NULL)
return true;
937 *(
reinterpret_cast<long long*
>(
dest)) =
r;
941 bool PCRE::Arg::parse_ulonglong_radix(
const char*
str,
945 if (n == 0)
return false;
956 if (
end !=
str + n)
return false;
957 if (errno)
return false;
958 if (
dest == NULL)
return true;
959 *(
reinterpret_cast<unsigned long long*
>(
dest)) =
r;
965 if (
n == 0)
return false;
966 static const int kMaxLength = 200;
967 char buf[kMaxLength];
968 if (
n >= kMaxLength)
return false;
979 if (
end !=
buf +
n)
return false;
980 if (errno)
return false;
981 if (
dest == NULL)
return true;
983 *(
reinterpret_cast<float*
>(
dest)) = (float)
r;
985 *(
reinterpret_cast<double*
>(
dest)) =
r;
998 #define DEFINE_INTEGER_PARSER(name) \
999 bool PCRE::Arg::parse_##name(const char* str, size_t n, void* dest) { \
1000 return parse_##name##_radix(str, n, dest, 10); \
1002 bool PCRE::Arg::parse_##name##_hex(const char* str, size_t n, void* dest) { \
1003 return parse_##name##_radix(str, n, dest, 16); \
1005 bool PCRE::Arg::parse_##name##_octal(const char* str, size_t n, \
1007 return parse_##name##_radix(str, n, dest, 8); \
1009 bool PCRE::Arg::parse_##name##_cradix(const char* str, size_t n, \
1011 return parse_##name##_radix(str, n, dest, 0); \
1023 #undef DEFINE_INTEGER_PARSER
static bool parse_null(const char *str, size_t n, void *dest)
#define PCRE_ERROR_RECURSIONLIMIT
int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *)
static bool parse_stringpiece(const char *str, size_t n, void *dest)
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
#define PCRE_INFO_CAPTURECOUNT
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)
int pcre_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int)
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)
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 * pcre_compile(const char *, int, const char **, int *, const unsigned char *)
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
#define PCRE_ERROR_MATCHLIMIT
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
#define PCRE_ERROR_NOMATCH
static const LogLevel ERROR
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)
static bool parse_char(const char *str, size_t n, void *dest)
PCRE(const char *pattern)
static bool Extract(const StringPiece &text, const PCRE &pattern, const StringPiece &rewrite, std::string *out)
static const int kMaxNumberLength
#define PCRE_EXTRA_MATCH_LIMIT
static bool parse_schar(const char *str, size_t n, void *dest)
const std::string & pattern() const
#define PCRE_EXTRA_MATCH_LIMIT_RECURSION
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)
DEFINE_FLAG(int, regexp_stack_limit, 256<< 10, "default PCRE stack limit (bytes)")
grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:41