re2/util/pcre.cc
Go to the documentation of this file.
1 // Copyright 2003-2009 Google Inc. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 
5 // This is a variant of PCRE's pcrecpp.cc, originally written at Google.
6 // The main changes are the addition of the HitLimit method and
7 // compilation as PCRE in namespace re2.
8 
9 #include <assert.h>
10 #include <ctype.h>
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <limits>
15 #include <string>
16 #include <utility>
17 
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"
23 
24 // Silence warnings about the wacky formatting in the operator() functions.
25 #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 6
26 #pragma GCC diagnostic ignored "-Wmisleading-indentation"
27 #endif
28 
29 #define PCREPORT(level) LOG(level)
30 
31 // Default PCRE limits.
32 // Defaults chosen to allow a plausible amount of CPU and
33 // not exceed main thread stacks. Note that other threads
34 // often have smaller stacks, and therefore tightening
35 // regexp_stack_limit may frequently be necessary.
36 DEFINE_FLAG(int, regexp_stack_limit, 256 << 10,
37  "default PCRE stack limit (bytes)");
38 DEFINE_FLAG(int, regexp_match_limit, 1000000,
39  "default PCRE match limit (function calls)");
40 
41 #ifndef USEPCRE
42 
43 // Fake just enough of the PCRE API to allow this file to build. :)
44 
45 struct pcre_extra {
46  int flags;
47  int match_limit;
49 };
50 
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
59 
60 void pcre_free(void*) {
61 }
62 
63 pcre* pcre_compile(const char*, int, const char**, int*, const unsigned char*) {
64  return NULL;
65 }
66 
67 int pcre_exec(const pcre*, const pcre_extra*, const char*, int, int, int, int*, int) {
68  return 0;
69 }
70 
71 int pcre_fullinfo(const pcre*, const pcre_extra*, int, void*) {
72  return 0;
73 }
74 
75 #endif
76 
77 namespace re2 {
78 
79 // Maximum number of args we can set
80 static const int kMaxArgs = 16;
81 static const int kVecSize = (1 + kMaxArgs) * 3; // results + PCRE workspace
82 
83 // Approximate size of a recursive invocation of PCRE's
84 // internal "match()" frame. This varies depending on the
85 // compiler and architecture, of course, so the constant is
86 // just a conservative estimate. To find the exact number,
87 // run regexp_unittest with --regexp_stack_limit=0 under
88 // a debugger and look at the frames when it crashes.
89 // The exact frame size was 656 in production on 2008/02/03.
90 static const int kPCREFrameSize = 700;
91 
92 // Special name for missing C++ arguments.
93 PCRE::Arg PCRE::no_more_args((void*)NULL);
94 
96 const PCRE::FullMatchFunctor PCRE::FullMatch = { } ;
97 const PCRE::ConsumeFunctor PCRE::Consume = { };
98 const PCRE::FindAndConsumeFunctor PCRE::FindAndConsume = { };
99 
100 // If a regular expression has no error, its error_ field points here
102 
103 void PCRE::Init(const char* pattern, Option options, int match_limit,
104  int stack_limit, bool report_errors) {
105  pattern_ = pattern;
106  options_ = options;
107  match_limit_ = match_limit;
108  stack_limit_ = stack_limit;
109  hit_limit_ = false;
110  error_ = &empty_string;
111  report_errors_ = report_errors;
112  re_full_ = NULL;
113  re_partial_ = NULL;
114 
116  error_ = new std::string("illegal regexp option");
117  PCREPORT(ERROR)
118  << "Error compiling '" << pattern << "': illegal regexp option";
119  } else {
121  if (re_partial_ != NULL) {
123  }
124  }
125 }
126 
127 PCRE::PCRE(const char* pattern) {
128  Init(pattern, None, 0, 0, true);
129 }
130 PCRE::PCRE(const char* pattern, Option option) {
131  Init(pattern, option, 0, 0, true);
132 }
134  Init(pattern.c_str(), None, 0, 0, true);
135 }
137  Init(pattern.c_str(), option, 0, 0, true);
138 }
139 PCRE::PCRE(const std::string& pattern, const PCRE_Options& re_option) {
140  Init(pattern.c_str(), re_option.option(), re_option.match_limit(),
141  re_option.stack_limit(), re_option.report_errors());
142 }
143 
144 PCRE::PCRE(const char *pattern, const PCRE_Options& re_option) {
145  Init(pattern, re_option.option(), re_option.match_limit(),
146  re_option.stack_limit(), re_option.report_errors());
147 }
148 
149 PCRE::~PCRE() {
150  if (re_full_ != NULL) pcre_free(re_full_);
151  if (re_partial_ != NULL) pcre_free(re_partial_);
152  if (error_ != &empty_string) delete error_;
153 }
154 
155 pcre* PCRE::Compile(Anchor anchor) {
156  // Special treatment for anchoring. This is needed because at
157  // runtime pcre only provides an option for anchoring at the
158  // beginning of a string.
159  //
160  // There are three types of anchoring we want:
161  // UNANCHORED Compile the original pattern, and use
162  // a pcre unanchored match.
163  // ANCHOR_START Compile the original pattern, and use
164  // a pcre anchored match.
165  // ANCHOR_BOTH Tack a "\z" to the end of the original pattern
166  // and use a pcre anchored match.
167 
168  const char* error = "";
169  int eoffset;
170  pcre* re;
171  if (anchor != ANCHOR_BOTH) {
172  re = pcre_compile(pattern_.c_str(),
174  &error, &eoffset, NULL);
175  } else {
176  // Tack a '\z' at the end of PCRE. Parenthesize it first so that
177  // the '\z' applies to all top-level alternatives in the regexp.
178  std::string wrapped = "(?:"; // A non-counting grouping operator
179  wrapped += pattern_;
180  wrapped += ")\\z";
181  re = pcre_compile(wrapped.c_str(),
183  &error, &eoffset, NULL);
184  }
185  if (re == NULL) {
186  if (error_ == &empty_string) error_ = new std::string(error);
187  PCREPORT(ERROR) << "Error compiling '" << pattern_ << "': " << error;
188  }
189  return re;
190 }
191 
192 /***** Convenience interfaces *****/
193 
194 bool PCRE::FullMatchFunctor::operator ()(const StringPiece& text,
195  const PCRE& re,
196  const Arg& a0,
197  const Arg& a1,
198  const Arg& a2,
199  const Arg& a3,
200  const Arg& a4,
201  const Arg& a5,
202  const Arg& a6,
203  const Arg& a7,
204  const Arg& a8,
205  const Arg& a9,
206  const Arg& a10,
207  const Arg& a11,
208  const Arg& a12,
209  const Arg& a13,
210  const Arg& a14,
211  const Arg& a15) const {
212  const Arg* args[kMaxArgs];
213  int n = 0;
214  if (&a0 == &no_more_args) goto done; args[n++] = &a0;
215  if (&a1 == &no_more_args) goto done; args[n++] = &a1;
216  if (&a2 == &no_more_args) goto done; args[n++] = &a2;
217  if (&a3 == &no_more_args) goto done; args[n++] = &a3;
218  if (&a4 == &no_more_args) goto done; args[n++] = &a4;
219  if (&a5 == &no_more_args) goto done; args[n++] = &a5;
220  if (&a6 == &no_more_args) goto done; args[n++] = &a6;
221  if (&a7 == &no_more_args) goto done; args[n++] = &a7;
222  if (&a8 == &no_more_args) goto done; args[n++] = &a8;
223  if (&a9 == &no_more_args) goto done; args[n++] = &a9;
224  if (&a10 == &no_more_args) goto done; args[n++] = &a10;
225  if (&a11 == &no_more_args) goto done; args[n++] = &a11;
226  if (&a12 == &no_more_args) goto done; args[n++] = &a12;
227  if (&a13 == &no_more_args) goto done; args[n++] = &a13;
228  if (&a14 == &no_more_args) goto done; args[n++] = &a14;
229  if (&a15 == &no_more_args) goto done; args[n++] = &a15;
230 done:
231 
232  size_t consumed;
233  int vec[kVecSize] = {};
234  return re.DoMatchImpl(text, ANCHOR_BOTH, &consumed, args, n, vec, kVecSize);
235 }
236 
237 bool PCRE::PartialMatchFunctor::operator ()(const StringPiece& text,
238  const PCRE& re,
239  const Arg& a0,
240  const Arg& a1,
241  const Arg& a2,
242  const Arg& a3,
243  const Arg& a4,
244  const Arg& a5,
245  const Arg& a6,
246  const Arg& a7,
247  const Arg& a8,
248  const Arg& a9,
249  const Arg& a10,
250  const Arg& a11,
251  const Arg& a12,
252  const Arg& a13,
253  const Arg& a14,
254  const Arg& a15) const {
255  const Arg* args[kMaxArgs];
256  int n = 0;
257  if (&a0 == &no_more_args) goto done; args[n++] = &a0;
258  if (&a1 == &no_more_args) goto done; args[n++] = &a1;
259  if (&a2 == &no_more_args) goto done; args[n++] = &a2;
260  if (&a3 == &no_more_args) goto done; args[n++] = &a3;
261  if (&a4 == &no_more_args) goto done; args[n++] = &a4;
262  if (&a5 == &no_more_args) goto done; args[n++] = &a5;
263  if (&a6 == &no_more_args) goto done; args[n++] = &a6;
264  if (&a7 == &no_more_args) goto done; args[n++] = &a7;
265  if (&a8 == &no_more_args) goto done; args[n++] = &a8;
266  if (&a9 == &no_more_args) goto done; args[n++] = &a9;
267  if (&a10 == &no_more_args) goto done; args[n++] = &a10;
268  if (&a11 == &no_more_args) goto done; args[n++] = &a11;
269  if (&a12 == &no_more_args) goto done; args[n++] = &a12;
270  if (&a13 == &no_more_args) goto done; args[n++] = &a13;
271  if (&a14 == &no_more_args) goto done; args[n++] = &a14;
272  if (&a15 == &no_more_args) goto done; args[n++] = &a15;
273 done:
274 
275  size_t consumed;
276  int vec[kVecSize] = {};
277  return re.DoMatchImpl(text, UNANCHORED, &consumed, args, n, vec, kVecSize);
278 }
279 
280 bool PCRE::ConsumeFunctor::operator ()(StringPiece* input,
281  const PCRE& pattern,
282  const Arg& a0,
283  const Arg& a1,
284  const Arg& a2,
285  const Arg& a3,
286  const Arg& a4,
287  const Arg& a5,
288  const Arg& a6,
289  const Arg& a7,
290  const Arg& a8,
291  const Arg& a9,
292  const Arg& a10,
293  const Arg& a11,
294  const Arg& a12,
295  const Arg& a13,
296  const Arg& a14,
297  const Arg& a15) const {
298  const Arg* args[kMaxArgs];
299  int n = 0;
300  if (&a0 == &no_more_args) goto done; args[n++] = &a0;
301  if (&a1 == &no_more_args) goto done; args[n++] = &a1;
302  if (&a2 == &no_more_args) goto done; args[n++] = &a2;
303  if (&a3 == &no_more_args) goto done; args[n++] = &a3;
304  if (&a4 == &no_more_args) goto done; args[n++] = &a4;
305  if (&a5 == &no_more_args) goto done; args[n++] = &a5;
306  if (&a6 == &no_more_args) goto done; args[n++] = &a6;
307  if (&a7 == &no_more_args) goto done; args[n++] = &a7;
308  if (&a8 == &no_more_args) goto done; args[n++] = &a8;
309  if (&a9 == &no_more_args) goto done; args[n++] = &a9;
310  if (&a10 == &no_more_args) goto done; args[n++] = &a10;
311  if (&a11 == &no_more_args) goto done; args[n++] = &a11;
312  if (&a12 == &no_more_args) goto done; args[n++] = &a12;
313  if (&a13 == &no_more_args) goto done; args[n++] = &a13;
314  if (&a14 == &no_more_args) goto done; args[n++] = &a14;
315  if (&a15 == &no_more_args) goto done; args[n++] = &a15;
316 done:
317 
318  size_t consumed;
319  int vec[kVecSize] = {};
320  if (pattern.DoMatchImpl(*input, ANCHOR_START, &consumed,
321  args, n, vec, kVecSize)) {
322  input->remove_prefix(consumed);
323  return true;
324  } else {
325  return false;
326  }
327 }
328 
330  const PCRE& pattern,
331  const Arg& a0,
332  const Arg& a1,
333  const Arg& a2,
334  const Arg& a3,
335  const Arg& a4,
336  const Arg& a5,
337  const Arg& a6,
338  const Arg& a7,
339  const Arg& a8,
340  const Arg& a9,
341  const Arg& a10,
342  const Arg& a11,
343  const Arg& a12,
344  const Arg& a13,
345  const Arg& a14,
346  const Arg& a15) const {
347  const Arg* args[kMaxArgs];
348  int n = 0;
349  if (&a0 == &no_more_args) goto done; args[n++] = &a0;
350  if (&a1 == &no_more_args) goto done; args[n++] = &a1;
351  if (&a2 == &no_more_args) goto done; args[n++] = &a2;
352  if (&a3 == &no_more_args) goto done; args[n++] = &a3;
353  if (&a4 == &no_more_args) goto done; args[n++] = &a4;
354  if (&a5 == &no_more_args) goto done; args[n++] = &a5;
355  if (&a6 == &no_more_args) goto done; args[n++] = &a6;
356  if (&a7 == &no_more_args) goto done; args[n++] = &a7;
357  if (&a8 == &no_more_args) goto done; args[n++] = &a8;
358  if (&a9 == &no_more_args) goto done; args[n++] = &a9;
359  if (&a10 == &no_more_args) goto done; args[n++] = &a10;
360  if (&a11 == &no_more_args) goto done; args[n++] = &a11;
361  if (&a12 == &no_more_args) goto done; args[n++] = &a12;
362  if (&a13 == &no_more_args) goto done; args[n++] = &a13;
363  if (&a14 == &no_more_args) goto done; args[n++] = &a14;
364  if (&a15 == &no_more_args) goto done; args[n++] = &a15;
365 done:
366 
367  size_t consumed;
368  int vec[kVecSize] = {};
369  if (pattern.DoMatchImpl(*input, UNANCHORED, &consumed,
370  args, n, vec, kVecSize)) {
371  input->remove_prefix(consumed);
372  return true;
373  } else {
374  return false;
375  }
376 }
377 
379  const PCRE& pattern,
380  const StringPiece& rewrite) {
381  int vec[kVecSize] = {};
382  int matches = pattern.TryMatch(*str, 0, UNANCHORED, true, vec, kVecSize);
383  if (matches == 0)
384  return false;
385 
386  std::string s;
387  if (!pattern.Rewrite(&s, rewrite, *str, vec, matches))
388  return false;
389 
390  assert(vec[0] >= 0);
391  assert(vec[1] >= 0);
392  str->replace(vec[0], vec[1] - vec[0], s);
393  return true;
394 }
395 
397  const PCRE& pattern,
398  const StringPiece& rewrite) {
399  int count = 0;
400  int vec[kVecSize] = {};
402  size_t start = 0;
403  bool last_match_was_empty_string = false;
404 
405  while (start <= str->size()) {
406  // If the previous match was for the empty string, we shouldn't
407  // just match again: we'll match in the same way and get an
408  // infinite loop. Instead, we do the match in a special way:
409  // anchored -- to force another try at the same position --
410  // and with a flag saying that this time, ignore empty matches.
411  // If this special match returns, that means there's a non-empty
412  // match at this position as well, and we can continue. If not,
413  // we do what perl does, and just advance by one.
414  // Notice that perl prints '@@@' for this;
415  // perl -le '$_ = "aa"; s/b*|aa/@/g; print'
416  int matches;
417  if (last_match_was_empty_string) {
418  matches = pattern.TryMatch(*str, start, ANCHOR_START, false,
419  vec, kVecSize);
420  if (matches <= 0) {
421  if (start < str->size())
422  out.push_back((*str)[start]);
423  start++;
424  last_match_was_empty_string = false;
425  continue;
426  }
427  } else {
428  matches = pattern.TryMatch(*str, start, UNANCHORED, true,
429  vec, kVecSize);
430  if (matches <= 0)
431  break;
432  }
433  size_t matchstart = vec[0], matchend = vec[1];
434  assert(matchstart >= start);
435  assert(matchend >= matchstart);
436 
437  out.append(*str, start, matchstart - start);
438  pattern.Rewrite(&out, rewrite, *str, vec, matches);
439  start = matchend;
440  count++;
441  last_match_was_empty_string = (matchstart == matchend);
442  }
443 
444  if (count == 0)
445  return 0;
446 
447  if (start < str->size())
448  out.append(*str, start, str->size() - start);
449  using std::swap;
450  swap(out, *str);
451  return count;
452 }
453 
454 bool PCRE::Extract(const StringPiece &text,
455  const PCRE& pattern,
456  const StringPiece &rewrite,
457  std::string *out) {
458  int vec[kVecSize] = {};
459  int matches = pattern.TryMatch(text, 0, UNANCHORED, true, vec, kVecSize);
460  if (matches == 0)
461  return false;
462  out->clear();
463  return pattern.Rewrite(out, rewrite, text, vec, matches);
464 }
465 
466 std::string PCRE::QuoteMeta(const StringPiece& unquoted) {
468  result.reserve(unquoted.size() << 1);
469 
470  // Escape any ascii character not in [A-Za-z_0-9].
471  //
472  // Note that it's legal to escape a character even if it has no
473  // special meaning in a regular expression -- so this function does
474  // that. (This also makes it identical to the perl function of the
475  // same name except for the null-character special case;
476  // see `perldoc -f quotemeta`.)
477  for (size_t ii = 0; ii < unquoted.size(); ++ii) {
478  // Note that using 'isalnum' here raises the benchmark time from
479  // 32ns to 58ns:
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] != '_' &&
484  // If this is the part of a UTF8 or Latin1 character, we need
485  // to copy this byte without escaping. Experimentally this is
486  // what works correctly with the regexp library.
487  !(unquoted[ii] & 128)) {
488  if (unquoted[ii] == '\0') { // Special handling for null chars.
489  // Can't use "\\0" since the next character might be a digit.
490  result += "\\x00";
491  continue;
492  }
493  result += '\\';
494  }
495  result += unquoted[ii];
496  }
497 
498  return result;
499 }
500 
501 /***** Actual matching and rewriting code *****/
502 
503 bool PCRE::HitLimit() {
504  return hit_limit_ != 0;
505 }
506 
507 void PCRE::ClearHitLimit() {
508  hit_limit_ = 0;
509 }
510 
511 int PCRE::TryMatch(const StringPiece& text,
512  size_t startpos,
513  Anchor anchor,
514  bool empty_ok,
515  int *vec,
516  int vecsize) const {
517  pcre* re = (anchor == ANCHOR_BOTH) ? re_full_ : re_partial_;
518  if (re == NULL) {
519  PCREPORT(ERROR) << "Matching against invalid re: " << *error_;
520  return 0;
521  }
522 
523  int match_limit = match_limit_;
524  if (match_limit <= 0) {
525  match_limit = GetFlag(FLAGS_regexp_match_limit);
526  }
527 
528  int stack_limit = stack_limit_;
529  if (stack_limit <= 0) {
530  stack_limit = GetFlag(FLAGS_regexp_stack_limit);
531  }
532 
533  pcre_extra extra = { 0 };
534  if (match_limit > 0) {
535  extra.flags |= PCRE_EXTRA_MATCH_LIMIT;
536  extra.match_limit = match_limit;
537  }
538  if (stack_limit > 0) {
540  extra.match_limit_recursion = stack_limit / kPCREFrameSize;
541  }
542 
543  int options = 0;
544  if (anchor != UNANCHORED)
546  if (!empty_ok)
548 
549  int rc = pcre_exec(re, // The regular expression object
550  &extra,
551  (text.data() == NULL) ? "" : text.data(),
552  static_cast<int>(text.size()),
553  static_cast<int>(startpos),
554  options,
555  vec,
556  vecsize);
557 
558  // Handle errors
559  if (rc == 0) {
560  // pcre_exec() returns 0 as a special case when the number of
561  // capturing subpatterns exceeds the size of the vector.
562  // When this happens, there is a match and the output vector
563  // is filled, but we miss out on the positions of the extra subpatterns.
564  rc = vecsize / 2;
565  } else if (rc < 0) {
566  switch (rc) {
567  case PCRE_ERROR_NOMATCH:
568  return 0;
570  // Writing to hit_limit is not safe if multiple threads
571  // are using the PCRE, but the flag is only intended
572  // for use by unit tests anyway, so we let it go.
573  hit_limit_ = true;
574  PCREPORT(WARNING) << "Exceeded match limit of " << match_limit
575  << " when matching '" << pattern_ << "'"
576  << " against text that is " << text.size() << " bytes.";
577  return 0;
579  // See comment about hit_limit above.
580  hit_limit_ = true;
581  PCREPORT(WARNING) << "Exceeded stack limit of " << stack_limit
582  << " when matching '" << pattern_ << "'"
583  << " against text that is " << text.size() << " bytes.";
584  return 0;
585  default:
586  // There are other return codes from pcre.h :
587  // PCRE_ERROR_NULL (-2)
588  // PCRE_ERROR_BADOPTION (-3)
589  // PCRE_ERROR_BADMAGIC (-4)
590  // PCRE_ERROR_UNKNOWN_NODE (-5)
591  // PCRE_ERROR_NOMEMORY (-6)
592  // PCRE_ERROR_NOSUBSTRING (-7)
593  // ...
594  PCREPORT(ERROR) << "Unexpected return code: " << rc
595  << " when matching '" << pattern_ << "'"
596  << ", re=" << re
597  << ", text=" << text
598  << ", vec=" << vec
599  << ", vecsize=" << vecsize;
600  return 0;
601  }
602  }
603 
604  return rc;
605 }
606 
607 bool PCRE::DoMatchImpl(const StringPiece& text,
608  Anchor anchor,
609  size_t* consumed,
610  const Arg* const* args,
611  int n,
612  int* vec,
613  int vecsize) const {
614  assert((1 + n) * 3 <= vecsize); // results + PCRE workspace
615  if (NumberOfCapturingGroups() < n) {
616  // RE has fewer capturing groups than number of Arg pointers passed in.
617  return false;
618  }
619 
620  int matches = TryMatch(text, 0, anchor, true, vec, vecsize);
621  assert(matches >= 0); // TryMatch never returns negatives
622  if (matches == 0)
623  return false;
624 
625  *consumed = vec[1];
626 
627  if (n == 0 || args == NULL) {
628  // We are not interested in results
629  return true;
630  }
631 
632  // If we got here, we must have matched the whole pattern.
633  // We do not need (can not do) any more checks on the value of 'matches' here
634  // -- see the comment for TryMatch.
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];
638 
639  // Avoid invoking undefined behavior when text.data() happens
640  // to be null and start happens to be -1, the latter being the
641  // case for an unmatched subexpression. Even if text.data() is
642  // not null, pointing one byte before was a longstanding bug.
643  const char* addr = NULL;
644  if (start != -1) {
645  addr = text.data() + start;
646  }
647 
648  if (!args[i]->Parse(addr, limit-start)) {
649  // TODO: Should we indicate what the error was?
650  return false;
651  }
652  }
653 
654  return true;
655 }
656 
657 bool PCRE::DoMatch(const StringPiece& text,
658  Anchor anchor,
659  size_t* consumed,
660  const Arg* const args[],
661  int n) const {
662  assert(n >= 0);
663  const int vecsize = (1 + n) * 3; // results + PCRE workspace
664  // (as for kVecSize)
665  int* vec = new int[vecsize];
666  bool b = DoMatchImpl(text, anchor, consumed, args, n, vec, vecsize);
667  delete[] vec;
668  return b;
669 }
670 
671 bool PCRE::Rewrite(std::string *out, const StringPiece &rewrite,
672  const StringPiece &text, int *vec, int veclen) const {
673  int number_of_capturing_groups = NumberOfCapturingGroups();
674  for (const char *s = rewrite.data(), *end = s + rewrite.size();
675  s < end; s++) {
676  int c = *s;
677  if (c == '\\') {
678  c = *++s;
679  if (isdigit(c)) {
680  int n = (c - '0');
681  if (n >= veclen) {
682  if (n <= number_of_capturing_groups) {
683  // unmatched optional capturing group. treat
684  // its value as empty string; i.e., nothing to append.
685  } else {
686  PCREPORT(ERROR) << "requested group " << n
687  << " in regexp " << rewrite.data();
688  return false;
689  }
690  }
691  int start = vec[2 * n];
692  if (start >= 0)
693  out->append(text.data() + start, vec[2 * n + 1] - start);
694  } else if (c == '\\') {
695  out->push_back('\\');
696  } else {
697  PCREPORT(ERROR) << "invalid rewrite pattern: " << rewrite.data();
698  return false;
699  }
700  } else {
701  out->push_back(c);
702  }
703  }
704  return true;
705 }
706 
707 bool PCRE::CheckRewriteString(const StringPiece& rewrite,
708  std::string* error) const {
709  int max_token = -1;
710  for (const char *s = rewrite.data(), *end = s + rewrite.size();
711  s < end; s++) {
712  int c = *s;
713  if (c != '\\') {
714  continue;
715  }
716  if (++s == end) {
717  *error = "Rewrite schema error: '\\' not allowed at end.";
718  return false;
719  }
720  c = *s;
721  if (c == '\\') {
722  continue;
723  }
724  if (!isdigit(c)) {
725  *error = "Rewrite schema error: "
726  "'\\' must be followed by a digit or '\\'.";
727  return false;
728  }
729  int n = (c - '0');
730  if (max_token < n) {
731  max_token = n;
732  }
733  }
734 
735  if (max_token > NumberOfCapturingGroups()) {
736  *error = StringPrintf(
737  "Rewrite schema requests %d matches, but the regexp only has %d "
738  "parenthesized subexpressions.",
739  max_token, NumberOfCapturingGroups());
740  return false;
741  }
742  return true;
743 }
744 
745 
746 // Return the number of capturing subpatterns, or -1 if the
747 // regexp wasn't valid on construction.
748 int PCRE::NumberOfCapturingGroups() const {
749  if (re_partial_ == NULL) return -1;
750 
751  int result;
752  int rc = pcre_fullinfo(re_partial_, // The regular expression object
753  NULL, // We did not study the pattern
755  &result);
756  if (rc != 0) {
757  PCREPORT(ERROR) << "Unexpected return code: " << rc;
758  return -1;
759  }
760  return result;
761 }
762 
763 
764 /***** Parsers for various types *****/
765 
766 bool PCRE::Arg::parse_null(const char* str, size_t n, void* dest) {
767  // We fail if somebody asked us to store into a non-NULL void* pointer
768  return (dest == NULL);
769 }
770 
771 bool PCRE::Arg::parse_string(const char* str, size_t n, void* dest) {
772  if (dest == NULL) return true;
773  reinterpret_cast<std::string*>(dest)->assign(str, n);
774  return true;
775 }
776 
777 bool PCRE::Arg::parse_stringpiece(const char* str, size_t n, void* dest) {
778  if (dest == NULL) return true;
779  *(reinterpret_cast<StringPiece*>(dest)) = StringPiece(str, n);
780  return true;
781 }
782 
783 bool PCRE::Arg::parse_char(const char* str, size_t n, void* dest) {
784  if (n != 1) return false;
785  if (dest == NULL) return true;
786  *(reinterpret_cast<char*>(dest)) = str[0];
787  return true;
788 }
789 
790 bool PCRE::Arg::parse_schar(const char* str, size_t n, void* dest) {
791  if (n != 1) return false;
792  if (dest == NULL) return true;
793  *(reinterpret_cast<signed char*>(dest)) = str[0];
794  return true;
795 }
796 
797 bool PCRE::Arg::parse_uchar(const char* str, size_t n, void* dest) {
798  if (n != 1) return false;
799  if (dest == NULL) return true;
800  *(reinterpret_cast<unsigned char*>(dest)) = str[0];
801  return true;
802 }
803 
804 // Largest number spec that we are willing to parse
805 static const int kMaxNumberLength = 32;
806 
807 // PCREQUIPCRES "buf" must have length at least kMaxNumberLength+1
808 // PCREQUIPCRES "n > 0"
809 // Copies "str" into "buf" and null-terminates if necessary.
810 // Returns one of:
811 // a. "str" if no termination is needed
812 // b. "buf" if the string was copied and null-terminated
813 // c. "" if the input was invalid and has no hope of being parsed
814 static const char* TerminateNumber(char* buf, const char* str, size_t n) {
815  if ((n > 0) && isspace(*str)) {
816  // We are less forgiving than the strtoxxx() routines and do not
817  // allow leading spaces.
818  return "";
819  }
820 
821  // See if the character right after the input text may potentially
822  // look like a digit.
823  if (isdigit(str[n]) ||
824  ((str[n] >= 'a') && (str[n] <= 'f')) ||
825  ((str[n] >= 'A') && (str[n] <= 'F'))) {
826  if (n > kMaxNumberLength) return ""; // Input too big to be a valid number
827  memcpy(buf, str, n);
828  buf[n] = '\0';
829  return buf;
830  } else {
831  // We can parse right out of the supplied string, so return it.
832  return str;
833  }
834 }
835 
836 bool PCRE::Arg::parse_long_radix(const char* str,
837  size_t n,
838  void* dest,
839  int radix) {
840  if (n == 0) return false;
841  char buf[kMaxNumberLength+1];
842  str = TerminateNumber(buf, str, n);
843  char* end;
844  errno = 0;
845  long r = strtol(str, &end, radix);
846  if (end != str + n) return false; // Leftover junk
847  if (errno) return false;
848  if (dest == NULL) return true;
849  *(reinterpret_cast<long*>(dest)) = r;
850  return true;
851 }
852 
853 bool PCRE::Arg::parse_ulong_radix(const char* str,
854  size_t n,
855  void* dest,
856  int radix) {
857  if (n == 0) return false;
858  char buf[kMaxNumberLength+1];
859  str = TerminateNumber(buf, str, n);
860  if (str[0] == '-') {
861  // strtoul() will silently accept negative numbers and parse
862  // them. This module is more strict and treats them as errors.
863  return false;
864  }
865 
866  char* end;
867  errno = 0;
868  unsigned long r = strtoul(str, &end, radix);
869  if (end != str + n) return false; // Leftover junk
870  if (errno) return false;
871  if (dest == NULL) return true;
872  *(reinterpret_cast<unsigned long*>(dest)) = r;
873  return true;
874 }
875 
876 bool PCRE::Arg::parse_short_radix(const char* str,
877  size_t n,
878  void* dest,
879  int radix) {
880  long r;
881  if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse
882  if ((short)r != r) return false; // Out of range
883  if (dest == NULL) return true;
884  *(reinterpret_cast<short*>(dest)) = (short)r;
885  return true;
886 }
887 
888 bool PCRE::Arg::parse_ushort_radix(const char* str,
889  size_t n,
890  void* dest,
891  int radix) {
892  unsigned long r;
893  if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse
894  if ((unsigned short)r != r) return false; // Out of range
895  if (dest == NULL) return true;
896  *(reinterpret_cast<unsigned short*>(dest)) = (unsigned short)r;
897  return true;
898 }
899 
900 bool PCRE::Arg::parse_int_radix(const char* str,
901  size_t n,
902  void* dest,
903  int radix) {
904  long r;
905  if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse
906  if ((int)r != r) return false; // Out of range
907  if (dest == NULL) return true;
908  *(reinterpret_cast<int*>(dest)) = (int)r;
909  return true;
910 }
911 
912 bool PCRE::Arg::parse_uint_radix(const char* str,
913  size_t n,
914  void* dest,
915  int radix) {
916  unsigned long r;
917  if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse
918  if ((unsigned int)r != r) return false; // Out of range
919  if (dest == NULL) return true;
920  *(reinterpret_cast<unsigned int*>(dest)) = (unsigned int)r;
921  return true;
922 }
923 
924 bool PCRE::Arg::parse_longlong_radix(const char* str,
925  size_t n,
926  void* dest,
927  int radix) {
928  if (n == 0) return false;
929  char buf[kMaxNumberLength+1];
930  str = TerminateNumber(buf, str, n);
931  char* end;
932  errno = 0;
933  long long r = strtoll(str, &end, radix);
934  if (end != str + n) return false; // Leftover junk
935  if (errno) return false;
936  if (dest == NULL) return true;
937  *(reinterpret_cast<long long*>(dest)) = r;
938  return true;
939 }
940 
941 bool PCRE::Arg::parse_ulonglong_radix(const char* str,
942  size_t n,
943  void* dest,
944  int radix) {
945  if (n == 0) return false;
946  char buf[kMaxNumberLength+1];
947  str = TerminateNumber(buf, str, n);
948  if (str[0] == '-') {
949  // strtoull() will silently accept negative numbers and parse
950  // them. This module is more strict and treats them as errors.
951  return false;
952  }
953  char* end;
954  errno = 0;
955  unsigned long long r = strtoull(str, &end, radix);
956  if (end != str + n) return false; // Leftover junk
957  if (errno) return false;
958  if (dest == NULL) return true;
959  *(reinterpret_cast<unsigned long long*>(dest)) = r;
960  return true;
961 }
962 
963 static bool parse_double_float(const char* str, size_t n, bool isfloat,
964  void* dest) {
965  if (n == 0) return false;
966  static const int kMaxLength = 200;
967  char buf[kMaxLength];
968  if (n >= kMaxLength) return false;
969  memcpy(buf, str, n);
970  buf[n] = '\0';
971  char* end;
972  errno = 0;
973  double r;
974  if (isfloat) {
975  r = strtof(buf, &end);
976  } else {
977  r = strtod(buf, &end);
978  }
979  if (end != buf + n) return false; // Leftover junk
980  if (errno) return false;
981  if (dest == NULL) return true;
982  if (isfloat) {
983  *(reinterpret_cast<float*>(dest)) = (float)r;
984  } else {
985  *(reinterpret_cast<double*>(dest)) = r;
986  }
987  return true;
988 }
989 
990 bool PCRE::Arg::parse_double(const char* str, size_t n, void* dest) {
991  return parse_double_float(str, n, false, dest);
992 }
993 
994 bool PCRE::Arg::parse_float(const char* str, size_t n, void* dest) {
995  return parse_double_float(str, n, true, dest);
996 }
997 
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); \
1001  } \
1002  bool PCRE::Arg::parse_##name##_hex(const char* str, size_t n, void* dest) { \
1003  return parse_##name##_radix(str, n, dest, 16); \
1004  } \
1005  bool PCRE::Arg::parse_##name##_octal(const char* str, size_t n, \
1006  void* dest) { \
1007  return parse_##name##_radix(str, n, dest, 8); \
1008  } \
1009  bool PCRE::Arg::parse_##name##_cradix(const char* str, size_t n, \
1010  void* dest) { \
1011  return parse_##name##_radix(str, n, dest, 0); \
1012  }
1013 
1014 DEFINE_INTEGER_PARSER(short);
1015 DEFINE_INTEGER_PARSER(ushort);
1018 DEFINE_INTEGER_PARSER(long);
1020 DEFINE_INTEGER_PARSER(longlong);
1021 DEFINE_INTEGER_PARSER(ulonglong);
1022 
1023 #undef DEFINE_INTEGER_PARSER
1024 
1025 } // namespace re2
re2::PCRE::PartialMatchFunctor
Definition: bloaty/third_party/re2/util/pcre.h:293
re2::PCRE::Arg::parse_null
static bool parse_null(const char *str, size_t n, void *dest)
Definition: bloaty/third_party/re2/util/pcre.cc:767
xds_interop_client.str
str
Definition: xds_interop_client.py:487
radix
int radix
Definition: abseil-cpp/absl/strings/internal/pow10_helper_test.cc:31
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
PCRE_ERROR_RECURSIONLIMIT
#define PCRE_ERROR_RECURSIONLIMIT
Definition: re2/util/pcre.cc:57
re2::PCRE::stack_limit_
int stack_limit_
Definition: bloaty/third_party/re2/util/pcre.h:502
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
pcre_fullinfo
int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *)
Definition: re2/util/pcre.cc:71
check_tracer_sanity.pattern
pattern
Definition: check_tracer_sanity.py:25
fix_build_deps.c
list c
Definition: fix_build_deps.py:490
re2::PCRE::Arg::parse_stringpiece
static bool parse_stringpiece(const char *str, size_t n, void *dest)
Definition: bloaty/third_party/re2/util/pcre.cc:778
pcre_extra::match_limit_recursion
int match_limit_recursion
Definition: bloaty/third_party/re2/util/pcre.cc:49
re2::PCRE::GlobalReplace
static int GlobalReplace(std::string *str, const PCRE &pattern, const StringPiece &rewrite)
Definition: bloaty/third_party/re2/util/pcre.cc:397
re2::PCRE::PartialMatchFunctor::operator()
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
Definition: bloaty/third_party/re2/util/pcre.cc:238
string.h
options
double_dict options[]
Definition: capstone_test.c:55
PCRE_INFO_CAPTURECOUNT
#define PCRE_INFO_CAPTURECOUNT
Definition: re2/util/pcre.cc:58
re2::PCRE::PartialMatch
static const PartialMatchFunctor PartialMatch
Definition: bloaty/third_party/re2/util/pcre.h:313
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
re2::PCRE::Anchor
Anchor
Definition: bloaty/third_party/re2/util/pcre.h:436
re2::PCRE::report_errors_
bool report_errors_
Definition: bloaty/third_party/re2/util/pcre.h:500
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
re2::PCRE::Rewrite
bool Rewrite(std::string *out, const StringPiece &rewrite, const StringPiece &text, int *vec, int veclen) const
Definition: bloaty/third_party/re2/util/pcre.cc:672
re2::PCRE::error
const std::string & error() const
Definition: bloaty/third_party/re2/util/pcre.h:229
re2
Definition: bloaty/third_party/re2/re2/bitmap256.h:17
re2::PCRE::Arg::parse_string
static bool parse_string(const char *str, size_t n, void *dest)
Definition: bloaty/third_party/re2/util/pcre.cc:772
absl::FormatConversionChar::s
@ s
pcre_exec
int pcre_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int)
Definition: re2/util/pcre.cc:67
re2::PCRE::re_full_
pcre * re_full_
Definition: bloaty/third_party/re2/util/pcre.h:497
Arg
Arg(64) -> Arg(128) ->Arg(256) ->Arg(512) ->Arg(1024) ->Arg(1536) ->Arg(2048) ->Arg(3072) ->Arg(4096) ->Arg(5120) ->Arg(6144) ->Arg(7168)
re2::PCRE::Arg::parse_float
static bool parse_float(const char *str, size_t n, void *dest)
Definition: bloaty/third_party/re2/util/pcre.cc:1020
re2::GetFlag
T GetFlag(const T &flag)
Definition: re2/util/flags.h:21
re2::PCRE::Arg::parse_double
static bool parse_double(const char *str, size_t n, void *dest)
Definition: bloaty/third_party/re2/util/pcre.cc:1016
re2::PCRE::QuoteMeta
static std::string QuoteMeta(const StringPiece &unquoted)
Definition: bloaty/third_party/re2/util/pcre.cc:467
PCREPORT
#define PCREPORT(level)
Definition: re2/util/pcre.cc:29
re2::PCRE::NumberOfCapturingGroups
int NumberOfCapturingGroups() const
Definition: bloaty/third_party/re2/util/pcre.cc:749
re2::PCRE::FullMatch
static const FullMatchFunctor FullMatch
Definition: bloaty/third_party/re2/util/pcre.h:289
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
start
static uint64_t start
Definition: benchmark-pound.c:74
gen_server_registered_method_bad_client_test_body.text
def text
Definition: gen_server_registered_method_bad_client_test_body.py:50
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
pcre_free
void pcre_free(void *)
Definition: re2/util/pcre.cc:60
a2
T::first_type a2
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:307
xds_interop_client.int
int
Definition: xds_interop_client.py:113
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
pcre_compile
pcre * pcre_compile(const char *, int, const char **, int *, const unsigned char *)
Definition: re2/util/pcre.cc:63
swap
#define swap(a, b)
Definition: qsort.h:111
PCRE_ANCHORED
#define PCRE_ANCHORED
Definition: re2/util/pcre.cc:53
re2::kVecSize
static const int kVecSize
Definition: bloaty/third_party/re2/re2/re2.cc:37
re2::StringPrintf
std::string StringPrintf(const char *format,...)
Definition: bloaty/third_party/re2/util/strutil.cc:140
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
re2::PCRE::FullMatchFunctor::operator()
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
Definition: bloaty/third_party/re2/util/pcre.cc:195
re2::PCRE::EnabledExecOptions
@ EnabledExecOptions
Definition: bloaty/third_party/re2/util/pcre.h:208
PCRE_ERROR_MATCHLIMIT
#define PCRE_ERROR_MATCHLIMIT
Definition: re2/util/pcre.cc:56
re2::parse_double_float
static bool parse_double_float(const char *str, size_t n, bool isfloat, void *dest)
Definition: bloaty/third_party/re2/re2/re2.cc:1177
std::swap
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:1226
re2::PCRE::FindAndConsumeFunctor::operator()
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
Definition: bloaty/third_party/re2/util/pcre.cc:330
absl::flags_internal::Parse
bool Parse(FlagOpFn op, absl::string_view text, void *dst, std::string *error)
Definition: abseil-cpp/absl/flags/internal/flag.h:125
google::protobuf::WARNING
static const LogLevel WARNING
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:71
PCRE_ERROR_NOMATCH
#define PCRE_ERROR_NOMATCH
Definition: re2/util/pcre.cc:55
a1
T::first_type a1
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:305
uint
unsigned int uint
Definition: bloaty/third_party/zlib/examples/gzlog.c:242
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
re2::PCRE::ANCHOR_BOTH
@ ANCHOR_BOTH
Definition: bloaty/third_party/re2/util/pcre.h:439
re2::PCRE::no_more_args
static Arg no_more_args
Definition: bloaty/third_party/re2/util/pcre.h:189
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
tests.qps.qps_worker.dest
dest
Definition: qps_worker.py:45
google::protobuf::ERROR
static const LogLevel ERROR
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:70
re2::PCRE::DoMatch
bool DoMatch(const StringPiece &text, Anchor anchor, size_t *consumed, const Arg *const *args, int n) const
re2::kPCREFrameSize
static const int kPCREFrameSize
Definition: bloaty/third_party/re2/util/pcre.cc:91
re2::PCRE::UNANCHORED
@ UNANCHORED
Definition: bloaty/third_party/re2/util/pcre.h:437
re2::PCRE::Compile
pcre * Compile(Anchor anchor)
Definition: bloaty/third_party/re2/util/pcre.cc:156
re2::DEFINE_INTEGER_PARSER
DEFINE_INTEGER_PARSER(short)
pcre_extra::flags
int flags
Definition: bloaty/third_party/re2/util/pcre.cc:47
re2::PCRE::pattern_
std::string pattern_
Definition: bloaty/third_party/re2/util/pcre.h:495
re2::PCRE::~PCRE
~PCRE()
Definition: bloaty/third_party/re2/util/pcre.cc:150
re2::PCRE::Arg::parse_char
static bool parse_char(const char *str, size_t n, void *dest)
Definition: bloaty/third_party/re2/util/pcre.cc:784
re2::PCRE::PCRE
PCRE(const char *pattern)
Definition: bloaty/third_party/re2/util/pcre.cc:128
re2::PCRE::EnabledCompileOptions
@ EnabledCompileOptions
Definition: bloaty/third_party/re2/util/pcre.h:207
re2::PCRE::ANCHOR_START
@ ANCHOR_START
Definition: bloaty/third_party/re2/util/pcre.h:438
re2::PCRE::Extract
static bool Extract(const StringPiece &text, const PCRE &pattern, const StringPiece &rewrite, std::string *out)
Definition: bloaty/third_party/re2/util/pcre.cc:455
pcre_extra::match_limit
int match_limit
Definition: bloaty/third_party/re2/util/pcre.cc:48
re2::PCRE::HitLimit
bool HitLimit()
Definition: bloaty/third_party/re2/util/pcre.cc:504
Option
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:1303
re2::kMaxNumberLength
static const int kMaxNumberLength
Definition: bloaty/third_party/re2/re2/re2.cc:991
wrapped
grpc_call * wrapped
Definition: src/php/ext/grpc/call.h:32
PCRE_EXTRA_MATCH_LIMIT
#define PCRE_EXTRA_MATCH_LIMIT
Definition: re2/util/pcre.cc:51
re2::PCRE::hit_limit_
int32_t hit_limit_
Definition: bloaty/third_party/re2/util/pcre.h:503
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
fix_build_deps.r
r
Definition: fix_build_deps.py:491
ulong
unsigned long ulong
Definition: bloaty/third_party/zlib/examples/gzlog.c:243
re2::PCRE::match_limit_
int match_limit_
Definition: bloaty/third_party/re2/util/pcre.h:501
re2::PCRE::Arg::parse_schar
static bool parse_schar(const char *str, size_t n, void *dest)
Definition: bloaty/third_party/re2/util/pcre.cc:791
re2::PCRE::pattern
const std::string & pattern() const
Definition: bloaty/third_party/re2/util/pcre.h:225
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
re2::PCRE::ClearHitLimit
void ClearHitLimit()
Definition: bloaty/third_party/re2/util/pcre.cc:508
PCRE_EXTRA_MATCH_LIMIT_RECURSION
#define PCRE_EXTRA_MATCH_LIMIT_RECURSION
Definition: re2/util/pcre.cc:52
re2::empty_string
static const std::string * empty_string
Definition: bloaty/third_party/re2/re2/re2.cc:59
re2::PCRE::re_partial_
pcre * re_partial_
Definition: bloaty/third_party/re2/util/pcre.h:498
re2::kMaxArgs
static const int kMaxArgs
Definition: bloaty/third_party/re2/re2/re2.cc:36
re2::PCRE::FindAndConsume
static const FindAndConsumeFunctor FindAndConsume
Definition: bloaty/third_party/re2/util/pcre.h:364
re2::PCRE::ConsumeFunctor::operator()
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
Definition: bloaty/third_party/re2/util/pcre.cc:281
re2::TerminateNumber
static const char * TerminateNumber(char *buf, size_t nbuf, const char *str, size_t *np, bool accept_spaces)
Definition: bloaty/third_party/re2/re2/re2.cc:996
re2::PCRE::Consume
static const ConsumeFunctor Consume
Definition: bloaty/third_party/re2/util/pcre.h:338
re2::PCRE::DoMatchImpl
bool DoMatchImpl(const StringPiece &text, Anchor anchor, size_t *consumed, const Arg *const args[], int n, int *vec, int vecsize) const
re2::PCRE::Arg
Definition: bloaty/third_party/re2/util/pcre.h:568
re2::PCRE::error_
const std::string * error_
Definition: bloaty/third_party/re2/util/pcre.h:499
re2::PCRE::TryMatch
int TryMatch(const StringPiece &text, size_t startpos, Anchor anchor, bool empty_ok, int *vec, int vecsize) const
Definition: bloaty/third_party/re2/util/pcre.cc:512
re2::PCRE::options_
Option options_
Definition: bloaty/third_party/re2/util/pcre.h:496
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
re2::PCRE::Init
void Init(const char *pattern, Option option, int match_limit, int stack_limit, bool report_errors)
Definition: bloaty/third_party/re2/util/pcre.cc:104
re2::PCRE::Replace
static bool Replace(std::string *str, const PCRE &pattern, const StringPiece &rewrite)
Definition: bloaty/third_party/re2/util/pcre.cc:379
PCRE_NOTEMPTY
#define PCRE_NOTEMPTY
Definition: re2/util/pcre.cc:54
re2::PCRE::None
@ None
Definition: bloaty/third_party/re2/util/pcre.h:205
google_benchmark.option
option
Definition: third_party/benchmark/bindings/python/google_benchmark/__init__.py:115
re2::PCRE::CheckRewriteString
bool CheckRewriteString(const StringPiece &rewrite, std::string *error) const
Definition: bloaty/third_party/re2/util/pcre.cc:708
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
pcre_extra
Definition: bloaty/third_party/re2/util/pcre.cc:46
errno.h
re2::PCRE::Arg::parse_uchar
static bool parse_uchar(const char *str, size_t n, void *dest)
Definition: bloaty/third_party/re2/util/pcre.cc:798
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
DEFINE_FLAG
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