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


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:41