• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2009 The RE2 Authors.  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 #include "re2/prefilter.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <string>
10 #include <vector>
11 
12 #include "util/util.h"
13 #include "util/logging.h"
14 #include "util/strutil.h"
15 #include "util/utf.h"
16 #include "re2/re2.h"
17 #include "re2/unicode_casefold.h"
18 #include "re2/walker-inl.h"
19 
20 namespace re2 {
21 
22 static const bool ExtraDebug = false;
23 
24 typedef std::set<std::string>::iterator SSIter;
25 typedef std::set<std::string>::const_iterator ConstSSIter;
26 
27 // Initializes a Prefilter, allocating subs_ as necessary.
Prefilter(Op op)28 Prefilter::Prefilter(Op op) {
29   op_ = op;
30   subs_ = NULL;
31   if (op_ == AND || op_ == OR)
32     subs_ = new std::vector<Prefilter*>;
33 }
34 
35 // Destroys a Prefilter.
~Prefilter()36 Prefilter::~Prefilter() {
37   if (subs_) {
38     for (size_t i = 0; i < subs_->size(); i++)
39       delete (*subs_)[i];
40     delete subs_;
41     subs_ = NULL;
42   }
43 }
44 
45 // Simplify if the node is an empty Or or And.
Simplify()46 Prefilter* Prefilter::Simplify() {
47   if (op_ != AND && op_ != OR) {
48     return this;
49   }
50 
51   // Nothing left in the AND/OR.
52   if (subs_->empty()) {
53     if (op_ == AND)
54       op_ = ALL;  // AND of nothing is true
55     else
56       op_ = NONE;  // OR of nothing is false
57 
58     return this;
59   }
60 
61   // Just one subnode: throw away wrapper.
62   if (subs_->size() == 1) {
63     Prefilter* a = (*subs_)[0];
64     subs_->clear();
65     delete this;
66     return a->Simplify();
67   }
68 
69   return this;
70 }
71 
72 // Combines two Prefilters together to create an "op" (AND or OR).
73 // The passed Prefilters will be part of the returned Prefilter or deleted.
74 // Does lots of work to avoid creating unnecessarily complicated structures.
AndOr(Op op,Prefilter * a,Prefilter * b)75 Prefilter* Prefilter::AndOr(Op op, Prefilter* a, Prefilter* b) {
76   // If a, b can be rewritten as op, do so.
77   a = a->Simplify();
78   b = b->Simplify();
79 
80   // Canonicalize: a->op <= b->op.
81   if (a->op() > b->op()) {
82     Prefilter* t = a;
83     a = b;
84     b = t;
85   }
86 
87   // Trivial cases.
88   //    ALL AND b = b
89   //    NONE OR b = b
90   //    ALL OR b   = ALL
91   //    NONE AND b = NONE
92   // Don't need to look at b, because of canonicalization above.
93   // ALL and NONE are smallest opcodes.
94   if (a->op() == ALL || a->op() == NONE) {
95     if ((a->op() == ALL && op == AND) ||
96         (a->op() == NONE && op == OR)) {
97       delete a;
98       return b;
99     } else {
100       delete b;
101       return a;
102     }
103   }
104 
105   // If a and b match op, merge their contents.
106   if (a->op() == op && b->op() == op) {
107     for (size_t i = 0; i < b->subs()->size(); i++) {
108       Prefilter* bb = (*b->subs())[i];
109       a->subs()->push_back(bb);
110     }
111     b->subs()->clear();
112     delete b;
113     return a;
114   }
115 
116   // If a already has the same op as the op that is under construction
117   // add in b (similarly if b already has the same op, add in a).
118   if (b->op() == op) {
119     Prefilter* t = a;
120     a = b;
121     b = t;
122   }
123   if (a->op() == op) {
124     a->subs()->push_back(b);
125     return a;
126   }
127 
128   // Otherwise just return the op.
129   Prefilter* c = new Prefilter(op);
130   c->subs()->push_back(a);
131   c->subs()->push_back(b);
132   return c;
133 }
134 
And(Prefilter * a,Prefilter * b)135 Prefilter* Prefilter::And(Prefilter* a, Prefilter* b) {
136   return AndOr(AND, a, b);
137 }
138 
Or(Prefilter * a,Prefilter * b)139 Prefilter* Prefilter::Or(Prefilter* a, Prefilter* b) {
140   return AndOr(OR, a, b);
141 }
142 
SimplifyStringSet(std::set<std::string> * ss)143 static void SimplifyStringSet(std::set<std::string>* ss) {
144   // Now make sure that the strings aren't redundant.  For example, if
145   // we know "ab" is a required string, then it doesn't help at all to
146   // know that "abc" is also a required string, so delete "abc". This
147   // is because, when we are performing a string search to filter
148   // regexps, matching "ab" will already allow this regexp to be a
149   // candidate for match, so further matching "abc" is redundant.
150   // Note that we must ignore "" because find() would find it at the
151   // start of everything and thus we would end up erasing everything.
152   for (SSIter i = ss->begin(); i != ss->end(); ++i) {
153     if (i->empty())
154       continue;
155     SSIter j = i;
156     ++j;
157     while (j != ss->end()) {
158       if (j->find(*i) != std::string::npos) {
159         j = ss->erase(j);
160         continue;
161       }
162       ++j;
163     }
164   }
165 }
166 
OrStrings(std::set<std::string> * ss)167 Prefilter* Prefilter::OrStrings(std::set<std::string>* ss) {
168   Prefilter* or_prefilter = new Prefilter(NONE);
169   SimplifyStringSet(ss);
170   for (SSIter i = ss->begin(); i != ss->end(); ++i)
171     or_prefilter = Or(or_prefilter, FromString(*i));
172   return or_prefilter;
173 }
174 
ToLowerRune(Rune r)175 static Rune ToLowerRune(Rune r) {
176   if (r < Runeself) {
177     if ('A' <= r && r <= 'Z')
178       r += 'a' - 'A';
179     return r;
180   }
181 
182   const CaseFold *f = LookupCaseFold(unicode_tolower, num_unicode_tolower, r);
183   if (f == NULL || r < f->lo)
184     return r;
185   return ApplyFold(f, r);
186 }
187 
ToLowerRuneLatin1(Rune r)188 static Rune ToLowerRuneLatin1(Rune r) {
189   if ('A' <= r && r <= 'Z')
190     r += 'a' - 'A';
191   return r;
192 }
193 
FromString(const std::string & str)194 Prefilter* Prefilter::FromString(const std::string& str) {
195   Prefilter* m = new Prefilter(Prefilter::ATOM);
196   m->atom_ = str;
197   return m;
198 }
199 
200 // Information about a regexp used during computation of Prefilter.
201 // Can be thought of as information about the set of strings matching
202 // the given regular expression.
203 class Prefilter::Info {
204  public:
205   Info();
206   ~Info();
207 
208   // More constructors.  They delete their Info* arguments.
209   static Info* Alt(Info* a, Info* b);
210   static Info* Concat(Info* a, Info* b);
211   static Info* And(Info* a, Info* b);
212   static Info* Star(Info* a);
213   static Info* Plus(Info* a);
214   static Info* Quest(Info* a);
215   static Info* EmptyString();
216   static Info* NoMatch();
217   static Info* AnyCharOrAnyByte();
218   static Info* CClass(CharClass* cc, bool latin1);
219   static Info* Literal(Rune r);
220   static Info* LiteralLatin1(Rune r);
221   static Info* AnyMatch();
222 
223   // Format Info as a string.
224   std::string ToString();
225 
226   // Caller takes ownership of the Prefilter.
227   Prefilter* TakeMatch();
228 
exact()229   std::set<std::string>& exact() { return exact_; }
230 
is_exact() const231   bool is_exact() const { return is_exact_; }
232 
233   class Walker;
234 
235  private:
236   std::set<std::string> exact_;
237 
238   // When is_exact_ is true, the strings that match
239   // are placed in exact_. When it is no longer an exact
240   // set of strings that match this RE, then is_exact_
241   // is false and the match_ contains the required match
242   // criteria.
243   bool is_exact_;
244 
245   // Accumulated Prefilter query that any
246   // match for this regexp is guaranteed to match.
247   Prefilter* match_;
248 };
249 
250 
Info()251 Prefilter::Info::Info()
252   : is_exact_(false),
253     match_(NULL) {
254 }
255 
~Info()256 Prefilter::Info::~Info() {
257   delete match_;
258 }
259 
TakeMatch()260 Prefilter* Prefilter::Info::TakeMatch() {
261   if (is_exact_) {
262     match_ = Prefilter::OrStrings(&exact_);
263     is_exact_ = false;
264   }
265   Prefilter* m = match_;
266   match_ = NULL;
267   return m;
268 }
269 
270 // Format a Info in string form.
ToString()271 std::string Prefilter::Info::ToString() {
272   if (is_exact_) {
273     int n = 0;
274     std::string s;
275     for (SSIter i = exact_.begin(); i != exact_.end(); ++i) {
276       if (n++ > 0)
277         s += ",";
278       s += *i;
279     }
280     return s;
281   }
282 
283   if (match_)
284     return match_->DebugString();
285 
286   return "";
287 }
288 
289 // Add the strings from src to dst.
CopyIn(const std::set<std::string> & src,std::set<std::string> * dst)290 static void CopyIn(const std::set<std::string>& src,
291                    std::set<std::string>* dst) {
292   for (ConstSSIter i = src.begin(); i != src.end(); ++i)
293     dst->insert(*i);
294 }
295 
296 // Add the cross-product of a and b to dst.
297 // (For each string i in a and j in b, add i+j.)
CrossProduct(const std::set<std::string> & a,const std::set<std::string> & b,std::set<std::string> * dst)298 static void CrossProduct(const std::set<std::string>& a,
299                          const std::set<std::string>& b,
300                          std::set<std::string>* dst) {
301   for (ConstSSIter i = a.begin(); i != a.end(); ++i)
302     for (ConstSSIter j = b.begin(); j != b.end(); ++j)
303       dst->insert(*i + *j);
304 }
305 
306 // Concats a and b. Requires that both are exact sets.
307 // Forms an exact set that is a crossproduct of a and b.
Concat(Info * a,Info * b)308 Prefilter::Info* Prefilter::Info::Concat(Info* a, Info* b) {
309   if (a == NULL)
310     return b;
311   DCHECK(a->is_exact_);
312   DCHECK(b && b->is_exact_);
313   Info *ab = new Info();
314 
315   CrossProduct(a->exact_, b->exact_, &ab->exact_);
316   ab->is_exact_ = true;
317 
318   delete a;
319   delete b;
320   return ab;
321 }
322 
323 // Constructs an inexact Info for ab given a and b.
324 // Used only when a or b is not exact or when the
325 // exact cross product is likely to be too big.
And(Info * a,Info * b)326 Prefilter::Info* Prefilter::Info::And(Info* a, Info* b) {
327   if (a == NULL)
328     return b;
329   if (b == NULL)
330     return a;
331 
332   Info *ab = new Info();
333 
334   ab->match_ = Prefilter::And(a->TakeMatch(), b->TakeMatch());
335   ab->is_exact_ = false;
336   delete a;
337   delete b;
338   return ab;
339 }
340 
341 // Constructs Info for a|b given a and b.
Alt(Info * a,Info * b)342 Prefilter::Info* Prefilter::Info::Alt(Info* a, Info* b) {
343   Info *ab = new Info();
344 
345   if (a->is_exact_ && b->is_exact_) {
346     CopyIn(a->exact_, &ab->exact_);
347     CopyIn(b->exact_, &ab->exact_);
348     ab->is_exact_ = true;
349   } else {
350     // Either a or b has is_exact_ = false. If the other
351     // one has is_exact_ = true, we move it to match_ and
352     // then create a OR of a,b. The resulting Info has
353     // is_exact_ = false.
354     ab->match_ = Prefilter::Or(a->TakeMatch(), b->TakeMatch());
355     ab->is_exact_ = false;
356   }
357 
358   delete a;
359   delete b;
360   return ab;
361 }
362 
363 // Constructs Info for a? given a.
Quest(Info * a)364 Prefilter::Info* Prefilter::Info::Quest(Info *a) {
365   Info *ab = new Info();
366 
367   ab->is_exact_ = false;
368   ab->match_ = new Prefilter(ALL);
369   delete a;
370   return ab;
371 }
372 
373 // Constructs Info for a* given a.
374 // Same as a? -- not much to do.
Star(Info * a)375 Prefilter::Info* Prefilter::Info::Star(Info *a) {
376   return Quest(a);
377 }
378 
379 // Constructs Info for a+ given a. If a was exact set, it isn't
380 // anymore.
Plus(Info * a)381 Prefilter::Info* Prefilter::Info::Plus(Info *a) {
382   Info *ab = new Info();
383 
384   ab->match_ = a->TakeMatch();
385   ab->is_exact_ = false;
386 
387   delete a;
388   return ab;
389 }
390 
RuneToString(Rune r)391 static std::string RuneToString(Rune r) {
392   char buf[UTFmax];
393   int n = runetochar(buf, &r);
394   return std::string(buf, n);
395 }
396 
RuneToStringLatin1(Rune r)397 static std::string RuneToStringLatin1(Rune r) {
398   char c = r & 0xff;
399   return std::string(&c, 1);
400 }
401 
402 // Constructs Info for literal rune.
Literal(Rune r)403 Prefilter::Info* Prefilter::Info::Literal(Rune r) {
404   Info* info = new Info();
405   info->exact_.insert(RuneToString(ToLowerRune(r)));
406   info->is_exact_ = true;
407   return info;
408 }
409 
410 // Constructs Info for literal rune for Latin1 encoded string.
LiteralLatin1(Rune r)411 Prefilter::Info* Prefilter::Info::LiteralLatin1(Rune r) {
412   Info* info = new Info();
413   info->exact_.insert(RuneToStringLatin1(ToLowerRuneLatin1(r)));
414   info->is_exact_ = true;
415   return info;
416 }
417 
418 // Constructs Info for dot (any character) or \C (any byte).
AnyCharOrAnyByte()419 Prefilter::Info* Prefilter::Info::AnyCharOrAnyByte() {
420   Prefilter::Info* info = new Prefilter::Info();
421   info->match_ = new Prefilter(ALL);
422   return info;
423 }
424 
425 // Constructs Prefilter::Info for no possible match.
NoMatch()426 Prefilter::Info* Prefilter::Info::NoMatch() {
427   Prefilter::Info* info = new Prefilter::Info();
428   info->match_ = new Prefilter(NONE);
429   return info;
430 }
431 
432 // Constructs Prefilter::Info for any possible match.
433 // This Prefilter::Info is valid for any regular expression,
434 // since it makes no assertions whatsoever about the
435 // strings being matched.
AnyMatch()436 Prefilter::Info* Prefilter::Info::AnyMatch() {
437   Prefilter::Info *info = new Prefilter::Info();
438   info->match_ = new Prefilter(ALL);
439   return info;
440 }
441 
442 // Constructs Prefilter::Info for just the empty string.
EmptyString()443 Prefilter::Info* Prefilter::Info::EmptyString() {
444   Prefilter::Info* info = new Prefilter::Info();
445   info->is_exact_ = true;
446   info->exact_.insert("");
447   return info;
448 }
449 
450 // Constructs Prefilter::Info for a character class.
451 typedef CharClass::iterator CCIter;
CClass(CharClass * cc,bool latin1)452 Prefilter::Info* Prefilter::Info::CClass(CharClass *cc,
453                                          bool latin1) {
454   if (ExtraDebug) {
455     LOG(ERROR) << "CharClassInfo:";
456     for (CCIter i = cc->begin(); i != cc->end(); ++i)
457       LOG(ERROR) << "  " << i->lo << "-" << i->hi;
458   }
459 
460   // If the class is too large, it's okay to overestimate.
461   if (cc->size() > 10)
462     return AnyCharOrAnyByte();
463 
464   Prefilter::Info *a = new Prefilter::Info();
465   for (CCIter i = cc->begin(); i != cc->end(); ++i)
466     for (Rune r = i->lo; r <= i->hi; r++) {
467       if (latin1) {
468         a->exact_.insert(RuneToStringLatin1(ToLowerRuneLatin1(r)));
469       } else {
470         a->exact_.insert(RuneToString(ToLowerRune(r)));
471       }
472     }
473 
474 
475   a->is_exact_ = true;
476 
477   if (ExtraDebug)
478     LOG(ERROR) << " = " << a->ToString();
479 
480   return a;
481 }
482 
483 class Prefilter::Info::Walker : public Regexp::Walker<Prefilter::Info*> {
484  public:
Walker(bool latin1)485   Walker(bool latin1) : latin1_(latin1) {}
486 
487   virtual Info* PostVisit(
488       Regexp* re, Info* parent_arg,
489       Info* pre_arg,
490       Info** child_args, int nchild_args);
491 
492   virtual Info* ShortVisit(
493       Regexp* re,
494       Info* parent_arg);
495 
latin1()496   bool latin1() { return latin1_; }
497  private:
498   bool latin1_;
499 
500   Walker(const Walker&) = delete;
501   Walker& operator=(const Walker&) = delete;
502 };
503 
BuildInfo(Regexp * re)504 Prefilter::Info* Prefilter::BuildInfo(Regexp* re) {
505   if (ExtraDebug)
506     LOG(ERROR) << "BuildPrefilter::Info: " << re->ToString();
507 
508   bool latin1 = (re->parse_flags() & Regexp::Latin1) != 0;
509   Prefilter::Info::Walker w(latin1);
510   Prefilter::Info* info = w.WalkExponential(re, NULL, 100000);
511 
512   if (w.stopped_early()) {
513     delete info;
514     return NULL;
515   }
516 
517   return info;
518 }
519 
ShortVisit(Regexp * re,Prefilter::Info * parent_arg)520 Prefilter::Info* Prefilter::Info::Walker::ShortVisit(
521     Regexp* re, Prefilter::Info* parent_arg) {
522   return AnyMatch();
523 }
524 
525 // Constructs the Prefilter::Info for the given regular expression.
526 // Assumes re is simplified.
PostVisit(Regexp * re,Prefilter::Info * parent_arg,Prefilter::Info * pre_arg,Prefilter::Info ** child_args,int nchild_args)527 Prefilter::Info* Prefilter::Info::Walker::PostVisit(
528     Regexp* re, Prefilter::Info* parent_arg,
529     Prefilter::Info* pre_arg, Prefilter::Info** child_args,
530     int nchild_args) {
531   Prefilter::Info *info;
532   switch (re->op()) {
533     default:
534     case kRegexpRepeat:
535       LOG(DFATAL) << "Bad regexp op " << re->op();
536       info = EmptyString();
537       break;
538 
539     case kRegexpNoMatch:
540       info = NoMatch();
541       break;
542 
543     // These ops match the empty string:
544     case kRegexpEmptyMatch:      // anywhere
545     case kRegexpBeginLine:       // at beginning of line
546     case kRegexpEndLine:         // at end of line
547     case kRegexpBeginText:       // at beginning of text
548     case kRegexpEndText:         // at end of text
549     case kRegexpWordBoundary:    // at word boundary
550     case kRegexpNoWordBoundary:  // not at word boundary
551       info = EmptyString();
552       break;
553 
554     case kRegexpLiteral:
555       if (latin1()) {
556         info = LiteralLatin1(re->rune());
557       }
558       else {
559         info = Literal(re->rune());
560       }
561       break;
562 
563     case kRegexpLiteralString:
564       if (re->nrunes() == 0) {
565         info = NoMatch();
566         break;
567       }
568       if (latin1()) {
569         info = LiteralLatin1(re->runes()[0]);
570         for (int i = 1; i < re->nrunes(); i++) {
571           info = Concat(info, LiteralLatin1(re->runes()[i]));
572         }
573       } else {
574         info = Literal(re->runes()[0]);
575         for (int i = 1; i < re->nrunes(); i++) {
576           info = Concat(info, Literal(re->runes()[i]));
577         }
578       }
579       break;
580 
581     case kRegexpConcat: {
582       // Accumulate in info.
583       // Exact is concat of recent contiguous exact nodes.
584       info = NULL;
585       Info* exact = NULL;
586       for (int i = 0; i < nchild_args; i++) {
587         Info* ci = child_args[i];  // child info
588         if (!ci->is_exact() ||
589             (exact && ci->exact().size() * exact->exact().size() > 16)) {
590           // Exact run is over.
591           info = And(info, exact);
592           exact = NULL;
593           // Add this child's info.
594           info = And(info, ci);
595         } else {
596           // Append to exact run.
597           exact = Concat(exact, ci);
598         }
599       }
600       info = And(info, exact);
601     }
602       break;
603 
604     case kRegexpAlternate:
605       info = child_args[0];
606       for (int i = 1; i < nchild_args; i++)
607         info = Alt(info, child_args[i]);
608       break;
609 
610     case kRegexpStar:
611       info = Star(child_args[0]);
612       break;
613 
614     case kRegexpQuest:
615       info = Quest(child_args[0]);
616       break;
617 
618     case kRegexpPlus:
619       info = Plus(child_args[0]);
620       break;
621 
622     case kRegexpAnyChar:
623     case kRegexpAnyByte:
624       // Claim nothing, except that it's not empty.
625       info = AnyCharOrAnyByte();
626       break;
627 
628     case kRegexpCharClass:
629       info = CClass(re->cc(), latin1());
630       break;
631 
632     case kRegexpCapture:
633       // These don't affect the set of matching strings.
634       info = child_args[0];
635       break;
636   }
637 
638   if (ExtraDebug)
639     LOG(ERROR) << "BuildInfo " << re->ToString()
640                << ": " << (info ? info->ToString() : "");
641 
642   return info;
643 }
644 
645 
FromRegexp(Regexp * re)646 Prefilter* Prefilter::FromRegexp(Regexp* re) {
647   if (re == NULL)
648     return NULL;
649 
650   Regexp* simple = re->Simplify();
651   Prefilter::Info *info = BuildInfo(simple);
652 
653   simple->Decref();
654   if (info == NULL)
655     return NULL;
656 
657   Prefilter* m = info->TakeMatch();
658 
659   delete info;
660   return m;
661 }
662 
DebugString() const663 std::string Prefilter::DebugString() const {
664   switch (op_) {
665     default:
666       LOG(DFATAL) << "Bad op in Prefilter::DebugString: " << op_;
667       return StringPrintf("op%d", op_);
668     case NONE:
669       return "*no-matches*";
670     case ATOM:
671       return atom_;
672     case ALL:
673       return "";
674     case AND: {
675       std::string s = "";
676       for (size_t i = 0; i < subs_->size(); i++) {
677         if (i > 0)
678           s += " ";
679         Prefilter* sub = (*subs_)[i];
680         s += sub ? sub->DebugString() : "<nil>";
681       }
682       return s;
683     }
684     case OR: {
685       std::string s = "(";
686       for (size_t i = 0; i < subs_->size(); i++) {
687         if (i > 0)
688           s += "|";
689         Prefilter* sub = (*subs_)[i];
690         s += sub ? sub->DebugString() : "<nil>";
691       }
692       s += ")";
693       return s;
694     }
695   }
696 }
697 
FromRE2(const RE2 * re2)698 Prefilter* Prefilter::FromRE2(const RE2* re2) {
699   if (re2 == NULL)
700     return NULL;
701 
702   Regexp* regexp = re2->Regexp();
703   if (regexp == NULL)
704     return NULL;
705 
706   return FromRegexp(regexp);
707 }
708 
709 
710 }  // namespace re2
711