xref: /aosp_15_r20/external/regex-re2/re2/parse.cc (revision ccdc9c3e24c519bfa4832a66aa2e83a52c19f295)
1*ccdc9c3eSSadaf Ebrahimi // Copyright 2006 The RE2 Authors.  All Rights Reserved.
2*ccdc9c3eSSadaf Ebrahimi // Use of this source code is governed by a BSD-style
3*ccdc9c3eSSadaf Ebrahimi // license that can be found in the LICENSE file.
4*ccdc9c3eSSadaf Ebrahimi 
5*ccdc9c3eSSadaf Ebrahimi // Regular expression parser.
6*ccdc9c3eSSadaf Ebrahimi 
7*ccdc9c3eSSadaf Ebrahimi // The parser is a simple precedence-based parser with a
8*ccdc9c3eSSadaf Ebrahimi // manual stack.  The parsing work is done by the methods
9*ccdc9c3eSSadaf Ebrahimi // of the ParseState class.  The Regexp::Parse function is
10*ccdc9c3eSSadaf Ebrahimi // essentially just a lexer that calls the ParseState method
11*ccdc9c3eSSadaf Ebrahimi // for each token.
12*ccdc9c3eSSadaf Ebrahimi 
13*ccdc9c3eSSadaf Ebrahimi // The parser recognizes POSIX extended regular expressions
14*ccdc9c3eSSadaf Ebrahimi // excluding backreferences, collating elements, and collating
15*ccdc9c3eSSadaf Ebrahimi // classes.  It also allows the empty string as a regular expression
16*ccdc9c3eSSadaf Ebrahimi // and recognizes the Perl escape sequences \d, \s, \w, \D, \S, and \W.
17*ccdc9c3eSSadaf Ebrahimi // See regexp.h for rationale.
18*ccdc9c3eSSadaf Ebrahimi 
19*ccdc9c3eSSadaf Ebrahimi #include <ctype.h>
20*ccdc9c3eSSadaf Ebrahimi #include <stddef.h>
21*ccdc9c3eSSadaf Ebrahimi #include <stdint.h>
22*ccdc9c3eSSadaf Ebrahimi #include <string.h>
23*ccdc9c3eSSadaf Ebrahimi #include <algorithm>
24*ccdc9c3eSSadaf Ebrahimi #include <map>
25*ccdc9c3eSSadaf Ebrahimi #include <string>
26*ccdc9c3eSSadaf Ebrahimi #include <vector>
27*ccdc9c3eSSadaf Ebrahimi 
28*ccdc9c3eSSadaf Ebrahimi #include "util/util.h"
29*ccdc9c3eSSadaf Ebrahimi #include "util/logging.h"
30*ccdc9c3eSSadaf Ebrahimi #include "util/pod_array.h"
31*ccdc9c3eSSadaf Ebrahimi #include "util/strutil.h"
32*ccdc9c3eSSadaf Ebrahimi #include "util/utf.h"
33*ccdc9c3eSSadaf Ebrahimi #include "re2/regexp.h"
34*ccdc9c3eSSadaf Ebrahimi #include "re2/stringpiece.h"
35*ccdc9c3eSSadaf Ebrahimi #include "re2/unicode_casefold.h"
36*ccdc9c3eSSadaf Ebrahimi #include "re2/unicode_groups.h"
37*ccdc9c3eSSadaf Ebrahimi #include "re2/walker-inl.h"
38*ccdc9c3eSSadaf Ebrahimi 
39*ccdc9c3eSSadaf Ebrahimi #if defined(RE2_USE_ICU)
40*ccdc9c3eSSadaf Ebrahimi #include "unicode/uniset.h"
41*ccdc9c3eSSadaf Ebrahimi #include "unicode/unistr.h"
42*ccdc9c3eSSadaf Ebrahimi #include "unicode/utypes.h"
43*ccdc9c3eSSadaf Ebrahimi #endif
44*ccdc9c3eSSadaf Ebrahimi 
45*ccdc9c3eSSadaf Ebrahimi namespace re2 {
46*ccdc9c3eSSadaf Ebrahimi 
47*ccdc9c3eSSadaf Ebrahimi // Reduce the maximum repeat count by an order of magnitude when fuzzing.
48*ccdc9c3eSSadaf Ebrahimi #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
49*ccdc9c3eSSadaf Ebrahimi static const int kMaxRepeat = 100;
50*ccdc9c3eSSadaf Ebrahimi #else
51*ccdc9c3eSSadaf Ebrahimi static const int kMaxRepeat = 1000;
52*ccdc9c3eSSadaf Ebrahimi #endif
53*ccdc9c3eSSadaf Ebrahimi 
54*ccdc9c3eSSadaf Ebrahimi // Regular expression parse state.
55*ccdc9c3eSSadaf Ebrahimi // The list of parsed regexps so far is maintained as a vector of
56*ccdc9c3eSSadaf Ebrahimi // Regexp pointers called the stack.  Left parenthesis and vertical
57*ccdc9c3eSSadaf Ebrahimi // bar markers are also placed on the stack, as Regexps with
58*ccdc9c3eSSadaf Ebrahimi // non-standard opcodes.
59*ccdc9c3eSSadaf Ebrahimi // Scanning a left parenthesis causes the parser to push a left parenthesis
60*ccdc9c3eSSadaf Ebrahimi // marker on the stack.
61*ccdc9c3eSSadaf Ebrahimi // Scanning a vertical bar causes the parser to pop the stack until it finds a
62*ccdc9c3eSSadaf Ebrahimi // vertical bar or left parenthesis marker (not popping the marker),
63*ccdc9c3eSSadaf Ebrahimi // concatenate all the popped results, and push them back on
64*ccdc9c3eSSadaf Ebrahimi // the stack (DoConcatenation).
65*ccdc9c3eSSadaf Ebrahimi // Scanning a right parenthesis causes the parser to act as though it
66*ccdc9c3eSSadaf Ebrahimi // has seen a vertical bar, which then leaves the top of the stack in the
67*ccdc9c3eSSadaf Ebrahimi // form LeftParen regexp VerticalBar regexp VerticalBar ... regexp VerticalBar.
68*ccdc9c3eSSadaf Ebrahimi // The parser pops all this off the stack and creates an alternation of the
69*ccdc9c3eSSadaf Ebrahimi // regexps (DoAlternation).
70*ccdc9c3eSSadaf Ebrahimi 
71*ccdc9c3eSSadaf Ebrahimi class Regexp::ParseState {
72*ccdc9c3eSSadaf Ebrahimi  public:
73*ccdc9c3eSSadaf Ebrahimi   ParseState(ParseFlags flags, const StringPiece& whole_regexp,
74*ccdc9c3eSSadaf Ebrahimi              RegexpStatus* status);
75*ccdc9c3eSSadaf Ebrahimi   ~ParseState();
76*ccdc9c3eSSadaf Ebrahimi 
flags()77*ccdc9c3eSSadaf Ebrahimi   ParseFlags flags() { return flags_; }
rune_max()78*ccdc9c3eSSadaf Ebrahimi   int rune_max() { return rune_max_; }
79*ccdc9c3eSSadaf Ebrahimi 
80*ccdc9c3eSSadaf Ebrahimi   // Parse methods.  All public methods return a bool saying
81*ccdc9c3eSSadaf Ebrahimi   // whether parsing should continue.  If a method returns
82*ccdc9c3eSSadaf Ebrahimi   // false, it has set fields in *status_, and the parser
83*ccdc9c3eSSadaf Ebrahimi   // should return NULL.
84*ccdc9c3eSSadaf Ebrahimi 
85*ccdc9c3eSSadaf Ebrahimi   // Pushes the given regular expression onto the stack.
86*ccdc9c3eSSadaf Ebrahimi   // Could check for too much memory used here.
87*ccdc9c3eSSadaf Ebrahimi   bool PushRegexp(Regexp* re);
88*ccdc9c3eSSadaf Ebrahimi 
89*ccdc9c3eSSadaf Ebrahimi   // Pushes the literal rune r onto the stack.
90*ccdc9c3eSSadaf Ebrahimi   bool PushLiteral(Rune r);
91*ccdc9c3eSSadaf Ebrahimi 
92*ccdc9c3eSSadaf Ebrahimi   // Pushes a regexp with the given op (and no args) onto the stack.
93*ccdc9c3eSSadaf Ebrahimi   bool PushSimpleOp(RegexpOp op);
94*ccdc9c3eSSadaf Ebrahimi 
95*ccdc9c3eSSadaf Ebrahimi   // Pushes a ^ onto the stack.
96*ccdc9c3eSSadaf Ebrahimi   bool PushCarat();
97*ccdc9c3eSSadaf Ebrahimi 
98*ccdc9c3eSSadaf Ebrahimi   // Pushes a \b (word == true) or \B (word == false) onto the stack.
99*ccdc9c3eSSadaf Ebrahimi   bool PushWordBoundary(bool word);
100*ccdc9c3eSSadaf Ebrahimi 
101*ccdc9c3eSSadaf Ebrahimi   // Pushes a $ onto the stack.
102*ccdc9c3eSSadaf Ebrahimi   bool PushDollar();
103*ccdc9c3eSSadaf Ebrahimi 
104*ccdc9c3eSSadaf Ebrahimi   // Pushes a . onto the stack
105*ccdc9c3eSSadaf Ebrahimi   bool PushDot();
106*ccdc9c3eSSadaf Ebrahimi 
107*ccdc9c3eSSadaf Ebrahimi   // Pushes a repeat operator regexp onto the stack.
108*ccdc9c3eSSadaf Ebrahimi   // A valid argument for the operator must already be on the stack.
109*ccdc9c3eSSadaf Ebrahimi   // s is the name of the operator, for use in error messages.
110*ccdc9c3eSSadaf Ebrahimi   bool PushRepeatOp(RegexpOp op, const StringPiece& s, bool nongreedy);
111*ccdc9c3eSSadaf Ebrahimi 
112*ccdc9c3eSSadaf Ebrahimi   // Pushes a repetition regexp onto the stack.
113*ccdc9c3eSSadaf Ebrahimi   // A valid argument for the operator must already be on the stack.
114*ccdc9c3eSSadaf Ebrahimi   bool PushRepetition(int min, int max, const StringPiece& s, bool nongreedy);
115*ccdc9c3eSSadaf Ebrahimi 
116*ccdc9c3eSSadaf Ebrahimi   // Checks whether a particular regexp op is a marker.
117*ccdc9c3eSSadaf Ebrahimi   bool IsMarker(RegexpOp op);
118*ccdc9c3eSSadaf Ebrahimi 
119*ccdc9c3eSSadaf Ebrahimi   // Processes a left parenthesis in the input.
120*ccdc9c3eSSadaf Ebrahimi   // Pushes a marker onto the stack.
121*ccdc9c3eSSadaf Ebrahimi   bool DoLeftParen(const StringPiece& name);
122*ccdc9c3eSSadaf Ebrahimi   bool DoLeftParenNoCapture();
123*ccdc9c3eSSadaf Ebrahimi 
124*ccdc9c3eSSadaf Ebrahimi   // Processes a vertical bar in the input.
125*ccdc9c3eSSadaf Ebrahimi   bool DoVerticalBar();
126*ccdc9c3eSSadaf Ebrahimi 
127*ccdc9c3eSSadaf Ebrahimi   // Processes a right parenthesis in the input.
128*ccdc9c3eSSadaf Ebrahimi   bool DoRightParen();
129*ccdc9c3eSSadaf Ebrahimi 
130*ccdc9c3eSSadaf Ebrahimi   // Processes the end of input, returning the final regexp.
131*ccdc9c3eSSadaf Ebrahimi   Regexp* DoFinish();
132*ccdc9c3eSSadaf Ebrahimi 
133*ccdc9c3eSSadaf Ebrahimi   // Finishes the regexp if necessary, preparing it for use
134*ccdc9c3eSSadaf Ebrahimi   // in a more complicated expression.
135*ccdc9c3eSSadaf Ebrahimi   // If it is a CharClassBuilder, converts into a CharClass.
136*ccdc9c3eSSadaf Ebrahimi   Regexp* FinishRegexp(Regexp*);
137*ccdc9c3eSSadaf Ebrahimi 
138*ccdc9c3eSSadaf Ebrahimi   // These routines don't manipulate the parse stack
139*ccdc9c3eSSadaf Ebrahimi   // directly, but they do need to look at flags_.
140*ccdc9c3eSSadaf Ebrahimi   // ParseCharClass also manipulates the internals of Regexp
141*ccdc9c3eSSadaf Ebrahimi   // while creating *out_re.
142*ccdc9c3eSSadaf Ebrahimi 
143*ccdc9c3eSSadaf Ebrahimi   // Parse a character class into *out_re.
144*ccdc9c3eSSadaf Ebrahimi   // Removes parsed text from s.
145*ccdc9c3eSSadaf Ebrahimi   bool ParseCharClass(StringPiece* s, Regexp** out_re,
146*ccdc9c3eSSadaf Ebrahimi                       RegexpStatus* status);
147*ccdc9c3eSSadaf Ebrahimi 
148*ccdc9c3eSSadaf Ebrahimi   // Parse a character class character into *rp.
149*ccdc9c3eSSadaf Ebrahimi   // Removes parsed text from s.
150*ccdc9c3eSSadaf Ebrahimi   bool ParseCCCharacter(StringPiece* s, Rune *rp,
151*ccdc9c3eSSadaf Ebrahimi                         const StringPiece& whole_class,
152*ccdc9c3eSSadaf Ebrahimi                         RegexpStatus* status);
153*ccdc9c3eSSadaf Ebrahimi 
154*ccdc9c3eSSadaf Ebrahimi   // Parse a character class range into rr.
155*ccdc9c3eSSadaf Ebrahimi   // Removes parsed text from s.
156*ccdc9c3eSSadaf Ebrahimi   bool ParseCCRange(StringPiece* s, RuneRange* rr,
157*ccdc9c3eSSadaf Ebrahimi                     const StringPiece& whole_class,
158*ccdc9c3eSSadaf Ebrahimi                     RegexpStatus* status);
159*ccdc9c3eSSadaf Ebrahimi 
160*ccdc9c3eSSadaf Ebrahimi   // Parse a Perl flag set or non-capturing group from s.
161*ccdc9c3eSSadaf Ebrahimi   bool ParsePerlFlags(StringPiece* s);
162*ccdc9c3eSSadaf Ebrahimi 
163*ccdc9c3eSSadaf Ebrahimi 
164*ccdc9c3eSSadaf Ebrahimi   // Finishes the current concatenation,
165*ccdc9c3eSSadaf Ebrahimi   // collapsing it into a single regexp on the stack.
166*ccdc9c3eSSadaf Ebrahimi   void DoConcatenation();
167*ccdc9c3eSSadaf Ebrahimi 
168*ccdc9c3eSSadaf Ebrahimi   // Finishes the current alternation,
169*ccdc9c3eSSadaf Ebrahimi   // collapsing it to a single regexp on the stack.
170*ccdc9c3eSSadaf Ebrahimi   void DoAlternation();
171*ccdc9c3eSSadaf Ebrahimi 
172*ccdc9c3eSSadaf Ebrahimi   // Generalized DoAlternation/DoConcatenation.
173*ccdc9c3eSSadaf Ebrahimi   void DoCollapse(RegexpOp op);
174*ccdc9c3eSSadaf Ebrahimi 
175*ccdc9c3eSSadaf Ebrahimi   // Maybe concatenate Literals into LiteralString.
176*ccdc9c3eSSadaf Ebrahimi   bool MaybeConcatString(int r, ParseFlags flags);
177*ccdc9c3eSSadaf Ebrahimi 
178*ccdc9c3eSSadaf Ebrahimi private:
179*ccdc9c3eSSadaf Ebrahimi   ParseFlags flags_;
180*ccdc9c3eSSadaf Ebrahimi   StringPiece whole_regexp_;
181*ccdc9c3eSSadaf Ebrahimi   RegexpStatus* status_;
182*ccdc9c3eSSadaf Ebrahimi   Regexp* stacktop_;
183*ccdc9c3eSSadaf Ebrahimi   int ncap_;  // number of capturing parens seen
184*ccdc9c3eSSadaf Ebrahimi   int rune_max_;  // maximum char value for this encoding
185*ccdc9c3eSSadaf Ebrahimi 
186*ccdc9c3eSSadaf Ebrahimi   ParseState(const ParseState&) = delete;
187*ccdc9c3eSSadaf Ebrahimi   ParseState& operator=(const ParseState&) = delete;
188*ccdc9c3eSSadaf Ebrahimi };
189*ccdc9c3eSSadaf Ebrahimi 
190*ccdc9c3eSSadaf Ebrahimi // Pseudo-operators - only on parse stack.
191*ccdc9c3eSSadaf Ebrahimi const RegexpOp kLeftParen = static_cast<RegexpOp>(kMaxRegexpOp+1);
192*ccdc9c3eSSadaf Ebrahimi const RegexpOp kVerticalBar = static_cast<RegexpOp>(kMaxRegexpOp+2);
193*ccdc9c3eSSadaf Ebrahimi 
ParseState(ParseFlags flags,const StringPiece & whole_regexp,RegexpStatus * status)194*ccdc9c3eSSadaf Ebrahimi Regexp::ParseState::ParseState(ParseFlags flags,
195*ccdc9c3eSSadaf Ebrahimi                                const StringPiece& whole_regexp,
196*ccdc9c3eSSadaf Ebrahimi                                RegexpStatus* status)
197*ccdc9c3eSSadaf Ebrahimi   : flags_(flags), whole_regexp_(whole_regexp),
198*ccdc9c3eSSadaf Ebrahimi     status_(status), stacktop_(NULL), ncap_(0) {
199*ccdc9c3eSSadaf Ebrahimi   if (flags_ & Latin1)
200*ccdc9c3eSSadaf Ebrahimi     rune_max_ = 0xFF;
201*ccdc9c3eSSadaf Ebrahimi   else
202*ccdc9c3eSSadaf Ebrahimi     rune_max_ = Runemax;
203*ccdc9c3eSSadaf Ebrahimi }
204*ccdc9c3eSSadaf Ebrahimi 
205*ccdc9c3eSSadaf Ebrahimi // Cleans up by freeing all the regexps on the stack.
~ParseState()206*ccdc9c3eSSadaf Ebrahimi Regexp::ParseState::~ParseState() {
207*ccdc9c3eSSadaf Ebrahimi   Regexp* next;
208*ccdc9c3eSSadaf Ebrahimi   for (Regexp* re = stacktop_; re != NULL; re = next) {
209*ccdc9c3eSSadaf Ebrahimi     next = re->down_;
210*ccdc9c3eSSadaf Ebrahimi     re->down_ = NULL;
211*ccdc9c3eSSadaf Ebrahimi     if (re->op() == kLeftParen)
212*ccdc9c3eSSadaf Ebrahimi       delete re->name_;
213*ccdc9c3eSSadaf Ebrahimi     re->Decref();
214*ccdc9c3eSSadaf Ebrahimi   }
215*ccdc9c3eSSadaf Ebrahimi }
216*ccdc9c3eSSadaf Ebrahimi 
217*ccdc9c3eSSadaf Ebrahimi // Finishes the regexp if necessary, preparing it for use in
218*ccdc9c3eSSadaf Ebrahimi // a more complex expression.
219*ccdc9c3eSSadaf Ebrahimi // If it is a CharClassBuilder, converts into a CharClass.
FinishRegexp(Regexp * re)220*ccdc9c3eSSadaf Ebrahimi Regexp* Regexp::ParseState::FinishRegexp(Regexp* re) {
221*ccdc9c3eSSadaf Ebrahimi   if (re == NULL)
222*ccdc9c3eSSadaf Ebrahimi     return NULL;
223*ccdc9c3eSSadaf Ebrahimi   re->down_ = NULL;
224*ccdc9c3eSSadaf Ebrahimi 
225*ccdc9c3eSSadaf Ebrahimi   if (re->op_ == kRegexpCharClass && re->ccb_ != NULL) {
226*ccdc9c3eSSadaf Ebrahimi     CharClassBuilder* ccb = re->ccb_;
227*ccdc9c3eSSadaf Ebrahimi     re->ccb_ = NULL;
228*ccdc9c3eSSadaf Ebrahimi     re->cc_ = ccb->GetCharClass();
229*ccdc9c3eSSadaf Ebrahimi     delete ccb;
230*ccdc9c3eSSadaf Ebrahimi   }
231*ccdc9c3eSSadaf Ebrahimi 
232*ccdc9c3eSSadaf Ebrahimi   return re;
233*ccdc9c3eSSadaf Ebrahimi }
234*ccdc9c3eSSadaf Ebrahimi 
235*ccdc9c3eSSadaf Ebrahimi // Pushes the given regular expression onto the stack.
236*ccdc9c3eSSadaf Ebrahimi // Could check for too much memory used here.
PushRegexp(Regexp * re)237*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::PushRegexp(Regexp* re) {
238*ccdc9c3eSSadaf Ebrahimi   MaybeConcatString(-1, NoParseFlags);
239*ccdc9c3eSSadaf Ebrahimi 
240*ccdc9c3eSSadaf Ebrahimi   // Special case: a character class of one character is just
241*ccdc9c3eSSadaf Ebrahimi   // a literal.  This is a common idiom for escaping
242*ccdc9c3eSSadaf Ebrahimi   // single characters (e.g., [.] instead of \.), and some
243*ccdc9c3eSSadaf Ebrahimi   // analysis does better with fewer character classes.
244*ccdc9c3eSSadaf Ebrahimi   // Similarly, [Aa] can be rewritten as a literal A with ASCII case folding.
245*ccdc9c3eSSadaf Ebrahimi   if (re->op_ == kRegexpCharClass && re->ccb_ != NULL) {
246*ccdc9c3eSSadaf Ebrahimi     re->ccb_->RemoveAbove(rune_max_);
247*ccdc9c3eSSadaf Ebrahimi     if (re->ccb_->size() == 1) {
248*ccdc9c3eSSadaf Ebrahimi       Rune r = re->ccb_->begin()->lo;
249*ccdc9c3eSSadaf Ebrahimi       re->Decref();
250*ccdc9c3eSSadaf Ebrahimi       re = new Regexp(kRegexpLiteral, flags_);
251*ccdc9c3eSSadaf Ebrahimi       re->rune_ = r;
252*ccdc9c3eSSadaf Ebrahimi     } else if (re->ccb_->size() == 2) {
253*ccdc9c3eSSadaf Ebrahimi       Rune r = re->ccb_->begin()->lo;
254*ccdc9c3eSSadaf Ebrahimi       if ('A' <= r && r <= 'Z' && re->ccb_->Contains(r + 'a' - 'A')) {
255*ccdc9c3eSSadaf Ebrahimi         re->Decref();
256*ccdc9c3eSSadaf Ebrahimi         re = new Regexp(kRegexpLiteral, flags_ | FoldCase);
257*ccdc9c3eSSadaf Ebrahimi         re->rune_ = r + 'a' - 'A';
258*ccdc9c3eSSadaf Ebrahimi       }
259*ccdc9c3eSSadaf Ebrahimi     }
260*ccdc9c3eSSadaf Ebrahimi   }
261*ccdc9c3eSSadaf Ebrahimi 
262*ccdc9c3eSSadaf Ebrahimi   if (!IsMarker(re->op()))
263*ccdc9c3eSSadaf Ebrahimi     re->simple_ = re->ComputeSimple();
264*ccdc9c3eSSadaf Ebrahimi   re->down_ = stacktop_;
265*ccdc9c3eSSadaf Ebrahimi   stacktop_ = re;
266*ccdc9c3eSSadaf Ebrahimi   return true;
267*ccdc9c3eSSadaf Ebrahimi }
268*ccdc9c3eSSadaf Ebrahimi 
269*ccdc9c3eSSadaf Ebrahimi // Searches the case folding tables and returns the CaseFold* that contains r.
270*ccdc9c3eSSadaf Ebrahimi // If there isn't one, returns the CaseFold* with smallest f->lo bigger than r.
271*ccdc9c3eSSadaf Ebrahimi // If there isn't one, returns NULL.
LookupCaseFold(const CaseFold * f,int n,Rune r)272*ccdc9c3eSSadaf Ebrahimi const CaseFold* LookupCaseFold(const CaseFold *f, int n, Rune r) {
273*ccdc9c3eSSadaf Ebrahimi   const CaseFold* ef = f + n;
274*ccdc9c3eSSadaf Ebrahimi 
275*ccdc9c3eSSadaf Ebrahimi   // Binary search for entry containing r.
276*ccdc9c3eSSadaf Ebrahimi   while (n > 0) {
277*ccdc9c3eSSadaf Ebrahimi     int m = n/2;
278*ccdc9c3eSSadaf Ebrahimi     if (f[m].lo <= r && r <= f[m].hi)
279*ccdc9c3eSSadaf Ebrahimi       return &f[m];
280*ccdc9c3eSSadaf Ebrahimi     if (r < f[m].lo) {
281*ccdc9c3eSSadaf Ebrahimi       n = m;
282*ccdc9c3eSSadaf Ebrahimi     } else {
283*ccdc9c3eSSadaf Ebrahimi       f += m+1;
284*ccdc9c3eSSadaf Ebrahimi       n -= m+1;
285*ccdc9c3eSSadaf Ebrahimi     }
286*ccdc9c3eSSadaf Ebrahimi   }
287*ccdc9c3eSSadaf Ebrahimi 
288*ccdc9c3eSSadaf Ebrahimi   // There is no entry that contains r, but f points
289*ccdc9c3eSSadaf Ebrahimi   // where it would have been.  Unless f points at
290*ccdc9c3eSSadaf Ebrahimi   // the end of the array, it points at the next entry
291*ccdc9c3eSSadaf Ebrahimi   // after r.
292*ccdc9c3eSSadaf Ebrahimi   if (f < ef)
293*ccdc9c3eSSadaf Ebrahimi     return f;
294*ccdc9c3eSSadaf Ebrahimi 
295*ccdc9c3eSSadaf Ebrahimi   // No entry contains r; no entry contains runes > r.
296*ccdc9c3eSSadaf Ebrahimi   return NULL;
297*ccdc9c3eSSadaf Ebrahimi }
298*ccdc9c3eSSadaf Ebrahimi 
299*ccdc9c3eSSadaf Ebrahimi // Returns the result of applying the fold f to the rune r.
ApplyFold(const CaseFold * f,Rune r)300*ccdc9c3eSSadaf Ebrahimi Rune ApplyFold(const CaseFold *f, Rune r) {
301*ccdc9c3eSSadaf Ebrahimi   switch (f->delta) {
302*ccdc9c3eSSadaf Ebrahimi     default:
303*ccdc9c3eSSadaf Ebrahimi       return r + f->delta;
304*ccdc9c3eSSadaf Ebrahimi 
305*ccdc9c3eSSadaf Ebrahimi     case EvenOddSkip:  // even <-> odd but only applies to every other
306*ccdc9c3eSSadaf Ebrahimi       if ((r - f->lo) % 2)
307*ccdc9c3eSSadaf Ebrahimi         return r;
308*ccdc9c3eSSadaf Ebrahimi       FALLTHROUGH_INTENDED;
309*ccdc9c3eSSadaf Ebrahimi     case EvenOdd:  // even <-> odd
310*ccdc9c3eSSadaf Ebrahimi       if (r%2 == 0)
311*ccdc9c3eSSadaf Ebrahimi         return r + 1;
312*ccdc9c3eSSadaf Ebrahimi       return r - 1;
313*ccdc9c3eSSadaf Ebrahimi 
314*ccdc9c3eSSadaf Ebrahimi     case OddEvenSkip:  // odd <-> even but only applies to every other
315*ccdc9c3eSSadaf Ebrahimi       if ((r - f->lo) % 2)
316*ccdc9c3eSSadaf Ebrahimi         return r;
317*ccdc9c3eSSadaf Ebrahimi       FALLTHROUGH_INTENDED;
318*ccdc9c3eSSadaf Ebrahimi     case OddEven:  // odd <-> even
319*ccdc9c3eSSadaf Ebrahimi       if (r%2 == 1)
320*ccdc9c3eSSadaf Ebrahimi         return r + 1;
321*ccdc9c3eSSadaf Ebrahimi       return r - 1;
322*ccdc9c3eSSadaf Ebrahimi   }
323*ccdc9c3eSSadaf Ebrahimi }
324*ccdc9c3eSSadaf Ebrahimi 
325*ccdc9c3eSSadaf Ebrahimi // Returns the next Rune in r's folding cycle (see unicode_casefold.h).
326*ccdc9c3eSSadaf Ebrahimi // Examples:
327*ccdc9c3eSSadaf Ebrahimi //   CycleFoldRune('A') = 'a'
328*ccdc9c3eSSadaf Ebrahimi //   CycleFoldRune('a') = 'A'
329*ccdc9c3eSSadaf Ebrahimi //
330*ccdc9c3eSSadaf Ebrahimi //   CycleFoldRune('K') = 'k'
331*ccdc9c3eSSadaf Ebrahimi //   CycleFoldRune('k') = 0x212A (Kelvin)
332*ccdc9c3eSSadaf Ebrahimi //   CycleFoldRune(0x212A) = 'K'
333*ccdc9c3eSSadaf Ebrahimi //
334*ccdc9c3eSSadaf Ebrahimi //   CycleFoldRune('?') = '?'
CycleFoldRune(Rune r)335*ccdc9c3eSSadaf Ebrahimi Rune CycleFoldRune(Rune r) {
336*ccdc9c3eSSadaf Ebrahimi   const CaseFold* f = LookupCaseFold(unicode_casefold, num_unicode_casefold, r);
337*ccdc9c3eSSadaf Ebrahimi   if (f == NULL || r < f->lo)
338*ccdc9c3eSSadaf Ebrahimi     return r;
339*ccdc9c3eSSadaf Ebrahimi   return ApplyFold(f, r);
340*ccdc9c3eSSadaf Ebrahimi }
341*ccdc9c3eSSadaf Ebrahimi 
342*ccdc9c3eSSadaf Ebrahimi // Add lo-hi to the class, along with their fold-equivalent characters.
343*ccdc9c3eSSadaf Ebrahimi // If lo-hi is already in the class, assume that the fold-equivalent
344*ccdc9c3eSSadaf Ebrahimi // chars are there too, so there's no work to do.
AddFoldedRange(CharClassBuilder * cc,Rune lo,Rune hi,int depth)345*ccdc9c3eSSadaf Ebrahimi static void AddFoldedRange(CharClassBuilder* cc, Rune lo, Rune hi, int depth) {
346*ccdc9c3eSSadaf Ebrahimi   // AddFoldedRange calls itself recursively for each rune in the fold cycle.
347*ccdc9c3eSSadaf Ebrahimi   // Most folding cycles are small: there aren't any bigger than four in the
348*ccdc9c3eSSadaf Ebrahimi   // current Unicode tables.  make_unicode_casefold.py checks that
349*ccdc9c3eSSadaf Ebrahimi   // the cycles are not too long, and we double-check here using depth.
350*ccdc9c3eSSadaf Ebrahimi   if (depth > 10) {
351*ccdc9c3eSSadaf Ebrahimi     LOG(DFATAL) << "AddFoldedRange recurses too much.";
352*ccdc9c3eSSadaf Ebrahimi     return;
353*ccdc9c3eSSadaf Ebrahimi   }
354*ccdc9c3eSSadaf Ebrahimi 
355*ccdc9c3eSSadaf Ebrahimi   if (!cc->AddRange(lo, hi))  // lo-hi was already there? we're done
356*ccdc9c3eSSadaf Ebrahimi     return;
357*ccdc9c3eSSadaf Ebrahimi 
358*ccdc9c3eSSadaf Ebrahimi   while (lo <= hi) {
359*ccdc9c3eSSadaf Ebrahimi     const CaseFold* f = LookupCaseFold(unicode_casefold, num_unicode_casefold, lo);
360*ccdc9c3eSSadaf Ebrahimi     if (f == NULL)  // lo has no fold, nor does anything above lo
361*ccdc9c3eSSadaf Ebrahimi       break;
362*ccdc9c3eSSadaf Ebrahimi     if (lo < f->lo) {  // lo has no fold; next rune with a fold is f->lo
363*ccdc9c3eSSadaf Ebrahimi       lo = f->lo;
364*ccdc9c3eSSadaf Ebrahimi       continue;
365*ccdc9c3eSSadaf Ebrahimi     }
366*ccdc9c3eSSadaf Ebrahimi 
367*ccdc9c3eSSadaf Ebrahimi     // Add in the result of folding the range lo - f->hi
368*ccdc9c3eSSadaf Ebrahimi     // and that range's fold, recursively.
369*ccdc9c3eSSadaf Ebrahimi     Rune lo1 = lo;
370*ccdc9c3eSSadaf Ebrahimi     Rune hi1 = std::min<Rune>(hi, f->hi);
371*ccdc9c3eSSadaf Ebrahimi     switch (f->delta) {
372*ccdc9c3eSSadaf Ebrahimi       default:
373*ccdc9c3eSSadaf Ebrahimi         lo1 += f->delta;
374*ccdc9c3eSSadaf Ebrahimi         hi1 += f->delta;
375*ccdc9c3eSSadaf Ebrahimi         break;
376*ccdc9c3eSSadaf Ebrahimi       case EvenOdd:
377*ccdc9c3eSSadaf Ebrahimi         if (lo1%2 == 1)
378*ccdc9c3eSSadaf Ebrahimi           lo1--;
379*ccdc9c3eSSadaf Ebrahimi         if (hi1%2 == 0)
380*ccdc9c3eSSadaf Ebrahimi           hi1++;
381*ccdc9c3eSSadaf Ebrahimi         break;
382*ccdc9c3eSSadaf Ebrahimi       case OddEven:
383*ccdc9c3eSSadaf Ebrahimi         if (lo1%2 == 0)
384*ccdc9c3eSSadaf Ebrahimi           lo1--;
385*ccdc9c3eSSadaf Ebrahimi         if (hi1%2 == 1)
386*ccdc9c3eSSadaf Ebrahimi           hi1++;
387*ccdc9c3eSSadaf Ebrahimi         break;
388*ccdc9c3eSSadaf Ebrahimi     }
389*ccdc9c3eSSadaf Ebrahimi     AddFoldedRange(cc, lo1, hi1, depth+1);
390*ccdc9c3eSSadaf Ebrahimi 
391*ccdc9c3eSSadaf Ebrahimi     // Pick up where this fold left off.
392*ccdc9c3eSSadaf Ebrahimi     lo = f->hi + 1;
393*ccdc9c3eSSadaf Ebrahimi   }
394*ccdc9c3eSSadaf Ebrahimi }
395*ccdc9c3eSSadaf Ebrahimi 
396*ccdc9c3eSSadaf Ebrahimi // Pushes the literal rune r onto the stack.
PushLiteral(Rune r)397*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::PushLiteral(Rune r) {
398*ccdc9c3eSSadaf Ebrahimi   // Do case folding if needed.
399*ccdc9c3eSSadaf Ebrahimi   if ((flags_ & FoldCase) && CycleFoldRune(r) != r) {
400*ccdc9c3eSSadaf Ebrahimi     Regexp* re = new Regexp(kRegexpCharClass, flags_ & ~FoldCase);
401*ccdc9c3eSSadaf Ebrahimi     re->ccb_ = new CharClassBuilder;
402*ccdc9c3eSSadaf Ebrahimi     Rune r1 = r;
403*ccdc9c3eSSadaf Ebrahimi     do {
404*ccdc9c3eSSadaf Ebrahimi       if (!(flags_ & NeverNL) || r != '\n') {
405*ccdc9c3eSSadaf Ebrahimi         re->ccb_->AddRange(r, r);
406*ccdc9c3eSSadaf Ebrahimi       }
407*ccdc9c3eSSadaf Ebrahimi       r = CycleFoldRune(r);
408*ccdc9c3eSSadaf Ebrahimi     } while (r != r1);
409*ccdc9c3eSSadaf Ebrahimi     return PushRegexp(re);
410*ccdc9c3eSSadaf Ebrahimi   }
411*ccdc9c3eSSadaf Ebrahimi 
412*ccdc9c3eSSadaf Ebrahimi   // Exclude newline if applicable.
413*ccdc9c3eSSadaf Ebrahimi   if ((flags_ & NeverNL) && r == '\n')
414*ccdc9c3eSSadaf Ebrahimi     return PushRegexp(new Regexp(kRegexpNoMatch, flags_));
415*ccdc9c3eSSadaf Ebrahimi 
416*ccdc9c3eSSadaf Ebrahimi   // No fancy stuff worked.  Ordinary literal.
417*ccdc9c3eSSadaf Ebrahimi   if (MaybeConcatString(r, flags_))
418*ccdc9c3eSSadaf Ebrahimi     return true;
419*ccdc9c3eSSadaf Ebrahimi 
420*ccdc9c3eSSadaf Ebrahimi   Regexp* re = new Regexp(kRegexpLiteral, flags_);
421*ccdc9c3eSSadaf Ebrahimi   re->rune_ = r;
422*ccdc9c3eSSadaf Ebrahimi   return PushRegexp(re);
423*ccdc9c3eSSadaf Ebrahimi }
424*ccdc9c3eSSadaf Ebrahimi 
425*ccdc9c3eSSadaf Ebrahimi // Pushes a ^ onto the stack.
PushCarat()426*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::PushCarat() {
427*ccdc9c3eSSadaf Ebrahimi   if (flags_ & OneLine) {
428*ccdc9c3eSSadaf Ebrahimi     return PushSimpleOp(kRegexpBeginText);
429*ccdc9c3eSSadaf Ebrahimi   }
430*ccdc9c3eSSadaf Ebrahimi   return PushSimpleOp(kRegexpBeginLine);
431*ccdc9c3eSSadaf Ebrahimi }
432*ccdc9c3eSSadaf Ebrahimi 
433*ccdc9c3eSSadaf Ebrahimi // Pushes a \b or \B onto the stack.
PushWordBoundary(bool word)434*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::PushWordBoundary(bool word) {
435*ccdc9c3eSSadaf Ebrahimi   if (word)
436*ccdc9c3eSSadaf Ebrahimi     return PushSimpleOp(kRegexpWordBoundary);
437*ccdc9c3eSSadaf Ebrahimi   return PushSimpleOp(kRegexpNoWordBoundary);
438*ccdc9c3eSSadaf Ebrahimi }
439*ccdc9c3eSSadaf Ebrahimi 
440*ccdc9c3eSSadaf Ebrahimi // Pushes a $ onto the stack.
PushDollar()441*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::PushDollar() {
442*ccdc9c3eSSadaf Ebrahimi   if (flags_ & OneLine) {
443*ccdc9c3eSSadaf Ebrahimi     // Clumsy marker so that MimicsPCRE() can tell whether
444*ccdc9c3eSSadaf Ebrahimi     // this kRegexpEndText was a $ and not a \z.
445*ccdc9c3eSSadaf Ebrahimi     Regexp::ParseFlags oflags = flags_;
446*ccdc9c3eSSadaf Ebrahimi     flags_ = flags_ | WasDollar;
447*ccdc9c3eSSadaf Ebrahimi     bool ret = PushSimpleOp(kRegexpEndText);
448*ccdc9c3eSSadaf Ebrahimi     flags_ = oflags;
449*ccdc9c3eSSadaf Ebrahimi     return ret;
450*ccdc9c3eSSadaf Ebrahimi   }
451*ccdc9c3eSSadaf Ebrahimi   return PushSimpleOp(kRegexpEndLine);
452*ccdc9c3eSSadaf Ebrahimi }
453*ccdc9c3eSSadaf Ebrahimi 
454*ccdc9c3eSSadaf Ebrahimi // Pushes a . onto the stack.
PushDot()455*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::PushDot() {
456*ccdc9c3eSSadaf Ebrahimi   if ((flags_ & DotNL) && !(flags_ & NeverNL))
457*ccdc9c3eSSadaf Ebrahimi     return PushSimpleOp(kRegexpAnyChar);
458*ccdc9c3eSSadaf Ebrahimi   // Rewrite . into [^\n]
459*ccdc9c3eSSadaf Ebrahimi   Regexp* re = new Regexp(kRegexpCharClass, flags_ & ~FoldCase);
460*ccdc9c3eSSadaf Ebrahimi   re->ccb_ = new CharClassBuilder;
461*ccdc9c3eSSadaf Ebrahimi   re->ccb_->AddRange(0, '\n' - 1);
462*ccdc9c3eSSadaf Ebrahimi   re->ccb_->AddRange('\n' + 1, rune_max_);
463*ccdc9c3eSSadaf Ebrahimi   return PushRegexp(re);
464*ccdc9c3eSSadaf Ebrahimi }
465*ccdc9c3eSSadaf Ebrahimi 
466*ccdc9c3eSSadaf Ebrahimi // Pushes a regexp with the given op (and no args) onto the stack.
PushSimpleOp(RegexpOp op)467*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::PushSimpleOp(RegexpOp op) {
468*ccdc9c3eSSadaf Ebrahimi   Regexp* re = new Regexp(op, flags_);
469*ccdc9c3eSSadaf Ebrahimi   return PushRegexp(re);
470*ccdc9c3eSSadaf Ebrahimi }
471*ccdc9c3eSSadaf Ebrahimi 
472*ccdc9c3eSSadaf Ebrahimi // Pushes a repeat operator regexp onto the stack.
473*ccdc9c3eSSadaf Ebrahimi // A valid argument for the operator must already be on the stack.
474*ccdc9c3eSSadaf Ebrahimi // The char c is the name of the operator, for use in error messages.
PushRepeatOp(RegexpOp op,const StringPiece & s,bool nongreedy)475*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::PushRepeatOp(RegexpOp op, const StringPiece& s,
476*ccdc9c3eSSadaf Ebrahimi                                       bool nongreedy) {
477*ccdc9c3eSSadaf Ebrahimi   if (stacktop_ == NULL || IsMarker(stacktop_->op())) {
478*ccdc9c3eSSadaf Ebrahimi     status_->set_code(kRegexpRepeatArgument);
479*ccdc9c3eSSadaf Ebrahimi     status_->set_error_arg(s);
480*ccdc9c3eSSadaf Ebrahimi     return false;
481*ccdc9c3eSSadaf Ebrahimi   }
482*ccdc9c3eSSadaf Ebrahimi   Regexp::ParseFlags fl = flags_;
483*ccdc9c3eSSadaf Ebrahimi   if (nongreedy)
484*ccdc9c3eSSadaf Ebrahimi     fl = fl ^ NonGreedy;
485*ccdc9c3eSSadaf Ebrahimi 
486*ccdc9c3eSSadaf Ebrahimi   // Squash **, ++ and ??. Regexp::Star() et al. handle this too, but
487*ccdc9c3eSSadaf Ebrahimi   // they're mostly for use during simplification, not during parsing.
488*ccdc9c3eSSadaf Ebrahimi   if (op == stacktop_->op() && fl == stacktop_->parse_flags())
489*ccdc9c3eSSadaf Ebrahimi     return true;
490*ccdc9c3eSSadaf Ebrahimi 
491*ccdc9c3eSSadaf Ebrahimi   // Squash *+, *?, +*, +?, ?* and ?+. They all squash to *, so because
492*ccdc9c3eSSadaf Ebrahimi   // op is a repeat, we just have to check that stacktop_->op() is too,
493*ccdc9c3eSSadaf Ebrahimi   // then adjust stacktop_.
494*ccdc9c3eSSadaf Ebrahimi   if ((stacktop_->op() == kRegexpStar ||
495*ccdc9c3eSSadaf Ebrahimi        stacktop_->op() == kRegexpPlus ||
496*ccdc9c3eSSadaf Ebrahimi        stacktop_->op() == kRegexpQuest) &&
497*ccdc9c3eSSadaf Ebrahimi       fl == stacktop_->parse_flags()) {
498*ccdc9c3eSSadaf Ebrahimi     stacktop_->op_ = kRegexpStar;
499*ccdc9c3eSSadaf Ebrahimi     return true;
500*ccdc9c3eSSadaf Ebrahimi   }
501*ccdc9c3eSSadaf Ebrahimi 
502*ccdc9c3eSSadaf Ebrahimi   Regexp* re = new Regexp(op, fl);
503*ccdc9c3eSSadaf Ebrahimi   re->AllocSub(1);
504*ccdc9c3eSSadaf Ebrahimi   re->down_ = stacktop_->down_;
505*ccdc9c3eSSadaf Ebrahimi   re->sub()[0] = FinishRegexp(stacktop_);
506*ccdc9c3eSSadaf Ebrahimi   re->simple_ = re->ComputeSimple();
507*ccdc9c3eSSadaf Ebrahimi   stacktop_ = re;
508*ccdc9c3eSSadaf Ebrahimi   return true;
509*ccdc9c3eSSadaf Ebrahimi }
510*ccdc9c3eSSadaf Ebrahimi 
511*ccdc9c3eSSadaf Ebrahimi // RepetitionWalker reports whether the repetition regexp is valid.
512*ccdc9c3eSSadaf Ebrahimi // Valid means that the combination of the top-level repetition
513*ccdc9c3eSSadaf Ebrahimi // and any inner repetitions does not exceed n copies of the
514*ccdc9c3eSSadaf Ebrahimi // innermost thing.
515*ccdc9c3eSSadaf Ebrahimi // This rewalks the regexp tree and is called for every repetition,
516*ccdc9c3eSSadaf Ebrahimi // so we have to worry about inducing quadratic behavior in the parser.
517*ccdc9c3eSSadaf Ebrahimi // We avoid this by only using RepetitionWalker when min or max >= 2.
518*ccdc9c3eSSadaf Ebrahimi // In that case the depth of any >= 2 nesting can only get to 9 without
519*ccdc9c3eSSadaf Ebrahimi // triggering a parse error, so each subtree can only be rewalked 9 times.
520*ccdc9c3eSSadaf Ebrahimi class RepetitionWalker : public Regexp::Walker<int> {
521*ccdc9c3eSSadaf Ebrahimi  public:
RepetitionWalker()522*ccdc9c3eSSadaf Ebrahimi   RepetitionWalker() {}
523*ccdc9c3eSSadaf Ebrahimi   virtual int PreVisit(Regexp* re, int parent_arg, bool* stop);
524*ccdc9c3eSSadaf Ebrahimi   virtual int PostVisit(Regexp* re, int parent_arg, int pre_arg,
525*ccdc9c3eSSadaf Ebrahimi                         int* child_args, int nchild_args);
526*ccdc9c3eSSadaf Ebrahimi   virtual int ShortVisit(Regexp* re, int parent_arg);
527*ccdc9c3eSSadaf Ebrahimi 
528*ccdc9c3eSSadaf Ebrahimi  private:
529*ccdc9c3eSSadaf Ebrahimi   RepetitionWalker(const RepetitionWalker&) = delete;
530*ccdc9c3eSSadaf Ebrahimi   RepetitionWalker& operator=(const RepetitionWalker&) = delete;
531*ccdc9c3eSSadaf Ebrahimi };
532*ccdc9c3eSSadaf Ebrahimi 
PreVisit(Regexp * re,int parent_arg,bool * stop)533*ccdc9c3eSSadaf Ebrahimi int RepetitionWalker::PreVisit(Regexp* re, int parent_arg, bool* stop) {
534*ccdc9c3eSSadaf Ebrahimi   int arg = parent_arg;
535*ccdc9c3eSSadaf Ebrahimi   if (re->op() == kRegexpRepeat) {
536*ccdc9c3eSSadaf Ebrahimi     int m = re->max();
537*ccdc9c3eSSadaf Ebrahimi     if (m < 0) {
538*ccdc9c3eSSadaf Ebrahimi       m = re->min();
539*ccdc9c3eSSadaf Ebrahimi     }
540*ccdc9c3eSSadaf Ebrahimi     if (m > 0) {
541*ccdc9c3eSSadaf Ebrahimi       arg /= m;
542*ccdc9c3eSSadaf Ebrahimi     }
543*ccdc9c3eSSadaf Ebrahimi   }
544*ccdc9c3eSSadaf Ebrahimi   return arg;
545*ccdc9c3eSSadaf Ebrahimi }
546*ccdc9c3eSSadaf Ebrahimi 
PostVisit(Regexp * re,int parent_arg,int pre_arg,int * child_args,int nchild_args)547*ccdc9c3eSSadaf Ebrahimi int RepetitionWalker::PostVisit(Regexp* re, int parent_arg, int pre_arg,
548*ccdc9c3eSSadaf Ebrahimi                                 int* child_args, int nchild_args) {
549*ccdc9c3eSSadaf Ebrahimi   int arg = pre_arg;
550*ccdc9c3eSSadaf Ebrahimi   for (int i = 0; i < nchild_args; i++) {
551*ccdc9c3eSSadaf Ebrahimi     if (child_args[i] < arg) {
552*ccdc9c3eSSadaf Ebrahimi       arg = child_args[i];
553*ccdc9c3eSSadaf Ebrahimi     }
554*ccdc9c3eSSadaf Ebrahimi   }
555*ccdc9c3eSSadaf Ebrahimi   return arg;
556*ccdc9c3eSSadaf Ebrahimi }
557*ccdc9c3eSSadaf Ebrahimi 
ShortVisit(Regexp * re,int parent_arg)558*ccdc9c3eSSadaf Ebrahimi int RepetitionWalker::ShortVisit(Regexp* re, int parent_arg) {
559*ccdc9c3eSSadaf Ebrahimi   // This should never be called, since we use Walk and not
560*ccdc9c3eSSadaf Ebrahimi   // WalkExponential.
561*ccdc9c3eSSadaf Ebrahimi   LOG(DFATAL) << "RepetitionWalker::ShortVisit called";
562*ccdc9c3eSSadaf Ebrahimi   return 0;
563*ccdc9c3eSSadaf Ebrahimi }
564*ccdc9c3eSSadaf Ebrahimi 
565*ccdc9c3eSSadaf Ebrahimi // Pushes a repetition regexp onto the stack.
566*ccdc9c3eSSadaf Ebrahimi // A valid argument for the operator must already be on the stack.
PushRepetition(int min,int max,const StringPiece & s,bool nongreedy)567*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::PushRepetition(int min, int max,
568*ccdc9c3eSSadaf Ebrahimi                                         const StringPiece& s,
569*ccdc9c3eSSadaf Ebrahimi                                         bool nongreedy) {
570*ccdc9c3eSSadaf Ebrahimi   if ((max != -1 && max < min) || min > kMaxRepeat || max > kMaxRepeat) {
571*ccdc9c3eSSadaf Ebrahimi     status_->set_code(kRegexpRepeatSize);
572*ccdc9c3eSSadaf Ebrahimi     status_->set_error_arg(s);
573*ccdc9c3eSSadaf Ebrahimi     return false;
574*ccdc9c3eSSadaf Ebrahimi   }
575*ccdc9c3eSSadaf Ebrahimi   if (stacktop_ == NULL || IsMarker(stacktop_->op())) {
576*ccdc9c3eSSadaf Ebrahimi     status_->set_code(kRegexpRepeatArgument);
577*ccdc9c3eSSadaf Ebrahimi     status_->set_error_arg(s);
578*ccdc9c3eSSadaf Ebrahimi     return false;
579*ccdc9c3eSSadaf Ebrahimi   }
580*ccdc9c3eSSadaf Ebrahimi   Regexp::ParseFlags fl = flags_;
581*ccdc9c3eSSadaf Ebrahimi   if (nongreedy)
582*ccdc9c3eSSadaf Ebrahimi     fl = fl ^ NonGreedy;
583*ccdc9c3eSSadaf Ebrahimi   Regexp* re = new Regexp(kRegexpRepeat, fl);
584*ccdc9c3eSSadaf Ebrahimi   re->min_ = min;
585*ccdc9c3eSSadaf Ebrahimi   re->max_ = max;
586*ccdc9c3eSSadaf Ebrahimi   re->AllocSub(1);
587*ccdc9c3eSSadaf Ebrahimi   re->down_ = stacktop_->down_;
588*ccdc9c3eSSadaf Ebrahimi   re->sub()[0] = FinishRegexp(stacktop_);
589*ccdc9c3eSSadaf Ebrahimi   re->simple_ = re->ComputeSimple();
590*ccdc9c3eSSadaf Ebrahimi   stacktop_ = re;
591*ccdc9c3eSSadaf Ebrahimi   if (min >= 2 || max >= 2) {
592*ccdc9c3eSSadaf Ebrahimi     RepetitionWalker w;
593*ccdc9c3eSSadaf Ebrahimi     if (w.Walk(stacktop_, kMaxRepeat) == 0) {
594*ccdc9c3eSSadaf Ebrahimi       status_->set_code(kRegexpRepeatSize);
595*ccdc9c3eSSadaf Ebrahimi       status_->set_error_arg(s);
596*ccdc9c3eSSadaf Ebrahimi       return false;
597*ccdc9c3eSSadaf Ebrahimi     }
598*ccdc9c3eSSadaf Ebrahimi   }
599*ccdc9c3eSSadaf Ebrahimi   return true;
600*ccdc9c3eSSadaf Ebrahimi }
601*ccdc9c3eSSadaf Ebrahimi 
602*ccdc9c3eSSadaf Ebrahimi // Checks whether a particular regexp op is a marker.
IsMarker(RegexpOp op)603*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::IsMarker(RegexpOp op) {
604*ccdc9c3eSSadaf Ebrahimi   return op >= kLeftParen;
605*ccdc9c3eSSadaf Ebrahimi }
606*ccdc9c3eSSadaf Ebrahimi 
607*ccdc9c3eSSadaf Ebrahimi // Processes a left parenthesis in the input.
608*ccdc9c3eSSadaf Ebrahimi // Pushes a marker onto the stack.
DoLeftParen(const StringPiece & name)609*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::DoLeftParen(const StringPiece& name) {
610*ccdc9c3eSSadaf Ebrahimi   Regexp* re = new Regexp(kLeftParen, flags_);
611*ccdc9c3eSSadaf Ebrahimi   re->cap_ = ++ncap_;
612*ccdc9c3eSSadaf Ebrahimi   if (name.data() != NULL)
613*ccdc9c3eSSadaf Ebrahimi     re->name_ = new string(name);
614*ccdc9c3eSSadaf Ebrahimi   return PushRegexp(re);
615*ccdc9c3eSSadaf Ebrahimi }
616*ccdc9c3eSSadaf Ebrahimi 
617*ccdc9c3eSSadaf Ebrahimi // Pushes a non-capturing marker onto the stack.
DoLeftParenNoCapture()618*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::DoLeftParenNoCapture() {
619*ccdc9c3eSSadaf Ebrahimi   Regexp* re = new Regexp(kLeftParen, flags_);
620*ccdc9c3eSSadaf Ebrahimi   re->cap_ = -1;
621*ccdc9c3eSSadaf Ebrahimi   return PushRegexp(re);
622*ccdc9c3eSSadaf Ebrahimi }
623*ccdc9c3eSSadaf Ebrahimi 
624*ccdc9c3eSSadaf Ebrahimi // Processes a vertical bar in the input.
DoVerticalBar()625*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::DoVerticalBar() {
626*ccdc9c3eSSadaf Ebrahimi   MaybeConcatString(-1, NoParseFlags);
627*ccdc9c3eSSadaf Ebrahimi   DoConcatenation();
628*ccdc9c3eSSadaf Ebrahimi 
629*ccdc9c3eSSadaf Ebrahimi   // Below the vertical bar is a list to alternate.
630*ccdc9c3eSSadaf Ebrahimi   // Above the vertical bar is a list to concatenate.
631*ccdc9c3eSSadaf Ebrahimi   // We just did the concatenation, so either swap
632*ccdc9c3eSSadaf Ebrahimi   // the result below the vertical bar or push a new
633*ccdc9c3eSSadaf Ebrahimi   // vertical bar on the stack.
634*ccdc9c3eSSadaf Ebrahimi   Regexp* r1;
635*ccdc9c3eSSadaf Ebrahimi   Regexp* r2;
636*ccdc9c3eSSadaf Ebrahimi   if ((r1 = stacktop_) != NULL &&
637*ccdc9c3eSSadaf Ebrahimi       (r2 = r1->down_) != NULL &&
638*ccdc9c3eSSadaf Ebrahimi       r2->op() == kVerticalBar) {
639*ccdc9c3eSSadaf Ebrahimi     Regexp* r3;
640*ccdc9c3eSSadaf Ebrahimi     if ((r3 = r2->down_) != NULL &&
641*ccdc9c3eSSadaf Ebrahimi         (r1->op() == kRegexpAnyChar || r3->op() == kRegexpAnyChar)) {
642*ccdc9c3eSSadaf Ebrahimi       // AnyChar is above or below the vertical bar. Let it subsume
643*ccdc9c3eSSadaf Ebrahimi       // the other when the other is Literal, CharClass or AnyChar.
644*ccdc9c3eSSadaf Ebrahimi       if (r3->op() == kRegexpAnyChar &&
645*ccdc9c3eSSadaf Ebrahimi           (r1->op() == kRegexpLiteral ||
646*ccdc9c3eSSadaf Ebrahimi            r1->op() == kRegexpCharClass ||
647*ccdc9c3eSSadaf Ebrahimi            r1->op() == kRegexpAnyChar)) {
648*ccdc9c3eSSadaf Ebrahimi         // Discard r1.
649*ccdc9c3eSSadaf Ebrahimi         stacktop_ = r2;
650*ccdc9c3eSSadaf Ebrahimi         r1->Decref();
651*ccdc9c3eSSadaf Ebrahimi         return true;
652*ccdc9c3eSSadaf Ebrahimi       }
653*ccdc9c3eSSadaf Ebrahimi       if (r1->op() == kRegexpAnyChar &&
654*ccdc9c3eSSadaf Ebrahimi           (r3->op() == kRegexpLiteral ||
655*ccdc9c3eSSadaf Ebrahimi            r3->op() == kRegexpCharClass ||
656*ccdc9c3eSSadaf Ebrahimi            r3->op() == kRegexpAnyChar)) {
657*ccdc9c3eSSadaf Ebrahimi         // Rearrange the stack and discard r3.
658*ccdc9c3eSSadaf Ebrahimi         r1->down_ = r3->down_;
659*ccdc9c3eSSadaf Ebrahimi         r2->down_ = r1;
660*ccdc9c3eSSadaf Ebrahimi         stacktop_ = r2;
661*ccdc9c3eSSadaf Ebrahimi         r3->Decref();
662*ccdc9c3eSSadaf Ebrahimi         return true;
663*ccdc9c3eSSadaf Ebrahimi       }
664*ccdc9c3eSSadaf Ebrahimi     }
665*ccdc9c3eSSadaf Ebrahimi     // Swap r1 below vertical bar (r2).
666*ccdc9c3eSSadaf Ebrahimi     r1->down_ = r2->down_;
667*ccdc9c3eSSadaf Ebrahimi     r2->down_ = r1;
668*ccdc9c3eSSadaf Ebrahimi     stacktop_ = r2;
669*ccdc9c3eSSadaf Ebrahimi     return true;
670*ccdc9c3eSSadaf Ebrahimi   }
671*ccdc9c3eSSadaf Ebrahimi   return PushSimpleOp(kVerticalBar);
672*ccdc9c3eSSadaf Ebrahimi }
673*ccdc9c3eSSadaf Ebrahimi 
674*ccdc9c3eSSadaf Ebrahimi // Processes a right parenthesis in the input.
DoRightParen()675*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::DoRightParen() {
676*ccdc9c3eSSadaf Ebrahimi   // Finish the current concatenation and alternation.
677*ccdc9c3eSSadaf Ebrahimi   DoAlternation();
678*ccdc9c3eSSadaf Ebrahimi 
679*ccdc9c3eSSadaf Ebrahimi   // The stack should be: LeftParen regexp
680*ccdc9c3eSSadaf Ebrahimi   // Remove the LeftParen, leaving the regexp,
681*ccdc9c3eSSadaf Ebrahimi   // parenthesized.
682*ccdc9c3eSSadaf Ebrahimi   Regexp* r1;
683*ccdc9c3eSSadaf Ebrahimi   Regexp* r2;
684*ccdc9c3eSSadaf Ebrahimi   if ((r1 = stacktop_) == NULL ||
685*ccdc9c3eSSadaf Ebrahimi       (r2 = r1->down_) == NULL ||
686*ccdc9c3eSSadaf Ebrahimi       r2->op() != kLeftParen) {
687*ccdc9c3eSSadaf Ebrahimi     status_->set_code(kRegexpMissingParen);
688*ccdc9c3eSSadaf Ebrahimi     status_->set_error_arg(whole_regexp_);
689*ccdc9c3eSSadaf Ebrahimi     return false;
690*ccdc9c3eSSadaf Ebrahimi   }
691*ccdc9c3eSSadaf Ebrahimi 
692*ccdc9c3eSSadaf Ebrahimi   // Pop off r1, r2.  Will Decref or reuse below.
693*ccdc9c3eSSadaf Ebrahimi   stacktop_ = r2->down_;
694*ccdc9c3eSSadaf Ebrahimi 
695*ccdc9c3eSSadaf Ebrahimi   // Restore flags from when paren opened.
696*ccdc9c3eSSadaf Ebrahimi   Regexp* re = r2;
697*ccdc9c3eSSadaf Ebrahimi   flags_ = re->parse_flags();
698*ccdc9c3eSSadaf Ebrahimi 
699*ccdc9c3eSSadaf Ebrahimi   // Rewrite LeftParen as capture if needed.
700*ccdc9c3eSSadaf Ebrahimi   if (re->cap_ > 0) {
701*ccdc9c3eSSadaf Ebrahimi     re->op_ = kRegexpCapture;
702*ccdc9c3eSSadaf Ebrahimi     // re->cap_ is already set
703*ccdc9c3eSSadaf Ebrahimi     re->AllocSub(1);
704*ccdc9c3eSSadaf Ebrahimi     re->sub()[0] = FinishRegexp(r1);
705*ccdc9c3eSSadaf Ebrahimi     re->simple_ = re->ComputeSimple();
706*ccdc9c3eSSadaf Ebrahimi   } else {
707*ccdc9c3eSSadaf Ebrahimi     re->Decref();
708*ccdc9c3eSSadaf Ebrahimi     re = r1;
709*ccdc9c3eSSadaf Ebrahimi   }
710*ccdc9c3eSSadaf Ebrahimi   return PushRegexp(re);
711*ccdc9c3eSSadaf Ebrahimi }
712*ccdc9c3eSSadaf Ebrahimi 
713*ccdc9c3eSSadaf Ebrahimi // Processes the end of input, returning the final regexp.
DoFinish()714*ccdc9c3eSSadaf Ebrahimi Regexp* Regexp::ParseState::DoFinish() {
715*ccdc9c3eSSadaf Ebrahimi   DoAlternation();
716*ccdc9c3eSSadaf Ebrahimi   Regexp* re = stacktop_;
717*ccdc9c3eSSadaf Ebrahimi   if (re != NULL && re->down_ != NULL) {
718*ccdc9c3eSSadaf Ebrahimi     status_->set_code(kRegexpMissingParen);
719*ccdc9c3eSSadaf Ebrahimi     status_->set_error_arg(whole_regexp_);
720*ccdc9c3eSSadaf Ebrahimi     return NULL;
721*ccdc9c3eSSadaf Ebrahimi   }
722*ccdc9c3eSSadaf Ebrahimi   stacktop_ = NULL;
723*ccdc9c3eSSadaf Ebrahimi   return FinishRegexp(re);
724*ccdc9c3eSSadaf Ebrahimi }
725*ccdc9c3eSSadaf Ebrahimi 
726*ccdc9c3eSSadaf Ebrahimi // Returns the leading regexp that re starts with.
727*ccdc9c3eSSadaf Ebrahimi // The returned Regexp* points into a piece of re,
728*ccdc9c3eSSadaf Ebrahimi // so it must not be used after the caller calls re->Decref().
LeadingRegexp(Regexp * re)729*ccdc9c3eSSadaf Ebrahimi Regexp* Regexp::LeadingRegexp(Regexp* re) {
730*ccdc9c3eSSadaf Ebrahimi   if (re->op() == kRegexpEmptyMatch)
731*ccdc9c3eSSadaf Ebrahimi     return NULL;
732*ccdc9c3eSSadaf Ebrahimi   if (re->op() == kRegexpConcat && re->nsub() >= 2) {
733*ccdc9c3eSSadaf Ebrahimi     Regexp** sub = re->sub();
734*ccdc9c3eSSadaf Ebrahimi     if (sub[0]->op() == kRegexpEmptyMatch)
735*ccdc9c3eSSadaf Ebrahimi       return NULL;
736*ccdc9c3eSSadaf Ebrahimi     return sub[0];
737*ccdc9c3eSSadaf Ebrahimi   }
738*ccdc9c3eSSadaf Ebrahimi   return re;
739*ccdc9c3eSSadaf Ebrahimi }
740*ccdc9c3eSSadaf Ebrahimi 
741*ccdc9c3eSSadaf Ebrahimi // Removes LeadingRegexp(re) from re and returns what's left.
742*ccdc9c3eSSadaf Ebrahimi // Consumes the reference to re and may edit it in place.
743*ccdc9c3eSSadaf Ebrahimi // If caller wants to hold on to LeadingRegexp(re),
744*ccdc9c3eSSadaf Ebrahimi // must have already Incref'ed it.
RemoveLeadingRegexp(Regexp * re)745*ccdc9c3eSSadaf Ebrahimi Regexp* Regexp::RemoveLeadingRegexp(Regexp* re) {
746*ccdc9c3eSSadaf Ebrahimi   if (re->op() == kRegexpEmptyMatch)
747*ccdc9c3eSSadaf Ebrahimi     return re;
748*ccdc9c3eSSadaf Ebrahimi   if (re->op() == kRegexpConcat && re->nsub() >= 2) {
749*ccdc9c3eSSadaf Ebrahimi     Regexp** sub = re->sub();
750*ccdc9c3eSSadaf Ebrahimi     if (sub[0]->op() == kRegexpEmptyMatch)
751*ccdc9c3eSSadaf Ebrahimi       return re;
752*ccdc9c3eSSadaf Ebrahimi     sub[0]->Decref();
753*ccdc9c3eSSadaf Ebrahimi     sub[0] = NULL;
754*ccdc9c3eSSadaf Ebrahimi     if (re->nsub() == 2) {
755*ccdc9c3eSSadaf Ebrahimi       // Collapse concatenation to single regexp.
756*ccdc9c3eSSadaf Ebrahimi       Regexp* nre = sub[1];
757*ccdc9c3eSSadaf Ebrahimi       sub[1] = NULL;
758*ccdc9c3eSSadaf Ebrahimi       re->Decref();
759*ccdc9c3eSSadaf Ebrahimi       return nre;
760*ccdc9c3eSSadaf Ebrahimi     }
761*ccdc9c3eSSadaf Ebrahimi     // 3 or more -> 2 or more.
762*ccdc9c3eSSadaf Ebrahimi     re->nsub_--;
763*ccdc9c3eSSadaf Ebrahimi     memmove(sub, sub + 1, re->nsub_ * sizeof sub[0]);
764*ccdc9c3eSSadaf Ebrahimi     return re;
765*ccdc9c3eSSadaf Ebrahimi   }
766*ccdc9c3eSSadaf Ebrahimi   Regexp::ParseFlags pf = re->parse_flags();
767*ccdc9c3eSSadaf Ebrahimi   re->Decref();
768*ccdc9c3eSSadaf Ebrahimi   return new Regexp(kRegexpEmptyMatch, pf);
769*ccdc9c3eSSadaf Ebrahimi }
770*ccdc9c3eSSadaf Ebrahimi 
771*ccdc9c3eSSadaf Ebrahimi // Returns the leading string that re starts with.
772*ccdc9c3eSSadaf Ebrahimi // The returned Rune* points into a piece of re,
773*ccdc9c3eSSadaf Ebrahimi // so it must not be used after the caller calls re->Decref().
LeadingString(Regexp * re,int * nrune,Regexp::ParseFlags * flags)774*ccdc9c3eSSadaf Ebrahimi Rune* Regexp::LeadingString(Regexp* re, int *nrune,
775*ccdc9c3eSSadaf Ebrahimi                             Regexp::ParseFlags *flags) {
776*ccdc9c3eSSadaf Ebrahimi   while (re->op() == kRegexpConcat && re->nsub() > 0)
777*ccdc9c3eSSadaf Ebrahimi     re = re->sub()[0];
778*ccdc9c3eSSadaf Ebrahimi 
779*ccdc9c3eSSadaf Ebrahimi   *flags = static_cast<Regexp::ParseFlags>(re->parse_flags_ & Regexp::FoldCase);
780*ccdc9c3eSSadaf Ebrahimi 
781*ccdc9c3eSSadaf Ebrahimi   if (re->op() == kRegexpLiteral) {
782*ccdc9c3eSSadaf Ebrahimi     *nrune = 1;
783*ccdc9c3eSSadaf Ebrahimi     return &re->rune_;
784*ccdc9c3eSSadaf Ebrahimi   }
785*ccdc9c3eSSadaf Ebrahimi 
786*ccdc9c3eSSadaf Ebrahimi   if (re->op() == kRegexpLiteralString) {
787*ccdc9c3eSSadaf Ebrahimi     *nrune = re->nrunes_;
788*ccdc9c3eSSadaf Ebrahimi     return re->runes_;
789*ccdc9c3eSSadaf Ebrahimi   }
790*ccdc9c3eSSadaf Ebrahimi 
791*ccdc9c3eSSadaf Ebrahimi   *nrune = 0;
792*ccdc9c3eSSadaf Ebrahimi   return NULL;
793*ccdc9c3eSSadaf Ebrahimi }
794*ccdc9c3eSSadaf Ebrahimi 
795*ccdc9c3eSSadaf Ebrahimi // Removes the first n leading runes from the beginning of re.
796*ccdc9c3eSSadaf Ebrahimi // Edits re in place.
RemoveLeadingString(Regexp * re,int n)797*ccdc9c3eSSadaf Ebrahimi void Regexp::RemoveLeadingString(Regexp* re, int n) {
798*ccdc9c3eSSadaf Ebrahimi   // Chase down concats to find first string.
799*ccdc9c3eSSadaf Ebrahimi   // For regexps generated by parser, nested concats are
800*ccdc9c3eSSadaf Ebrahimi   // flattened except when doing so would overflow the 16-bit
801*ccdc9c3eSSadaf Ebrahimi   // limit on the size of a concatenation, so we should never
802*ccdc9c3eSSadaf Ebrahimi   // see more than two here.
803*ccdc9c3eSSadaf Ebrahimi   Regexp* stk[4];
804*ccdc9c3eSSadaf Ebrahimi   int d = 0;
805*ccdc9c3eSSadaf Ebrahimi   while (re->op() == kRegexpConcat) {
806*ccdc9c3eSSadaf Ebrahimi     if (d < arraysize(stk))
807*ccdc9c3eSSadaf Ebrahimi       stk[d++] = re;
808*ccdc9c3eSSadaf Ebrahimi     re = re->sub()[0];
809*ccdc9c3eSSadaf Ebrahimi   }
810*ccdc9c3eSSadaf Ebrahimi 
811*ccdc9c3eSSadaf Ebrahimi   // Remove leading string from re.
812*ccdc9c3eSSadaf Ebrahimi   if (re->op() == kRegexpLiteral) {
813*ccdc9c3eSSadaf Ebrahimi     re->rune_ = 0;
814*ccdc9c3eSSadaf Ebrahimi     re->op_ = kRegexpEmptyMatch;
815*ccdc9c3eSSadaf Ebrahimi   } else if (re->op() == kRegexpLiteralString) {
816*ccdc9c3eSSadaf Ebrahimi     if (n >= re->nrunes_) {
817*ccdc9c3eSSadaf Ebrahimi       delete[] re->runes_;
818*ccdc9c3eSSadaf Ebrahimi       re->runes_ = NULL;
819*ccdc9c3eSSadaf Ebrahimi       re->nrunes_ = 0;
820*ccdc9c3eSSadaf Ebrahimi       re->op_ = kRegexpEmptyMatch;
821*ccdc9c3eSSadaf Ebrahimi     } else if (n == re->nrunes_ - 1) {
822*ccdc9c3eSSadaf Ebrahimi       Rune rune = re->runes_[re->nrunes_ - 1];
823*ccdc9c3eSSadaf Ebrahimi       delete[] re->runes_;
824*ccdc9c3eSSadaf Ebrahimi       re->runes_ = NULL;
825*ccdc9c3eSSadaf Ebrahimi       re->nrunes_ = 0;
826*ccdc9c3eSSadaf Ebrahimi       re->rune_ = rune;
827*ccdc9c3eSSadaf Ebrahimi       re->op_ = kRegexpLiteral;
828*ccdc9c3eSSadaf Ebrahimi     } else {
829*ccdc9c3eSSadaf Ebrahimi       re->nrunes_ -= n;
830*ccdc9c3eSSadaf Ebrahimi       memmove(re->runes_, re->runes_ + n, re->nrunes_ * sizeof re->runes_[0]);
831*ccdc9c3eSSadaf Ebrahimi     }
832*ccdc9c3eSSadaf Ebrahimi   }
833*ccdc9c3eSSadaf Ebrahimi 
834*ccdc9c3eSSadaf Ebrahimi   // If re is now empty, concatenations might simplify too.
835*ccdc9c3eSSadaf Ebrahimi   while (d-- > 0) {
836*ccdc9c3eSSadaf Ebrahimi     re = stk[d];
837*ccdc9c3eSSadaf Ebrahimi     Regexp** sub = re->sub();
838*ccdc9c3eSSadaf Ebrahimi     if (sub[0]->op() == kRegexpEmptyMatch) {
839*ccdc9c3eSSadaf Ebrahimi       sub[0]->Decref();
840*ccdc9c3eSSadaf Ebrahimi       sub[0] = NULL;
841*ccdc9c3eSSadaf Ebrahimi       // Delete first element of concat.
842*ccdc9c3eSSadaf Ebrahimi       switch (re->nsub()) {
843*ccdc9c3eSSadaf Ebrahimi         case 0:
844*ccdc9c3eSSadaf Ebrahimi         case 1:
845*ccdc9c3eSSadaf Ebrahimi           // Impossible.
846*ccdc9c3eSSadaf Ebrahimi           LOG(DFATAL) << "Concat of " << re->nsub();
847*ccdc9c3eSSadaf Ebrahimi           re->submany_ = NULL;
848*ccdc9c3eSSadaf Ebrahimi           re->op_ = kRegexpEmptyMatch;
849*ccdc9c3eSSadaf Ebrahimi           break;
850*ccdc9c3eSSadaf Ebrahimi 
851*ccdc9c3eSSadaf Ebrahimi         case 2: {
852*ccdc9c3eSSadaf Ebrahimi           // Replace re with sub[1].
853*ccdc9c3eSSadaf Ebrahimi           Regexp* old = sub[1];
854*ccdc9c3eSSadaf Ebrahimi           sub[1] = NULL;
855*ccdc9c3eSSadaf Ebrahimi           re->Swap(old);
856*ccdc9c3eSSadaf Ebrahimi           old->Decref();
857*ccdc9c3eSSadaf Ebrahimi           break;
858*ccdc9c3eSSadaf Ebrahimi         }
859*ccdc9c3eSSadaf Ebrahimi 
860*ccdc9c3eSSadaf Ebrahimi         default:
861*ccdc9c3eSSadaf Ebrahimi           // Slide down.
862*ccdc9c3eSSadaf Ebrahimi           re->nsub_--;
863*ccdc9c3eSSadaf Ebrahimi           memmove(sub, sub + 1, re->nsub_ * sizeof sub[0]);
864*ccdc9c3eSSadaf Ebrahimi           break;
865*ccdc9c3eSSadaf Ebrahimi       }
866*ccdc9c3eSSadaf Ebrahimi     }
867*ccdc9c3eSSadaf Ebrahimi   }
868*ccdc9c3eSSadaf Ebrahimi }
869*ccdc9c3eSSadaf Ebrahimi 
870*ccdc9c3eSSadaf Ebrahimi // In the context of factoring alternations, a Splice is: a factored prefix or
871*ccdc9c3eSSadaf Ebrahimi // merged character class computed by one iteration of one round of factoring;
872*ccdc9c3eSSadaf Ebrahimi // the span of subexpressions of the alternation to be "spliced" (i.e. removed
873*ccdc9c3eSSadaf Ebrahimi // and replaced); and, for a factored prefix, the number of suffixes after any
874*ccdc9c3eSSadaf Ebrahimi // factoring that might have subsequently been performed on them. For a merged
875*ccdc9c3eSSadaf Ebrahimi // character class, there are no suffixes, of course, so the field is ignored.
876*ccdc9c3eSSadaf Ebrahimi struct Splice {
Splicere2::Splice877*ccdc9c3eSSadaf Ebrahimi   Splice(Regexp* prefix, Regexp** sub, int nsub)
878*ccdc9c3eSSadaf Ebrahimi       : prefix(prefix),
879*ccdc9c3eSSadaf Ebrahimi         sub(sub),
880*ccdc9c3eSSadaf Ebrahimi         nsub(nsub),
881*ccdc9c3eSSadaf Ebrahimi         nsuffix(-1) {}
882*ccdc9c3eSSadaf Ebrahimi 
883*ccdc9c3eSSadaf Ebrahimi   Regexp* prefix;
884*ccdc9c3eSSadaf Ebrahimi   Regexp** sub;
885*ccdc9c3eSSadaf Ebrahimi   int nsub;
886*ccdc9c3eSSadaf Ebrahimi   int nsuffix;
887*ccdc9c3eSSadaf Ebrahimi };
888*ccdc9c3eSSadaf Ebrahimi 
889*ccdc9c3eSSadaf Ebrahimi // Named so because it is used to implement an explicit stack, a Frame is: the
890*ccdc9c3eSSadaf Ebrahimi // span of subexpressions of the alternation to be factored; the current round
891*ccdc9c3eSSadaf Ebrahimi // of factoring; any Splices computed; and, for a factored prefix, an iterator
892*ccdc9c3eSSadaf Ebrahimi // to the next Splice to be factored (i.e. in another Frame) because suffixes.
893*ccdc9c3eSSadaf Ebrahimi struct Frame {
Framere2::Frame894*ccdc9c3eSSadaf Ebrahimi   Frame(Regexp** sub, int nsub)
895*ccdc9c3eSSadaf Ebrahimi       : sub(sub),
896*ccdc9c3eSSadaf Ebrahimi         nsub(nsub),
897*ccdc9c3eSSadaf Ebrahimi         round(0) {}
898*ccdc9c3eSSadaf Ebrahimi 
899*ccdc9c3eSSadaf Ebrahimi   Regexp** sub;
900*ccdc9c3eSSadaf Ebrahimi   int nsub;
901*ccdc9c3eSSadaf Ebrahimi   int round;
902*ccdc9c3eSSadaf Ebrahimi   std::vector<Splice> splices;
903*ccdc9c3eSSadaf Ebrahimi   int spliceidx;
904*ccdc9c3eSSadaf Ebrahimi };
905*ccdc9c3eSSadaf Ebrahimi 
906*ccdc9c3eSSadaf Ebrahimi // Bundled into a class for friend access to Regexp without needing to declare
907*ccdc9c3eSSadaf Ebrahimi // (or define) Splice in regexp.h.
908*ccdc9c3eSSadaf Ebrahimi class FactorAlternationImpl {
909*ccdc9c3eSSadaf Ebrahimi  public:
910*ccdc9c3eSSadaf Ebrahimi   static void Round1(Regexp** sub, int nsub,
911*ccdc9c3eSSadaf Ebrahimi                      Regexp::ParseFlags flags,
912*ccdc9c3eSSadaf Ebrahimi                      std::vector<Splice>* splices);
913*ccdc9c3eSSadaf Ebrahimi   static void Round2(Regexp** sub, int nsub,
914*ccdc9c3eSSadaf Ebrahimi                      Regexp::ParseFlags flags,
915*ccdc9c3eSSadaf Ebrahimi                      std::vector<Splice>* splices);
916*ccdc9c3eSSadaf Ebrahimi   static void Round3(Regexp** sub, int nsub,
917*ccdc9c3eSSadaf Ebrahimi                      Regexp::ParseFlags flags,
918*ccdc9c3eSSadaf Ebrahimi                      std::vector<Splice>* splices);
919*ccdc9c3eSSadaf Ebrahimi };
920*ccdc9c3eSSadaf Ebrahimi 
921*ccdc9c3eSSadaf Ebrahimi // Factors common prefixes from alternation.
922*ccdc9c3eSSadaf Ebrahimi // For example,
923*ccdc9c3eSSadaf Ebrahimi //     ABC|ABD|AEF|BCX|BCY
924*ccdc9c3eSSadaf Ebrahimi // simplifies to
925*ccdc9c3eSSadaf Ebrahimi //     A(B(C|D)|EF)|BC(X|Y)
926*ccdc9c3eSSadaf Ebrahimi // and thence to
927*ccdc9c3eSSadaf Ebrahimi //     A(B[CD]|EF)|BC[XY]
928*ccdc9c3eSSadaf Ebrahimi //
929*ccdc9c3eSSadaf Ebrahimi // Rewrites sub to contain simplified list to alternate and returns
930*ccdc9c3eSSadaf Ebrahimi // the new length of sub.  Adjusts reference counts accordingly
931*ccdc9c3eSSadaf Ebrahimi // (incoming sub[i] decremented, outgoing sub[i] incremented).
FactorAlternation(Regexp ** sub,int nsub,ParseFlags flags)932*ccdc9c3eSSadaf Ebrahimi int Regexp::FactorAlternation(Regexp** sub, int nsub, ParseFlags flags) {
933*ccdc9c3eSSadaf Ebrahimi   std::vector<Frame> stk;
934*ccdc9c3eSSadaf Ebrahimi   stk.emplace_back(sub, nsub);
935*ccdc9c3eSSadaf Ebrahimi 
936*ccdc9c3eSSadaf Ebrahimi   for (;;) {
937*ccdc9c3eSSadaf Ebrahimi     auto& sub = stk.back().sub;
938*ccdc9c3eSSadaf Ebrahimi     auto& nsub = stk.back().nsub;
939*ccdc9c3eSSadaf Ebrahimi     auto& round = stk.back().round;
940*ccdc9c3eSSadaf Ebrahimi     auto& splices = stk.back().splices;
941*ccdc9c3eSSadaf Ebrahimi     auto& spliceidx = stk.back().spliceidx;
942*ccdc9c3eSSadaf Ebrahimi 
943*ccdc9c3eSSadaf Ebrahimi     if (splices.empty()) {
944*ccdc9c3eSSadaf Ebrahimi       // Advance to the next round of factoring. Note that this covers
945*ccdc9c3eSSadaf Ebrahimi       // the initialised state: when splices is empty and round is 0.
946*ccdc9c3eSSadaf Ebrahimi       round++;
947*ccdc9c3eSSadaf Ebrahimi     } else if (spliceidx < static_cast<int>(splices.size())) {
948*ccdc9c3eSSadaf Ebrahimi       // We have at least one more Splice to factor. Recurse logically.
949*ccdc9c3eSSadaf Ebrahimi       stk.emplace_back(splices[spliceidx].sub, splices[spliceidx].nsub);
950*ccdc9c3eSSadaf Ebrahimi       continue;
951*ccdc9c3eSSadaf Ebrahimi     } else {
952*ccdc9c3eSSadaf Ebrahimi       // We have no more Splices to factor. Apply them.
953*ccdc9c3eSSadaf Ebrahimi       auto iter = splices.begin();
954*ccdc9c3eSSadaf Ebrahimi       int out = 0;
955*ccdc9c3eSSadaf Ebrahimi       for (int i = 0; i < nsub; ) {
956*ccdc9c3eSSadaf Ebrahimi         // Copy until we reach where the next Splice begins.
957*ccdc9c3eSSadaf Ebrahimi         while (sub + i < iter->sub)
958*ccdc9c3eSSadaf Ebrahimi           sub[out++] = sub[i++];
959*ccdc9c3eSSadaf Ebrahimi         switch (round) {
960*ccdc9c3eSSadaf Ebrahimi           case 1:
961*ccdc9c3eSSadaf Ebrahimi           case 2: {
962*ccdc9c3eSSadaf Ebrahimi             // Assemble the Splice prefix and the suffixes.
963*ccdc9c3eSSadaf Ebrahimi             Regexp* re[2];
964*ccdc9c3eSSadaf Ebrahimi             re[0] = iter->prefix;
965*ccdc9c3eSSadaf Ebrahimi             re[1] = Regexp::AlternateNoFactor(iter->sub, iter->nsuffix, flags);
966*ccdc9c3eSSadaf Ebrahimi             sub[out++] = Regexp::Concat(re, 2, flags);
967*ccdc9c3eSSadaf Ebrahimi             i += iter->nsub;
968*ccdc9c3eSSadaf Ebrahimi             break;
969*ccdc9c3eSSadaf Ebrahimi           }
970*ccdc9c3eSSadaf Ebrahimi           case 3:
971*ccdc9c3eSSadaf Ebrahimi             // Just use the Splice prefix.
972*ccdc9c3eSSadaf Ebrahimi             sub[out++] = iter->prefix;
973*ccdc9c3eSSadaf Ebrahimi             i += iter->nsub;
974*ccdc9c3eSSadaf Ebrahimi             break;
975*ccdc9c3eSSadaf Ebrahimi           default:
976*ccdc9c3eSSadaf Ebrahimi             LOG(DFATAL) << "unknown round: " << round;
977*ccdc9c3eSSadaf Ebrahimi             break;
978*ccdc9c3eSSadaf Ebrahimi         }
979*ccdc9c3eSSadaf Ebrahimi         // If we are done, copy until the end of sub.
980*ccdc9c3eSSadaf Ebrahimi         if (++iter == splices.end()) {
981*ccdc9c3eSSadaf Ebrahimi           while (i < nsub)
982*ccdc9c3eSSadaf Ebrahimi             sub[out++] = sub[i++];
983*ccdc9c3eSSadaf Ebrahimi         }
984*ccdc9c3eSSadaf Ebrahimi       }
985*ccdc9c3eSSadaf Ebrahimi       splices.clear();
986*ccdc9c3eSSadaf Ebrahimi       nsub = out;
987*ccdc9c3eSSadaf Ebrahimi       // Advance to the next round of factoring.
988*ccdc9c3eSSadaf Ebrahimi       round++;
989*ccdc9c3eSSadaf Ebrahimi     }
990*ccdc9c3eSSadaf Ebrahimi 
991*ccdc9c3eSSadaf Ebrahimi     switch (round) {
992*ccdc9c3eSSadaf Ebrahimi       case 1:
993*ccdc9c3eSSadaf Ebrahimi         FactorAlternationImpl::Round1(sub, nsub, flags, &splices);
994*ccdc9c3eSSadaf Ebrahimi         break;
995*ccdc9c3eSSadaf Ebrahimi       case 2:
996*ccdc9c3eSSadaf Ebrahimi         FactorAlternationImpl::Round2(sub, nsub, flags, &splices);
997*ccdc9c3eSSadaf Ebrahimi         break;
998*ccdc9c3eSSadaf Ebrahimi       case 3:
999*ccdc9c3eSSadaf Ebrahimi         FactorAlternationImpl::Round3(sub, nsub, flags, &splices);
1000*ccdc9c3eSSadaf Ebrahimi         break;
1001*ccdc9c3eSSadaf Ebrahimi       case 4:
1002*ccdc9c3eSSadaf Ebrahimi         if (stk.size() == 1) {
1003*ccdc9c3eSSadaf Ebrahimi           // We are at the top of the stack. Just return.
1004*ccdc9c3eSSadaf Ebrahimi           return nsub;
1005*ccdc9c3eSSadaf Ebrahimi         } else {
1006*ccdc9c3eSSadaf Ebrahimi           // Pop the stack and set the number of suffixes.
1007*ccdc9c3eSSadaf Ebrahimi           // (Note that references will be invalidated!)
1008*ccdc9c3eSSadaf Ebrahimi           int nsuffix = nsub;
1009*ccdc9c3eSSadaf Ebrahimi           stk.pop_back();
1010*ccdc9c3eSSadaf Ebrahimi           stk.back().splices[stk.back().spliceidx].nsuffix = nsuffix;
1011*ccdc9c3eSSadaf Ebrahimi           ++stk.back().spliceidx;
1012*ccdc9c3eSSadaf Ebrahimi           continue;
1013*ccdc9c3eSSadaf Ebrahimi         }
1014*ccdc9c3eSSadaf Ebrahimi       default:
1015*ccdc9c3eSSadaf Ebrahimi         LOG(DFATAL) << "unknown round: " << round;
1016*ccdc9c3eSSadaf Ebrahimi         break;
1017*ccdc9c3eSSadaf Ebrahimi     }
1018*ccdc9c3eSSadaf Ebrahimi 
1019*ccdc9c3eSSadaf Ebrahimi     // Set spliceidx depending on whether we have Splices to factor.
1020*ccdc9c3eSSadaf Ebrahimi     if (splices.empty() || round == 3) {
1021*ccdc9c3eSSadaf Ebrahimi       spliceidx = static_cast<int>(splices.size());
1022*ccdc9c3eSSadaf Ebrahimi     } else {
1023*ccdc9c3eSSadaf Ebrahimi       spliceidx = 0;
1024*ccdc9c3eSSadaf Ebrahimi     }
1025*ccdc9c3eSSadaf Ebrahimi   }
1026*ccdc9c3eSSadaf Ebrahimi }
1027*ccdc9c3eSSadaf Ebrahimi 
Round1(Regexp ** sub,int nsub,Regexp::ParseFlags flags,std::vector<Splice> * splices)1028*ccdc9c3eSSadaf Ebrahimi void FactorAlternationImpl::Round1(Regexp** sub, int nsub,
1029*ccdc9c3eSSadaf Ebrahimi                                    Regexp::ParseFlags flags,
1030*ccdc9c3eSSadaf Ebrahimi                                    std::vector<Splice>* splices) {
1031*ccdc9c3eSSadaf Ebrahimi   // Round 1: Factor out common literal prefixes.
1032*ccdc9c3eSSadaf Ebrahimi   int start = 0;
1033*ccdc9c3eSSadaf Ebrahimi   Rune* rune = NULL;
1034*ccdc9c3eSSadaf Ebrahimi   int nrune = 0;
1035*ccdc9c3eSSadaf Ebrahimi   Regexp::ParseFlags runeflags = Regexp::NoParseFlags;
1036*ccdc9c3eSSadaf Ebrahimi   for (int i = 0; i <= nsub; i++) {
1037*ccdc9c3eSSadaf Ebrahimi     // Invariant: sub[start:i] consists of regexps that all
1038*ccdc9c3eSSadaf Ebrahimi     // begin with rune[0:nrune].
1039*ccdc9c3eSSadaf Ebrahimi     Rune* rune_i = NULL;
1040*ccdc9c3eSSadaf Ebrahimi     int nrune_i = 0;
1041*ccdc9c3eSSadaf Ebrahimi     Regexp::ParseFlags runeflags_i = Regexp::NoParseFlags;
1042*ccdc9c3eSSadaf Ebrahimi     if (i < nsub) {
1043*ccdc9c3eSSadaf Ebrahimi       rune_i = Regexp::LeadingString(sub[i], &nrune_i, &runeflags_i);
1044*ccdc9c3eSSadaf Ebrahimi       if (runeflags_i == runeflags) {
1045*ccdc9c3eSSadaf Ebrahimi         int same = 0;
1046*ccdc9c3eSSadaf Ebrahimi         while (same < nrune && same < nrune_i && rune[same] == rune_i[same])
1047*ccdc9c3eSSadaf Ebrahimi           same++;
1048*ccdc9c3eSSadaf Ebrahimi         if (same > 0) {
1049*ccdc9c3eSSadaf Ebrahimi           // Matches at least one rune in current range.  Keep going around.
1050*ccdc9c3eSSadaf Ebrahimi           nrune = same;
1051*ccdc9c3eSSadaf Ebrahimi           continue;
1052*ccdc9c3eSSadaf Ebrahimi         }
1053*ccdc9c3eSSadaf Ebrahimi       }
1054*ccdc9c3eSSadaf Ebrahimi     }
1055*ccdc9c3eSSadaf Ebrahimi 
1056*ccdc9c3eSSadaf Ebrahimi     // Found end of a run with common leading literal string:
1057*ccdc9c3eSSadaf Ebrahimi     // sub[start:i] all begin with rune[0:nrune],
1058*ccdc9c3eSSadaf Ebrahimi     // but sub[i] does not even begin with rune[0].
1059*ccdc9c3eSSadaf Ebrahimi     if (i == start) {
1060*ccdc9c3eSSadaf Ebrahimi       // Nothing to do - first iteration.
1061*ccdc9c3eSSadaf Ebrahimi     } else if (i == start+1) {
1062*ccdc9c3eSSadaf Ebrahimi       // Just one: don't bother factoring.
1063*ccdc9c3eSSadaf Ebrahimi     } else {
1064*ccdc9c3eSSadaf Ebrahimi       Regexp* prefix = Regexp::LiteralString(rune, nrune, runeflags);
1065*ccdc9c3eSSadaf Ebrahimi       for (int j = start; j < i; j++)
1066*ccdc9c3eSSadaf Ebrahimi         Regexp::RemoveLeadingString(sub[j], nrune);
1067*ccdc9c3eSSadaf Ebrahimi       splices->emplace_back(prefix, sub + start, i - start);
1068*ccdc9c3eSSadaf Ebrahimi     }
1069*ccdc9c3eSSadaf Ebrahimi 
1070*ccdc9c3eSSadaf Ebrahimi     // Prepare for next iteration (if there is one).
1071*ccdc9c3eSSadaf Ebrahimi     if (i < nsub) {
1072*ccdc9c3eSSadaf Ebrahimi       start = i;
1073*ccdc9c3eSSadaf Ebrahimi       rune = rune_i;
1074*ccdc9c3eSSadaf Ebrahimi       nrune = nrune_i;
1075*ccdc9c3eSSadaf Ebrahimi       runeflags = runeflags_i;
1076*ccdc9c3eSSadaf Ebrahimi     }
1077*ccdc9c3eSSadaf Ebrahimi   }
1078*ccdc9c3eSSadaf Ebrahimi }
1079*ccdc9c3eSSadaf Ebrahimi 
Round2(Regexp ** sub,int nsub,Regexp::ParseFlags flags,std::vector<Splice> * splices)1080*ccdc9c3eSSadaf Ebrahimi void FactorAlternationImpl::Round2(Regexp** sub, int nsub,
1081*ccdc9c3eSSadaf Ebrahimi                                    Regexp::ParseFlags flags,
1082*ccdc9c3eSSadaf Ebrahimi                                    std::vector<Splice>* splices) {
1083*ccdc9c3eSSadaf Ebrahimi   // Round 2: Factor out common simple prefixes,
1084*ccdc9c3eSSadaf Ebrahimi   // just the first piece of each concatenation.
1085*ccdc9c3eSSadaf Ebrahimi   // This will be good enough a lot of the time.
1086*ccdc9c3eSSadaf Ebrahimi   //
1087*ccdc9c3eSSadaf Ebrahimi   // Complex subexpressions (e.g. involving quantifiers)
1088*ccdc9c3eSSadaf Ebrahimi   // are not safe to factor because that collapses their
1089*ccdc9c3eSSadaf Ebrahimi   // distinct paths through the automaton, which affects
1090*ccdc9c3eSSadaf Ebrahimi   // correctness in some cases.
1091*ccdc9c3eSSadaf Ebrahimi   int start = 0;
1092*ccdc9c3eSSadaf Ebrahimi   Regexp* first = NULL;
1093*ccdc9c3eSSadaf Ebrahimi   for (int i = 0; i <= nsub; i++) {
1094*ccdc9c3eSSadaf Ebrahimi     // Invariant: sub[start:i] consists of regexps that all
1095*ccdc9c3eSSadaf Ebrahimi     // begin with first.
1096*ccdc9c3eSSadaf Ebrahimi     Regexp* first_i = NULL;
1097*ccdc9c3eSSadaf Ebrahimi     if (i < nsub) {
1098*ccdc9c3eSSadaf Ebrahimi       first_i = Regexp::LeadingRegexp(sub[i]);
1099*ccdc9c3eSSadaf Ebrahimi       if (first != NULL &&
1100*ccdc9c3eSSadaf Ebrahimi           // first must be an empty-width op
1101*ccdc9c3eSSadaf Ebrahimi           // OR a char class, any char or any byte
1102*ccdc9c3eSSadaf Ebrahimi           // OR a fixed repeat of a literal, char class, any char or any byte.
1103*ccdc9c3eSSadaf Ebrahimi           (first->op() == kRegexpBeginLine ||
1104*ccdc9c3eSSadaf Ebrahimi            first->op() == kRegexpEndLine ||
1105*ccdc9c3eSSadaf Ebrahimi            first->op() == kRegexpWordBoundary ||
1106*ccdc9c3eSSadaf Ebrahimi            first->op() == kRegexpNoWordBoundary ||
1107*ccdc9c3eSSadaf Ebrahimi            first->op() == kRegexpBeginText ||
1108*ccdc9c3eSSadaf Ebrahimi            first->op() == kRegexpEndText ||
1109*ccdc9c3eSSadaf Ebrahimi            first->op() == kRegexpCharClass ||
1110*ccdc9c3eSSadaf Ebrahimi            first->op() == kRegexpAnyChar ||
1111*ccdc9c3eSSadaf Ebrahimi            first->op() == kRegexpAnyByte ||
1112*ccdc9c3eSSadaf Ebrahimi            (first->op() == kRegexpRepeat &&
1113*ccdc9c3eSSadaf Ebrahimi             first->min() == first->max() &&
1114*ccdc9c3eSSadaf Ebrahimi             (first->sub()[0]->op() == kRegexpLiteral ||
1115*ccdc9c3eSSadaf Ebrahimi              first->sub()[0]->op() == kRegexpCharClass ||
1116*ccdc9c3eSSadaf Ebrahimi              first->sub()[0]->op() == kRegexpAnyChar ||
1117*ccdc9c3eSSadaf Ebrahimi              first->sub()[0]->op() == kRegexpAnyByte))) &&
1118*ccdc9c3eSSadaf Ebrahimi           Regexp::Equal(first, first_i))
1119*ccdc9c3eSSadaf Ebrahimi         continue;
1120*ccdc9c3eSSadaf Ebrahimi     }
1121*ccdc9c3eSSadaf Ebrahimi 
1122*ccdc9c3eSSadaf Ebrahimi     // Found end of a run with common leading regexp:
1123*ccdc9c3eSSadaf Ebrahimi     // sub[start:i] all begin with first,
1124*ccdc9c3eSSadaf Ebrahimi     // but sub[i] does not.
1125*ccdc9c3eSSadaf Ebrahimi     if (i == start) {
1126*ccdc9c3eSSadaf Ebrahimi       // Nothing to do - first iteration.
1127*ccdc9c3eSSadaf Ebrahimi     } else if (i == start+1) {
1128*ccdc9c3eSSadaf Ebrahimi       // Just one: don't bother factoring.
1129*ccdc9c3eSSadaf Ebrahimi     } else {
1130*ccdc9c3eSSadaf Ebrahimi       Regexp* prefix = first->Incref();
1131*ccdc9c3eSSadaf Ebrahimi       for (int j = start; j < i; j++)
1132*ccdc9c3eSSadaf Ebrahimi         sub[j] = Regexp::RemoveLeadingRegexp(sub[j]);
1133*ccdc9c3eSSadaf Ebrahimi       splices->emplace_back(prefix, sub + start, i - start);
1134*ccdc9c3eSSadaf Ebrahimi     }
1135*ccdc9c3eSSadaf Ebrahimi 
1136*ccdc9c3eSSadaf Ebrahimi     // Prepare for next iteration (if there is one).
1137*ccdc9c3eSSadaf Ebrahimi     if (i < nsub) {
1138*ccdc9c3eSSadaf Ebrahimi       start = i;
1139*ccdc9c3eSSadaf Ebrahimi       first = first_i;
1140*ccdc9c3eSSadaf Ebrahimi     }
1141*ccdc9c3eSSadaf Ebrahimi   }
1142*ccdc9c3eSSadaf Ebrahimi }
1143*ccdc9c3eSSadaf Ebrahimi 
Round3(Regexp ** sub,int nsub,Regexp::ParseFlags flags,std::vector<Splice> * splices)1144*ccdc9c3eSSadaf Ebrahimi void FactorAlternationImpl::Round3(Regexp** sub, int nsub,
1145*ccdc9c3eSSadaf Ebrahimi                                    Regexp::ParseFlags flags,
1146*ccdc9c3eSSadaf Ebrahimi                                    std::vector<Splice>* splices) {
1147*ccdc9c3eSSadaf Ebrahimi   // Round 3: Merge runs of literals and/or character classes.
1148*ccdc9c3eSSadaf Ebrahimi   int start = 0;
1149*ccdc9c3eSSadaf Ebrahimi   Regexp* first = NULL;
1150*ccdc9c3eSSadaf Ebrahimi   for (int i = 0; i <= nsub; i++) {
1151*ccdc9c3eSSadaf Ebrahimi     // Invariant: sub[start:i] consists of regexps that all
1152*ccdc9c3eSSadaf Ebrahimi     // are either literals (i.e. runes) or character classes.
1153*ccdc9c3eSSadaf Ebrahimi     Regexp* first_i = NULL;
1154*ccdc9c3eSSadaf Ebrahimi     if (i < nsub) {
1155*ccdc9c3eSSadaf Ebrahimi       first_i = sub[i];
1156*ccdc9c3eSSadaf Ebrahimi       if (first != NULL &&
1157*ccdc9c3eSSadaf Ebrahimi           (first->op() == kRegexpLiteral ||
1158*ccdc9c3eSSadaf Ebrahimi            first->op() == kRegexpCharClass) &&
1159*ccdc9c3eSSadaf Ebrahimi           (first_i->op() == kRegexpLiteral ||
1160*ccdc9c3eSSadaf Ebrahimi            first_i->op() == kRegexpCharClass))
1161*ccdc9c3eSSadaf Ebrahimi         continue;
1162*ccdc9c3eSSadaf Ebrahimi     }
1163*ccdc9c3eSSadaf Ebrahimi 
1164*ccdc9c3eSSadaf Ebrahimi     // Found end of a run of Literal/CharClass:
1165*ccdc9c3eSSadaf Ebrahimi     // sub[start:i] all are either one or the other,
1166*ccdc9c3eSSadaf Ebrahimi     // but sub[i] is not.
1167*ccdc9c3eSSadaf Ebrahimi     if (i == start) {
1168*ccdc9c3eSSadaf Ebrahimi       // Nothing to do - first iteration.
1169*ccdc9c3eSSadaf Ebrahimi     } else if (i == start+1) {
1170*ccdc9c3eSSadaf Ebrahimi       // Just one: don't bother factoring.
1171*ccdc9c3eSSadaf Ebrahimi     } else {
1172*ccdc9c3eSSadaf Ebrahimi       CharClassBuilder ccb;
1173*ccdc9c3eSSadaf Ebrahimi       for (int j = start; j < i; j++) {
1174*ccdc9c3eSSadaf Ebrahimi         Regexp* re = sub[j];
1175*ccdc9c3eSSadaf Ebrahimi         if (re->op() == kRegexpCharClass) {
1176*ccdc9c3eSSadaf Ebrahimi           CharClass* cc = re->cc();
1177*ccdc9c3eSSadaf Ebrahimi           for (CharClass::iterator it = cc->begin(); it != cc->end(); ++it)
1178*ccdc9c3eSSadaf Ebrahimi             ccb.AddRange(it->lo, it->hi);
1179*ccdc9c3eSSadaf Ebrahimi         } else if (re->op() == kRegexpLiteral) {
1180*ccdc9c3eSSadaf Ebrahimi           ccb.AddRangeFlags(re->rune(), re->rune(), re->parse_flags());
1181*ccdc9c3eSSadaf Ebrahimi         } else {
1182*ccdc9c3eSSadaf Ebrahimi           LOG(DFATAL) << "RE2: unexpected op: " << re->op() << " "
1183*ccdc9c3eSSadaf Ebrahimi                       << re->ToString();
1184*ccdc9c3eSSadaf Ebrahimi         }
1185*ccdc9c3eSSadaf Ebrahimi         re->Decref();
1186*ccdc9c3eSSadaf Ebrahimi       }
1187*ccdc9c3eSSadaf Ebrahimi       Regexp* re = Regexp::NewCharClass(ccb.GetCharClass(), flags);
1188*ccdc9c3eSSadaf Ebrahimi       splices->emplace_back(re, sub + start, i - start);
1189*ccdc9c3eSSadaf Ebrahimi     }
1190*ccdc9c3eSSadaf Ebrahimi 
1191*ccdc9c3eSSadaf Ebrahimi     // Prepare for next iteration (if there is one).
1192*ccdc9c3eSSadaf Ebrahimi     if (i < nsub) {
1193*ccdc9c3eSSadaf Ebrahimi       start = i;
1194*ccdc9c3eSSadaf Ebrahimi       first = first_i;
1195*ccdc9c3eSSadaf Ebrahimi     }
1196*ccdc9c3eSSadaf Ebrahimi   }
1197*ccdc9c3eSSadaf Ebrahimi }
1198*ccdc9c3eSSadaf Ebrahimi 
1199*ccdc9c3eSSadaf Ebrahimi // Collapse the regexps on top of the stack, down to the
1200*ccdc9c3eSSadaf Ebrahimi // first marker, into a new op node (op == kRegexpAlternate
1201*ccdc9c3eSSadaf Ebrahimi // or op == kRegexpConcat).
DoCollapse(RegexpOp op)1202*ccdc9c3eSSadaf Ebrahimi void Regexp::ParseState::DoCollapse(RegexpOp op) {
1203*ccdc9c3eSSadaf Ebrahimi   // Scan backward to marker, counting children of composite.
1204*ccdc9c3eSSadaf Ebrahimi   int n = 0;
1205*ccdc9c3eSSadaf Ebrahimi   Regexp* next = NULL;
1206*ccdc9c3eSSadaf Ebrahimi   Regexp* sub;
1207*ccdc9c3eSSadaf Ebrahimi   for (sub = stacktop_; sub != NULL && !IsMarker(sub->op()); sub = next) {
1208*ccdc9c3eSSadaf Ebrahimi     next = sub->down_;
1209*ccdc9c3eSSadaf Ebrahimi     if (sub->op_ == op)
1210*ccdc9c3eSSadaf Ebrahimi       n += sub->nsub_;
1211*ccdc9c3eSSadaf Ebrahimi     else
1212*ccdc9c3eSSadaf Ebrahimi       n++;
1213*ccdc9c3eSSadaf Ebrahimi   }
1214*ccdc9c3eSSadaf Ebrahimi 
1215*ccdc9c3eSSadaf Ebrahimi   // If there's just one child, leave it alone.
1216*ccdc9c3eSSadaf Ebrahimi   // (Concat of one thing is that one thing; alternate of one thing is same.)
1217*ccdc9c3eSSadaf Ebrahimi   if (stacktop_ != NULL && stacktop_->down_ == next)
1218*ccdc9c3eSSadaf Ebrahimi     return;
1219*ccdc9c3eSSadaf Ebrahimi 
1220*ccdc9c3eSSadaf Ebrahimi   // Construct op (alternation or concatenation), flattening op of op.
1221*ccdc9c3eSSadaf Ebrahimi   PODArray<Regexp*> subs(n);
1222*ccdc9c3eSSadaf Ebrahimi   next = NULL;
1223*ccdc9c3eSSadaf Ebrahimi   int i = n;
1224*ccdc9c3eSSadaf Ebrahimi   for (sub = stacktop_; sub != NULL && !IsMarker(sub->op()); sub = next) {
1225*ccdc9c3eSSadaf Ebrahimi     next = sub->down_;
1226*ccdc9c3eSSadaf Ebrahimi     if (sub->op_ == op) {
1227*ccdc9c3eSSadaf Ebrahimi       Regexp** sub_subs = sub->sub();
1228*ccdc9c3eSSadaf Ebrahimi       for (int k = sub->nsub_ - 1; k >= 0; k--)
1229*ccdc9c3eSSadaf Ebrahimi         subs[--i] = sub_subs[k]->Incref();
1230*ccdc9c3eSSadaf Ebrahimi       sub->Decref();
1231*ccdc9c3eSSadaf Ebrahimi     } else {
1232*ccdc9c3eSSadaf Ebrahimi       subs[--i] = FinishRegexp(sub);
1233*ccdc9c3eSSadaf Ebrahimi     }
1234*ccdc9c3eSSadaf Ebrahimi   }
1235*ccdc9c3eSSadaf Ebrahimi 
1236*ccdc9c3eSSadaf Ebrahimi   Regexp* re = ConcatOrAlternate(op, subs.data(), n, flags_, true);
1237*ccdc9c3eSSadaf Ebrahimi   re->simple_ = re->ComputeSimple();
1238*ccdc9c3eSSadaf Ebrahimi   re->down_ = next;
1239*ccdc9c3eSSadaf Ebrahimi   stacktop_ = re;
1240*ccdc9c3eSSadaf Ebrahimi }
1241*ccdc9c3eSSadaf Ebrahimi 
1242*ccdc9c3eSSadaf Ebrahimi // Finishes the current concatenation,
1243*ccdc9c3eSSadaf Ebrahimi // collapsing it into a single regexp on the stack.
DoConcatenation()1244*ccdc9c3eSSadaf Ebrahimi void Regexp::ParseState::DoConcatenation() {
1245*ccdc9c3eSSadaf Ebrahimi   Regexp* r1 = stacktop_;
1246*ccdc9c3eSSadaf Ebrahimi   if (r1 == NULL || IsMarker(r1->op())) {
1247*ccdc9c3eSSadaf Ebrahimi     // empty concatenation is special case
1248*ccdc9c3eSSadaf Ebrahimi     Regexp* re = new Regexp(kRegexpEmptyMatch, flags_);
1249*ccdc9c3eSSadaf Ebrahimi     PushRegexp(re);
1250*ccdc9c3eSSadaf Ebrahimi   }
1251*ccdc9c3eSSadaf Ebrahimi   DoCollapse(kRegexpConcat);
1252*ccdc9c3eSSadaf Ebrahimi }
1253*ccdc9c3eSSadaf Ebrahimi 
1254*ccdc9c3eSSadaf Ebrahimi // Finishes the current alternation,
1255*ccdc9c3eSSadaf Ebrahimi // collapsing it to a single regexp on the stack.
DoAlternation()1256*ccdc9c3eSSadaf Ebrahimi void Regexp::ParseState::DoAlternation() {
1257*ccdc9c3eSSadaf Ebrahimi   DoVerticalBar();
1258*ccdc9c3eSSadaf Ebrahimi   // Now stack top is kVerticalBar.
1259*ccdc9c3eSSadaf Ebrahimi   Regexp* r1 = stacktop_;
1260*ccdc9c3eSSadaf Ebrahimi   stacktop_ = r1->down_;
1261*ccdc9c3eSSadaf Ebrahimi   r1->Decref();
1262*ccdc9c3eSSadaf Ebrahimi   DoCollapse(kRegexpAlternate);
1263*ccdc9c3eSSadaf Ebrahimi }
1264*ccdc9c3eSSadaf Ebrahimi 
1265*ccdc9c3eSSadaf Ebrahimi // Incremental conversion of concatenated literals into strings.
1266*ccdc9c3eSSadaf Ebrahimi // If top two elements on stack are both literal or string,
1267*ccdc9c3eSSadaf Ebrahimi // collapse into single string.
1268*ccdc9c3eSSadaf Ebrahimi // Don't walk down the stack -- the parser calls this frequently
1269*ccdc9c3eSSadaf Ebrahimi // enough that below the bottom two is known to be collapsed.
1270*ccdc9c3eSSadaf Ebrahimi // Only called when another regexp is about to be pushed
1271*ccdc9c3eSSadaf Ebrahimi // on the stack, so that the topmost literal is not being considered.
1272*ccdc9c3eSSadaf Ebrahimi // (Otherwise ab* would turn into (ab)*.)
1273*ccdc9c3eSSadaf Ebrahimi // If r >= 0, consider pushing a literal r on the stack.
1274*ccdc9c3eSSadaf Ebrahimi // Return whether that happened.
MaybeConcatString(int r,ParseFlags flags)1275*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::MaybeConcatString(int r, ParseFlags flags) {
1276*ccdc9c3eSSadaf Ebrahimi   Regexp* re1;
1277*ccdc9c3eSSadaf Ebrahimi   Regexp* re2;
1278*ccdc9c3eSSadaf Ebrahimi   if ((re1 = stacktop_) == NULL || (re2 = re1->down_) == NULL)
1279*ccdc9c3eSSadaf Ebrahimi     return false;
1280*ccdc9c3eSSadaf Ebrahimi 
1281*ccdc9c3eSSadaf Ebrahimi   if (re1->op_ != kRegexpLiteral && re1->op_ != kRegexpLiteralString)
1282*ccdc9c3eSSadaf Ebrahimi     return false;
1283*ccdc9c3eSSadaf Ebrahimi   if (re2->op_ != kRegexpLiteral && re2->op_ != kRegexpLiteralString)
1284*ccdc9c3eSSadaf Ebrahimi     return false;
1285*ccdc9c3eSSadaf Ebrahimi   if ((re1->parse_flags_ & FoldCase) != (re2->parse_flags_ & FoldCase))
1286*ccdc9c3eSSadaf Ebrahimi     return false;
1287*ccdc9c3eSSadaf Ebrahimi 
1288*ccdc9c3eSSadaf Ebrahimi   if (re2->op_ == kRegexpLiteral) {
1289*ccdc9c3eSSadaf Ebrahimi     // convert into string
1290*ccdc9c3eSSadaf Ebrahimi     Rune rune = re2->rune_;
1291*ccdc9c3eSSadaf Ebrahimi     re2->op_ = kRegexpLiteralString;
1292*ccdc9c3eSSadaf Ebrahimi     re2->nrunes_ = 0;
1293*ccdc9c3eSSadaf Ebrahimi     re2->runes_ = NULL;
1294*ccdc9c3eSSadaf Ebrahimi     re2->AddRuneToString(rune);
1295*ccdc9c3eSSadaf Ebrahimi   }
1296*ccdc9c3eSSadaf Ebrahimi 
1297*ccdc9c3eSSadaf Ebrahimi   // push re1 into re2.
1298*ccdc9c3eSSadaf Ebrahimi   if (re1->op_ == kRegexpLiteral) {
1299*ccdc9c3eSSadaf Ebrahimi     re2->AddRuneToString(re1->rune_);
1300*ccdc9c3eSSadaf Ebrahimi   } else {
1301*ccdc9c3eSSadaf Ebrahimi     for (int i = 0; i < re1->nrunes_; i++)
1302*ccdc9c3eSSadaf Ebrahimi       re2->AddRuneToString(re1->runes_[i]);
1303*ccdc9c3eSSadaf Ebrahimi     re1->nrunes_ = 0;
1304*ccdc9c3eSSadaf Ebrahimi     delete[] re1->runes_;
1305*ccdc9c3eSSadaf Ebrahimi     re1->runes_ = NULL;
1306*ccdc9c3eSSadaf Ebrahimi   }
1307*ccdc9c3eSSadaf Ebrahimi 
1308*ccdc9c3eSSadaf Ebrahimi   // reuse re1 if possible
1309*ccdc9c3eSSadaf Ebrahimi   if (r >= 0) {
1310*ccdc9c3eSSadaf Ebrahimi     re1->op_ = kRegexpLiteral;
1311*ccdc9c3eSSadaf Ebrahimi     re1->rune_ = r;
1312*ccdc9c3eSSadaf Ebrahimi     re1->parse_flags_ = static_cast<uint16_t>(flags);
1313*ccdc9c3eSSadaf Ebrahimi     return true;
1314*ccdc9c3eSSadaf Ebrahimi   }
1315*ccdc9c3eSSadaf Ebrahimi 
1316*ccdc9c3eSSadaf Ebrahimi   stacktop_ = re2;
1317*ccdc9c3eSSadaf Ebrahimi   re1->Decref();
1318*ccdc9c3eSSadaf Ebrahimi   return false;
1319*ccdc9c3eSSadaf Ebrahimi }
1320*ccdc9c3eSSadaf Ebrahimi 
1321*ccdc9c3eSSadaf Ebrahimi // Lexing routines.
1322*ccdc9c3eSSadaf Ebrahimi 
1323*ccdc9c3eSSadaf Ebrahimi // Parses a decimal integer, storing it in *np.
1324*ccdc9c3eSSadaf Ebrahimi // Sets *s to span the remainder of the string.
ParseInteger(StringPiece * s,int * np)1325*ccdc9c3eSSadaf Ebrahimi static bool ParseInteger(StringPiece* s, int* np) {
1326*ccdc9c3eSSadaf Ebrahimi   if (s->size() == 0 || !isdigit((*s)[0] & 0xFF))
1327*ccdc9c3eSSadaf Ebrahimi     return false;
1328*ccdc9c3eSSadaf Ebrahimi   // Disallow leading zeros.
1329*ccdc9c3eSSadaf Ebrahimi   if (s->size() >= 2 && (*s)[0] == '0' && isdigit((*s)[1] & 0xFF))
1330*ccdc9c3eSSadaf Ebrahimi     return false;
1331*ccdc9c3eSSadaf Ebrahimi   int n = 0;
1332*ccdc9c3eSSadaf Ebrahimi   int c;
1333*ccdc9c3eSSadaf Ebrahimi   while (s->size() > 0 && isdigit(c = (*s)[0] & 0xFF)) {
1334*ccdc9c3eSSadaf Ebrahimi     // Avoid overflow.
1335*ccdc9c3eSSadaf Ebrahimi     if (n >= 100000000)
1336*ccdc9c3eSSadaf Ebrahimi       return false;
1337*ccdc9c3eSSadaf Ebrahimi     n = n*10 + c - '0';
1338*ccdc9c3eSSadaf Ebrahimi     s->remove_prefix(1);  // digit
1339*ccdc9c3eSSadaf Ebrahimi   }
1340*ccdc9c3eSSadaf Ebrahimi   *np = n;
1341*ccdc9c3eSSadaf Ebrahimi   return true;
1342*ccdc9c3eSSadaf Ebrahimi }
1343*ccdc9c3eSSadaf Ebrahimi 
1344*ccdc9c3eSSadaf Ebrahimi // Parses a repetition suffix like {1,2} or {2} or {2,}.
1345*ccdc9c3eSSadaf Ebrahimi // Sets *s to span the remainder of the string on success.
1346*ccdc9c3eSSadaf Ebrahimi // Sets *lo and *hi to the given range.
1347*ccdc9c3eSSadaf Ebrahimi // In the case of {2,}, the high number is unbounded;
1348*ccdc9c3eSSadaf Ebrahimi // sets *hi to -1 to signify this.
1349*ccdc9c3eSSadaf Ebrahimi // {,2} is NOT a valid suffix.
1350*ccdc9c3eSSadaf Ebrahimi // The Maybe in the name signifies that the regexp parse
1351*ccdc9c3eSSadaf Ebrahimi // doesn't fail even if ParseRepetition does, so the StringPiece
1352*ccdc9c3eSSadaf Ebrahimi // s must NOT be edited unless MaybeParseRepetition returns true.
MaybeParseRepetition(StringPiece * sp,int * lo,int * hi)1353*ccdc9c3eSSadaf Ebrahimi static bool MaybeParseRepetition(StringPiece* sp, int* lo, int* hi) {
1354*ccdc9c3eSSadaf Ebrahimi   StringPiece s = *sp;
1355*ccdc9c3eSSadaf Ebrahimi   if (s.size() == 0 || s[0] != '{')
1356*ccdc9c3eSSadaf Ebrahimi     return false;
1357*ccdc9c3eSSadaf Ebrahimi   s.remove_prefix(1);  // '{'
1358*ccdc9c3eSSadaf Ebrahimi   if (!ParseInteger(&s, lo))
1359*ccdc9c3eSSadaf Ebrahimi     return false;
1360*ccdc9c3eSSadaf Ebrahimi   if (s.size() == 0)
1361*ccdc9c3eSSadaf Ebrahimi     return false;
1362*ccdc9c3eSSadaf Ebrahimi   if (s[0] == ',') {
1363*ccdc9c3eSSadaf Ebrahimi     s.remove_prefix(1);  // ','
1364*ccdc9c3eSSadaf Ebrahimi     if (s.size() == 0)
1365*ccdc9c3eSSadaf Ebrahimi       return false;
1366*ccdc9c3eSSadaf Ebrahimi     if (s[0] == '}') {
1367*ccdc9c3eSSadaf Ebrahimi       // {2,} means at least 2
1368*ccdc9c3eSSadaf Ebrahimi       *hi = -1;
1369*ccdc9c3eSSadaf Ebrahimi     } else {
1370*ccdc9c3eSSadaf Ebrahimi       // {2,4} means 2, 3, or 4.
1371*ccdc9c3eSSadaf Ebrahimi       if (!ParseInteger(&s, hi))
1372*ccdc9c3eSSadaf Ebrahimi         return false;
1373*ccdc9c3eSSadaf Ebrahimi     }
1374*ccdc9c3eSSadaf Ebrahimi   } else {
1375*ccdc9c3eSSadaf Ebrahimi     // {2} means exactly two
1376*ccdc9c3eSSadaf Ebrahimi     *hi = *lo;
1377*ccdc9c3eSSadaf Ebrahimi   }
1378*ccdc9c3eSSadaf Ebrahimi   if (s.size() == 0 || s[0] != '}')
1379*ccdc9c3eSSadaf Ebrahimi     return false;
1380*ccdc9c3eSSadaf Ebrahimi   s.remove_prefix(1);  // '}'
1381*ccdc9c3eSSadaf Ebrahimi   *sp = s;
1382*ccdc9c3eSSadaf Ebrahimi   return true;
1383*ccdc9c3eSSadaf Ebrahimi }
1384*ccdc9c3eSSadaf Ebrahimi 
1385*ccdc9c3eSSadaf Ebrahimi // Removes the next Rune from the StringPiece and stores it in *r.
1386*ccdc9c3eSSadaf Ebrahimi // Returns number of bytes removed from sp.
1387*ccdc9c3eSSadaf Ebrahimi // Behaves as though there is a terminating NUL at the end of sp.
1388*ccdc9c3eSSadaf Ebrahimi // Argument order is backwards from usual Google style
1389*ccdc9c3eSSadaf Ebrahimi // but consistent with chartorune.
StringPieceToRune(Rune * r,StringPiece * sp,RegexpStatus * status)1390*ccdc9c3eSSadaf Ebrahimi static int StringPieceToRune(Rune *r, StringPiece *sp, RegexpStatus* status) {
1391*ccdc9c3eSSadaf Ebrahimi   // fullrune() takes int, not size_t. However, it just looks
1392*ccdc9c3eSSadaf Ebrahimi   // at the leading byte and treats any length >= 4 the same.
1393*ccdc9c3eSSadaf Ebrahimi   if (fullrune(sp->data(), static_cast<int>(std::min(size_t{4}, sp->size())))) {
1394*ccdc9c3eSSadaf Ebrahimi     int n = chartorune(r, sp->data());
1395*ccdc9c3eSSadaf Ebrahimi     // Some copies of chartorune have a bug that accepts
1396*ccdc9c3eSSadaf Ebrahimi     // encodings of values in (10FFFF, 1FFFFF] as valid.
1397*ccdc9c3eSSadaf Ebrahimi     // Those values break the character class algorithm,
1398*ccdc9c3eSSadaf Ebrahimi     // which assumes Runemax is the largest rune.
1399*ccdc9c3eSSadaf Ebrahimi     if (*r > Runemax) {
1400*ccdc9c3eSSadaf Ebrahimi       n = 1;
1401*ccdc9c3eSSadaf Ebrahimi       *r = Runeerror;
1402*ccdc9c3eSSadaf Ebrahimi     }
1403*ccdc9c3eSSadaf Ebrahimi     if (!(n == 1 && *r == Runeerror)) {  // no decoding error
1404*ccdc9c3eSSadaf Ebrahimi       sp->remove_prefix(n);
1405*ccdc9c3eSSadaf Ebrahimi       return n;
1406*ccdc9c3eSSadaf Ebrahimi     }
1407*ccdc9c3eSSadaf Ebrahimi   }
1408*ccdc9c3eSSadaf Ebrahimi 
1409*ccdc9c3eSSadaf Ebrahimi   status->set_code(kRegexpBadUTF8);
1410*ccdc9c3eSSadaf Ebrahimi   status->set_error_arg(StringPiece());
1411*ccdc9c3eSSadaf Ebrahimi   return -1;
1412*ccdc9c3eSSadaf Ebrahimi }
1413*ccdc9c3eSSadaf Ebrahimi 
1414*ccdc9c3eSSadaf Ebrahimi // Return whether name is valid UTF-8.
1415*ccdc9c3eSSadaf Ebrahimi // If not, set status to kRegexpBadUTF8.
IsValidUTF8(const StringPiece & s,RegexpStatus * status)1416*ccdc9c3eSSadaf Ebrahimi static bool IsValidUTF8(const StringPiece& s, RegexpStatus* status) {
1417*ccdc9c3eSSadaf Ebrahimi   StringPiece t = s;
1418*ccdc9c3eSSadaf Ebrahimi   Rune r;
1419*ccdc9c3eSSadaf Ebrahimi   while (t.size() > 0) {
1420*ccdc9c3eSSadaf Ebrahimi     if (StringPieceToRune(&r, &t, status) < 0)
1421*ccdc9c3eSSadaf Ebrahimi       return false;
1422*ccdc9c3eSSadaf Ebrahimi   }
1423*ccdc9c3eSSadaf Ebrahimi   return true;
1424*ccdc9c3eSSadaf Ebrahimi }
1425*ccdc9c3eSSadaf Ebrahimi 
1426*ccdc9c3eSSadaf Ebrahimi // Is c a hex digit?
IsHex(int c)1427*ccdc9c3eSSadaf Ebrahimi static int IsHex(int c) {
1428*ccdc9c3eSSadaf Ebrahimi   return ('0' <= c && c <= '9') ||
1429*ccdc9c3eSSadaf Ebrahimi          ('A' <= c && c <= 'F') ||
1430*ccdc9c3eSSadaf Ebrahimi          ('a' <= c && c <= 'f');
1431*ccdc9c3eSSadaf Ebrahimi }
1432*ccdc9c3eSSadaf Ebrahimi 
1433*ccdc9c3eSSadaf Ebrahimi // Convert hex digit to value.
UnHex(int c)1434*ccdc9c3eSSadaf Ebrahimi static int UnHex(int c) {
1435*ccdc9c3eSSadaf Ebrahimi   if ('0' <= c && c <= '9')
1436*ccdc9c3eSSadaf Ebrahimi     return c - '0';
1437*ccdc9c3eSSadaf Ebrahimi   if ('A' <= c && c <= 'F')
1438*ccdc9c3eSSadaf Ebrahimi     return c - 'A' + 10;
1439*ccdc9c3eSSadaf Ebrahimi   if ('a' <= c && c <= 'f')
1440*ccdc9c3eSSadaf Ebrahimi     return c - 'a' + 10;
1441*ccdc9c3eSSadaf Ebrahimi   LOG(DFATAL) << "Bad hex digit " << c;
1442*ccdc9c3eSSadaf Ebrahimi   return 0;
1443*ccdc9c3eSSadaf Ebrahimi }
1444*ccdc9c3eSSadaf Ebrahimi 
1445*ccdc9c3eSSadaf Ebrahimi // Parse an escape sequence (e.g., \n, \{).
1446*ccdc9c3eSSadaf Ebrahimi // Sets *s to span the remainder of the string.
1447*ccdc9c3eSSadaf Ebrahimi // Sets *rp to the named character.
ParseEscape(StringPiece * s,Rune * rp,RegexpStatus * status,int rune_max)1448*ccdc9c3eSSadaf Ebrahimi static bool ParseEscape(StringPiece* s, Rune* rp,
1449*ccdc9c3eSSadaf Ebrahimi                         RegexpStatus* status, int rune_max) {
1450*ccdc9c3eSSadaf Ebrahimi   const char* begin = s->begin();
1451*ccdc9c3eSSadaf Ebrahimi   if (s->size() < 1 || (*s)[0] != '\\') {
1452*ccdc9c3eSSadaf Ebrahimi     // Should not happen - caller always checks.
1453*ccdc9c3eSSadaf Ebrahimi     status->set_code(kRegexpInternalError);
1454*ccdc9c3eSSadaf Ebrahimi     status->set_error_arg(StringPiece());
1455*ccdc9c3eSSadaf Ebrahimi     return false;
1456*ccdc9c3eSSadaf Ebrahimi   }
1457*ccdc9c3eSSadaf Ebrahimi   if (s->size() < 2) {
1458*ccdc9c3eSSadaf Ebrahimi     status->set_code(kRegexpTrailingBackslash);
1459*ccdc9c3eSSadaf Ebrahimi     status->set_error_arg(StringPiece());
1460*ccdc9c3eSSadaf Ebrahimi     return false;
1461*ccdc9c3eSSadaf Ebrahimi   }
1462*ccdc9c3eSSadaf Ebrahimi   Rune c, c1;
1463*ccdc9c3eSSadaf Ebrahimi   s->remove_prefix(1);  // backslash
1464*ccdc9c3eSSadaf Ebrahimi   if (StringPieceToRune(&c, s, status) < 0)
1465*ccdc9c3eSSadaf Ebrahimi     return false;
1466*ccdc9c3eSSadaf Ebrahimi   int code;
1467*ccdc9c3eSSadaf Ebrahimi   switch (c) {
1468*ccdc9c3eSSadaf Ebrahimi     default:
1469*ccdc9c3eSSadaf Ebrahimi       if (c < Runeself && !isalpha(c) && !isdigit(c)) {
1470*ccdc9c3eSSadaf Ebrahimi         // Escaped non-word characters are always themselves.
1471*ccdc9c3eSSadaf Ebrahimi         // PCRE is not quite so rigorous: it accepts things like
1472*ccdc9c3eSSadaf Ebrahimi         // \q, but we don't.  We once rejected \_, but too many
1473*ccdc9c3eSSadaf Ebrahimi         // programs and people insist on using it, so allow \_.
1474*ccdc9c3eSSadaf Ebrahimi         *rp = c;
1475*ccdc9c3eSSadaf Ebrahimi         return true;
1476*ccdc9c3eSSadaf Ebrahimi       }
1477*ccdc9c3eSSadaf Ebrahimi       goto BadEscape;
1478*ccdc9c3eSSadaf Ebrahimi 
1479*ccdc9c3eSSadaf Ebrahimi     // Octal escapes.
1480*ccdc9c3eSSadaf Ebrahimi     case '1':
1481*ccdc9c3eSSadaf Ebrahimi     case '2':
1482*ccdc9c3eSSadaf Ebrahimi     case '3':
1483*ccdc9c3eSSadaf Ebrahimi     case '4':
1484*ccdc9c3eSSadaf Ebrahimi     case '5':
1485*ccdc9c3eSSadaf Ebrahimi     case '6':
1486*ccdc9c3eSSadaf Ebrahimi     case '7':
1487*ccdc9c3eSSadaf Ebrahimi       // Single non-zero octal digit is a backreference; not supported.
1488*ccdc9c3eSSadaf Ebrahimi       if (s->size() == 0 || (*s)[0] < '0' || (*s)[0] > '7')
1489*ccdc9c3eSSadaf Ebrahimi         goto BadEscape;
1490*ccdc9c3eSSadaf Ebrahimi       FALLTHROUGH_INTENDED;
1491*ccdc9c3eSSadaf Ebrahimi     case '0':
1492*ccdc9c3eSSadaf Ebrahimi       // consume up to three octal digits; already have one.
1493*ccdc9c3eSSadaf Ebrahimi       code = c - '0';
1494*ccdc9c3eSSadaf Ebrahimi       if (s->size() > 0 && '0' <= (c = (*s)[0]) && c <= '7') {
1495*ccdc9c3eSSadaf Ebrahimi         code = code * 8 + c - '0';
1496*ccdc9c3eSSadaf Ebrahimi         s->remove_prefix(1);  // digit
1497*ccdc9c3eSSadaf Ebrahimi         if (s->size() > 0) {
1498*ccdc9c3eSSadaf Ebrahimi           c = (*s)[0];
1499*ccdc9c3eSSadaf Ebrahimi           if ('0' <= c && c <= '7') {
1500*ccdc9c3eSSadaf Ebrahimi             code = code * 8 + c - '0';
1501*ccdc9c3eSSadaf Ebrahimi             s->remove_prefix(1);  // digit
1502*ccdc9c3eSSadaf Ebrahimi           }
1503*ccdc9c3eSSadaf Ebrahimi         }
1504*ccdc9c3eSSadaf Ebrahimi       }
1505*ccdc9c3eSSadaf Ebrahimi       if (code > rune_max)
1506*ccdc9c3eSSadaf Ebrahimi         goto BadEscape;
1507*ccdc9c3eSSadaf Ebrahimi       *rp = code;
1508*ccdc9c3eSSadaf Ebrahimi       return true;
1509*ccdc9c3eSSadaf Ebrahimi 
1510*ccdc9c3eSSadaf Ebrahimi     // Hexadecimal escapes
1511*ccdc9c3eSSadaf Ebrahimi     case 'x':
1512*ccdc9c3eSSadaf Ebrahimi       if (s->size() == 0)
1513*ccdc9c3eSSadaf Ebrahimi         goto BadEscape;
1514*ccdc9c3eSSadaf Ebrahimi       if (StringPieceToRune(&c, s, status) < 0)
1515*ccdc9c3eSSadaf Ebrahimi         return false;
1516*ccdc9c3eSSadaf Ebrahimi       if (c == '{') {
1517*ccdc9c3eSSadaf Ebrahimi         // Any number of digits in braces.
1518*ccdc9c3eSSadaf Ebrahimi         // Update n as we consume the string, so that
1519*ccdc9c3eSSadaf Ebrahimi         // the whole thing gets shown in the error message.
1520*ccdc9c3eSSadaf Ebrahimi         // Perl accepts any text at all; it ignores all text
1521*ccdc9c3eSSadaf Ebrahimi         // after the first non-hex digit.  We require only hex digits,
1522*ccdc9c3eSSadaf Ebrahimi         // and at least one.
1523*ccdc9c3eSSadaf Ebrahimi         if (StringPieceToRune(&c, s, status) < 0)
1524*ccdc9c3eSSadaf Ebrahimi           return false;
1525*ccdc9c3eSSadaf Ebrahimi         int nhex = 0;
1526*ccdc9c3eSSadaf Ebrahimi         code = 0;
1527*ccdc9c3eSSadaf Ebrahimi         while (IsHex(c)) {
1528*ccdc9c3eSSadaf Ebrahimi           nhex++;
1529*ccdc9c3eSSadaf Ebrahimi           code = code * 16 + UnHex(c);
1530*ccdc9c3eSSadaf Ebrahimi           if (code > rune_max)
1531*ccdc9c3eSSadaf Ebrahimi             goto BadEscape;
1532*ccdc9c3eSSadaf Ebrahimi           if (s->size() == 0)
1533*ccdc9c3eSSadaf Ebrahimi             goto BadEscape;
1534*ccdc9c3eSSadaf Ebrahimi           if (StringPieceToRune(&c, s, status) < 0)
1535*ccdc9c3eSSadaf Ebrahimi             return false;
1536*ccdc9c3eSSadaf Ebrahimi         }
1537*ccdc9c3eSSadaf Ebrahimi         if (c != '}' || nhex == 0)
1538*ccdc9c3eSSadaf Ebrahimi           goto BadEscape;
1539*ccdc9c3eSSadaf Ebrahimi         *rp = code;
1540*ccdc9c3eSSadaf Ebrahimi         return true;
1541*ccdc9c3eSSadaf Ebrahimi       }
1542*ccdc9c3eSSadaf Ebrahimi       // Easy case: two hex digits.
1543*ccdc9c3eSSadaf Ebrahimi       if (s->size() == 0)
1544*ccdc9c3eSSadaf Ebrahimi         goto BadEscape;
1545*ccdc9c3eSSadaf Ebrahimi       if (StringPieceToRune(&c1, s, status) < 0)
1546*ccdc9c3eSSadaf Ebrahimi         return false;
1547*ccdc9c3eSSadaf Ebrahimi       if (!IsHex(c) || !IsHex(c1))
1548*ccdc9c3eSSadaf Ebrahimi         goto BadEscape;
1549*ccdc9c3eSSadaf Ebrahimi       *rp = UnHex(c) * 16 + UnHex(c1);
1550*ccdc9c3eSSadaf Ebrahimi       return true;
1551*ccdc9c3eSSadaf Ebrahimi 
1552*ccdc9c3eSSadaf Ebrahimi     // C escapes.
1553*ccdc9c3eSSadaf Ebrahimi     case 'n':
1554*ccdc9c3eSSadaf Ebrahimi       *rp = '\n';
1555*ccdc9c3eSSadaf Ebrahimi       return true;
1556*ccdc9c3eSSadaf Ebrahimi     case 'r':
1557*ccdc9c3eSSadaf Ebrahimi       *rp = '\r';
1558*ccdc9c3eSSadaf Ebrahimi       return true;
1559*ccdc9c3eSSadaf Ebrahimi     case 't':
1560*ccdc9c3eSSadaf Ebrahimi       *rp = '\t';
1561*ccdc9c3eSSadaf Ebrahimi       return true;
1562*ccdc9c3eSSadaf Ebrahimi 
1563*ccdc9c3eSSadaf Ebrahimi     // Less common C escapes.
1564*ccdc9c3eSSadaf Ebrahimi     case 'a':
1565*ccdc9c3eSSadaf Ebrahimi       *rp = '\a';
1566*ccdc9c3eSSadaf Ebrahimi       return true;
1567*ccdc9c3eSSadaf Ebrahimi     case 'f':
1568*ccdc9c3eSSadaf Ebrahimi       *rp = '\f';
1569*ccdc9c3eSSadaf Ebrahimi       return true;
1570*ccdc9c3eSSadaf Ebrahimi     case 'v':
1571*ccdc9c3eSSadaf Ebrahimi       *rp = '\v';
1572*ccdc9c3eSSadaf Ebrahimi       return true;
1573*ccdc9c3eSSadaf Ebrahimi 
1574*ccdc9c3eSSadaf Ebrahimi     // This code is disabled to avoid misparsing
1575*ccdc9c3eSSadaf Ebrahimi     // the Perl word-boundary \b as a backspace
1576*ccdc9c3eSSadaf Ebrahimi     // when in POSIX regexp mode.  Surprisingly,
1577*ccdc9c3eSSadaf Ebrahimi     // in Perl, \b means word-boundary but [\b]
1578*ccdc9c3eSSadaf Ebrahimi     // means backspace.  We don't support that:
1579*ccdc9c3eSSadaf Ebrahimi     // if you want a backspace embed a literal
1580*ccdc9c3eSSadaf Ebrahimi     // backspace character or use \x08.
1581*ccdc9c3eSSadaf Ebrahimi     //
1582*ccdc9c3eSSadaf Ebrahimi     // case 'b':
1583*ccdc9c3eSSadaf Ebrahimi     //   *rp = '\b';
1584*ccdc9c3eSSadaf Ebrahimi     //   return true;
1585*ccdc9c3eSSadaf Ebrahimi   }
1586*ccdc9c3eSSadaf Ebrahimi 
1587*ccdc9c3eSSadaf Ebrahimi   LOG(DFATAL) << "Not reached in ParseEscape.";
1588*ccdc9c3eSSadaf Ebrahimi 
1589*ccdc9c3eSSadaf Ebrahimi BadEscape:
1590*ccdc9c3eSSadaf Ebrahimi   // Unrecognized escape sequence.
1591*ccdc9c3eSSadaf Ebrahimi   status->set_code(kRegexpBadEscape);
1592*ccdc9c3eSSadaf Ebrahimi   status->set_error_arg(
1593*ccdc9c3eSSadaf Ebrahimi       StringPiece(begin, static_cast<size_t>(s->begin() - begin)));
1594*ccdc9c3eSSadaf Ebrahimi   return false;
1595*ccdc9c3eSSadaf Ebrahimi }
1596*ccdc9c3eSSadaf Ebrahimi 
1597*ccdc9c3eSSadaf Ebrahimi // Add a range to the character class, but exclude newline if asked.
1598*ccdc9c3eSSadaf Ebrahimi // Also handle case folding.
AddRangeFlags(Rune lo,Rune hi,Regexp::ParseFlags parse_flags)1599*ccdc9c3eSSadaf Ebrahimi void CharClassBuilder::AddRangeFlags(
1600*ccdc9c3eSSadaf Ebrahimi     Rune lo, Rune hi, Regexp::ParseFlags parse_flags) {
1601*ccdc9c3eSSadaf Ebrahimi 
1602*ccdc9c3eSSadaf Ebrahimi   // Take out \n if the flags say so.
1603*ccdc9c3eSSadaf Ebrahimi   bool cutnl = !(parse_flags & Regexp::ClassNL) ||
1604*ccdc9c3eSSadaf Ebrahimi                (parse_flags & Regexp::NeverNL);
1605*ccdc9c3eSSadaf Ebrahimi   if (cutnl && lo <= '\n' && '\n' <= hi) {
1606*ccdc9c3eSSadaf Ebrahimi     if (lo < '\n')
1607*ccdc9c3eSSadaf Ebrahimi       AddRangeFlags(lo, '\n' - 1, parse_flags);
1608*ccdc9c3eSSadaf Ebrahimi     if (hi > '\n')
1609*ccdc9c3eSSadaf Ebrahimi       AddRangeFlags('\n' + 1, hi, parse_flags);
1610*ccdc9c3eSSadaf Ebrahimi     return;
1611*ccdc9c3eSSadaf Ebrahimi   }
1612*ccdc9c3eSSadaf Ebrahimi 
1613*ccdc9c3eSSadaf Ebrahimi   // If folding case, add fold-equivalent characters too.
1614*ccdc9c3eSSadaf Ebrahimi   if (parse_flags & Regexp::FoldCase)
1615*ccdc9c3eSSadaf Ebrahimi     AddFoldedRange(this, lo, hi, 0);
1616*ccdc9c3eSSadaf Ebrahimi   else
1617*ccdc9c3eSSadaf Ebrahimi     AddRange(lo, hi);
1618*ccdc9c3eSSadaf Ebrahimi }
1619*ccdc9c3eSSadaf Ebrahimi 
1620*ccdc9c3eSSadaf Ebrahimi // Look for a group with the given name.
LookupGroup(const StringPiece & name,const UGroup * groups,int ngroups)1621*ccdc9c3eSSadaf Ebrahimi static const UGroup* LookupGroup(const StringPiece& name,
1622*ccdc9c3eSSadaf Ebrahimi                                  const UGroup *groups, int ngroups) {
1623*ccdc9c3eSSadaf Ebrahimi   // Simple name lookup.
1624*ccdc9c3eSSadaf Ebrahimi   for (int i = 0; i < ngroups; i++)
1625*ccdc9c3eSSadaf Ebrahimi     if (StringPiece(groups[i].name) == name)
1626*ccdc9c3eSSadaf Ebrahimi       return &groups[i];
1627*ccdc9c3eSSadaf Ebrahimi   return NULL;
1628*ccdc9c3eSSadaf Ebrahimi }
1629*ccdc9c3eSSadaf Ebrahimi 
1630*ccdc9c3eSSadaf Ebrahimi // Look for a POSIX group with the given name (e.g., "[:^alpha:]")
LookupPosixGroup(const StringPiece & name)1631*ccdc9c3eSSadaf Ebrahimi static const UGroup* LookupPosixGroup(const StringPiece& name) {
1632*ccdc9c3eSSadaf Ebrahimi   return LookupGroup(name, posix_groups, num_posix_groups);
1633*ccdc9c3eSSadaf Ebrahimi }
1634*ccdc9c3eSSadaf Ebrahimi 
LookupPerlGroup(const StringPiece & name)1635*ccdc9c3eSSadaf Ebrahimi static const UGroup* LookupPerlGroup(const StringPiece& name) {
1636*ccdc9c3eSSadaf Ebrahimi   return LookupGroup(name, perl_groups, num_perl_groups);
1637*ccdc9c3eSSadaf Ebrahimi }
1638*ccdc9c3eSSadaf Ebrahimi 
1639*ccdc9c3eSSadaf Ebrahimi #if !defined(RE2_USE_ICU)
1640*ccdc9c3eSSadaf Ebrahimi // Fake UGroup containing all Runes
1641*ccdc9c3eSSadaf Ebrahimi static URange16 any16[] = { { 0, 65535 } };
1642*ccdc9c3eSSadaf Ebrahimi static URange32 any32[] = { { 65536, Runemax } };
1643*ccdc9c3eSSadaf Ebrahimi static UGroup anygroup = { "Any", +1, any16, 1, any32, 1 };
1644*ccdc9c3eSSadaf Ebrahimi 
1645*ccdc9c3eSSadaf Ebrahimi // Look for a Unicode group with the given name (e.g., "Han")
LookupUnicodeGroup(const StringPiece & name)1646*ccdc9c3eSSadaf Ebrahimi static const UGroup* LookupUnicodeGroup(const StringPiece& name) {
1647*ccdc9c3eSSadaf Ebrahimi   // Special case: "Any" means any.
1648*ccdc9c3eSSadaf Ebrahimi   if (name == StringPiece("Any"))
1649*ccdc9c3eSSadaf Ebrahimi     return &anygroup;
1650*ccdc9c3eSSadaf Ebrahimi   return LookupGroup(name, unicode_groups, num_unicode_groups);
1651*ccdc9c3eSSadaf Ebrahimi }
1652*ccdc9c3eSSadaf Ebrahimi #endif
1653*ccdc9c3eSSadaf Ebrahimi 
1654*ccdc9c3eSSadaf Ebrahimi // Add a UGroup or its negation to the character class.
AddUGroup(CharClassBuilder * cc,const UGroup * g,int sign,Regexp::ParseFlags parse_flags)1655*ccdc9c3eSSadaf Ebrahimi static void AddUGroup(CharClassBuilder *cc, const UGroup *g, int sign,
1656*ccdc9c3eSSadaf Ebrahimi                       Regexp::ParseFlags parse_flags) {
1657*ccdc9c3eSSadaf Ebrahimi   if (sign == +1) {
1658*ccdc9c3eSSadaf Ebrahimi     for (int i = 0; i < g->nr16; i++) {
1659*ccdc9c3eSSadaf Ebrahimi       cc->AddRangeFlags(g->r16[i].lo, g->r16[i].hi, parse_flags);
1660*ccdc9c3eSSadaf Ebrahimi     }
1661*ccdc9c3eSSadaf Ebrahimi     for (int i = 0; i < g->nr32; i++) {
1662*ccdc9c3eSSadaf Ebrahimi       cc->AddRangeFlags(g->r32[i].lo, g->r32[i].hi, parse_flags);
1663*ccdc9c3eSSadaf Ebrahimi     }
1664*ccdc9c3eSSadaf Ebrahimi   } else {
1665*ccdc9c3eSSadaf Ebrahimi     if (parse_flags & Regexp::FoldCase) {
1666*ccdc9c3eSSadaf Ebrahimi       // Normally adding a case-folded group means
1667*ccdc9c3eSSadaf Ebrahimi       // adding all the extra fold-equivalent runes too.
1668*ccdc9c3eSSadaf Ebrahimi       // But if we're adding the negation of the group,
1669*ccdc9c3eSSadaf Ebrahimi       // we have to exclude all the runes that are fold-equivalent
1670*ccdc9c3eSSadaf Ebrahimi       // to what's already missing.  Too hard, so do in two steps.
1671*ccdc9c3eSSadaf Ebrahimi       CharClassBuilder ccb1;
1672*ccdc9c3eSSadaf Ebrahimi       AddUGroup(&ccb1, g, +1, parse_flags);
1673*ccdc9c3eSSadaf Ebrahimi       // If the flags say to take out \n, put it in, so that negating will take it out.
1674*ccdc9c3eSSadaf Ebrahimi       // Normally AddRangeFlags does this, but we're bypassing AddRangeFlags.
1675*ccdc9c3eSSadaf Ebrahimi       bool cutnl = !(parse_flags & Regexp::ClassNL) ||
1676*ccdc9c3eSSadaf Ebrahimi                    (parse_flags & Regexp::NeverNL);
1677*ccdc9c3eSSadaf Ebrahimi       if (cutnl) {
1678*ccdc9c3eSSadaf Ebrahimi         ccb1.AddRange('\n', '\n');
1679*ccdc9c3eSSadaf Ebrahimi       }
1680*ccdc9c3eSSadaf Ebrahimi       ccb1.Negate();
1681*ccdc9c3eSSadaf Ebrahimi       cc->AddCharClass(&ccb1);
1682*ccdc9c3eSSadaf Ebrahimi       return;
1683*ccdc9c3eSSadaf Ebrahimi     }
1684*ccdc9c3eSSadaf Ebrahimi     int next = 0;
1685*ccdc9c3eSSadaf Ebrahimi     for (int i = 0; i < g->nr16; i++) {
1686*ccdc9c3eSSadaf Ebrahimi       if (next < g->r16[i].lo)
1687*ccdc9c3eSSadaf Ebrahimi         cc->AddRangeFlags(next, g->r16[i].lo - 1, parse_flags);
1688*ccdc9c3eSSadaf Ebrahimi       next = g->r16[i].hi + 1;
1689*ccdc9c3eSSadaf Ebrahimi     }
1690*ccdc9c3eSSadaf Ebrahimi     for (int i = 0; i < g->nr32; i++) {
1691*ccdc9c3eSSadaf Ebrahimi       if (next < g->r32[i].lo)
1692*ccdc9c3eSSadaf Ebrahimi         cc->AddRangeFlags(next, g->r32[i].lo - 1, parse_flags);
1693*ccdc9c3eSSadaf Ebrahimi       next = g->r32[i].hi + 1;
1694*ccdc9c3eSSadaf Ebrahimi     }
1695*ccdc9c3eSSadaf Ebrahimi     if (next <= Runemax)
1696*ccdc9c3eSSadaf Ebrahimi       cc->AddRangeFlags(next, Runemax, parse_flags);
1697*ccdc9c3eSSadaf Ebrahimi   }
1698*ccdc9c3eSSadaf Ebrahimi }
1699*ccdc9c3eSSadaf Ebrahimi 
1700*ccdc9c3eSSadaf Ebrahimi // Maybe parse a Perl character class escape sequence.
1701*ccdc9c3eSSadaf Ebrahimi // Only recognizes the Perl character classes (\d \s \w \D \S \W),
1702*ccdc9c3eSSadaf Ebrahimi // not the Perl empty-string classes (\b \B \A \Z \z).
1703*ccdc9c3eSSadaf Ebrahimi // On success, sets *s to span the remainder of the string
1704*ccdc9c3eSSadaf Ebrahimi // and returns the corresponding UGroup.
1705*ccdc9c3eSSadaf Ebrahimi // The StringPiece must *NOT* be edited unless the call succeeds.
MaybeParsePerlCCEscape(StringPiece * s,Regexp::ParseFlags parse_flags)1706*ccdc9c3eSSadaf Ebrahimi const UGroup* MaybeParsePerlCCEscape(StringPiece* s, Regexp::ParseFlags parse_flags) {
1707*ccdc9c3eSSadaf Ebrahimi   if (!(parse_flags & Regexp::PerlClasses))
1708*ccdc9c3eSSadaf Ebrahimi     return NULL;
1709*ccdc9c3eSSadaf Ebrahimi   if (s->size() < 2 || (*s)[0] != '\\')
1710*ccdc9c3eSSadaf Ebrahimi     return NULL;
1711*ccdc9c3eSSadaf Ebrahimi   // Could use StringPieceToRune, but there aren't
1712*ccdc9c3eSSadaf Ebrahimi   // any non-ASCII Perl group names.
1713*ccdc9c3eSSadaf Ebrahimi   StringPiece name(s->begin(), 2);
1714*ccdc9c3eSSadaf Ebrahimi   const UGroup *g = LookupPerlGroup(name);
1715*ccdc9c3eSSadaf Ebrahimi   if (g == NULL)
1716*ccdc9c3eSSadaf Ebrahimi     return NULL;
1717*ccdc9c3eSSadaf Ebrahimi   s->remove_prefix(name.size());
1718*ccdc9c3eSSadaf Ebrahimi   return g;
1719*ccdc9c3eSSadaf Ebrahimi }
1720*ccdc9c3eSSadaf Ebrahimi 
1721*ccdc9c3eSSadaf Ebrahimi enum ParseStatus {
1722*ccdc9c3eSSadaf Ebrahimi   kParseOk,  // Did some parsing.
1723*ccdc9c3eSSadaf Ebrahimi   kParseError,  // Found an error.
1724*ccdc9c3eSSadaf Ebrahimi   kParseNothing,  // Decided not to parse.
1725*ccdc9c3eSSadaf Ebrahimi };
1726*ccdc9c3eSSadaf Ebrahimi 
1727*ccdc9c3eSSadaf Ebrahimi // Maybe parses a Unicode character group like \p{Han} or \P{Han}
1728*ccdc9c3eSSadaf Ebrahimi // (the latter is a negated group).
ParseUnicodeGroup(StringPiece * s,Regexp::ParseFlags parse_flags,CharClassBuilder * cc,RegexpStatus * status)1729*ccdc9c3eSSadaf Ebrahimi ParseStatus ParseUnicodeGroup(StringPiece* s, Regexp::ParseFlags parse_flags,
1730*ccdc9c3eSSadaf Ebrahimi                               CharClassBuilder *cc,
1731*ccdc9c3eSSadaf Ebrahimi                               RegexpStatus* status) {
1732*ccdc9c3eSSadaf Ebrahimi   // Decide whether to parse.
1733*ccdc9c3eSSadaf Ebrahimi   if (!(parse_flags & Regexp::UnicodeGroups))
1734*ccdc9c3eSSadaf Ebrahimi     return kParseNothing;
1735*ccdc9c3eSSadaf Ebrahimi   if (s->size() < 2 || (*s)[0] != '\\')
1736*ccdc9c3eSSadaf Ebrahimi     return kParseNothing;
1737*ccdc9c3eSSadaf Ebrahimi   Rune c = (*s)[1];
1738*ccdc9c3eSSadaf Ebrahimi   if (c != 'p' && c != 'P')
1739*ccdc9c3eSSadaf Ebrahimi     return kParseNothing;
1740*ccdc9c3eSSadaf Ebrahimi 
1741*ccdc9c3eSSadaf Ebrahimi   // Committed to parse.  Results:
1742*ccdc9c3eSSadaf Ebrahimi   int sign = +1;  // -1 = negated char class
1743*ccdc9c3eSSadaf Ebrahimi   if (c == 'P')
1744*ccdc9c3eSSadaf Ebrahimi     sign = -sign;
1745*ccdc9c3eSSadaf Ebrahimi   StringPiece seq = *s;  // \p{Han} or \pL
1746*ccdc9c3eSSadaf Ebrahimi   StringPiece name;  // Han or L
1747*ccdc9c3eSSadaf Ebrahimi   s->remove_prefix(2);  // '\\', 'p'
1748*ccdc9c3eSSadaf Ebrahimi 
1749*ccdc9c3eSSadaf Ebrahimi   if (!StringPieceToRune(&c, s, status))
1750*ccdc9c3eSSadaf Ebrahimi     return kParseError;
1751*ccdc9c3eSSadaf Ebrahimi   if (c != '{') {
1752*ccdc9c3eSSadaf Ebrahimi     // Name is the bit of string we just skipped over for c.
1753*ccdc9c3eSSadaf Ebrahimi     const char* p = seq.begin() + 2;
1754*ccdc9c3eSSadaf Ebrahimi     name = StringPiece(p, static_cast<size_t>(s->begin() - p));
1755*ccdc9c3eSSadaf Ebrahimi   } else {
1756*ccdc9c3eSSadaf Ebrahimi     // Name is in braces. Look for closing }
1757*ccdc9c3eSSadaf Ebrahimi     size_t end = s->find('}', 0);
1758*ccdc9c3eSSadaf Ebrahimi     if (end == StringPiece::npos) {
1759*ccdc9c3eSSadaf Ebrahimi       if (!IsValidUTF8(seq, status))
1760*ccdc9c3eSSadaf Ebrahimi         return kParseError;
1761*ccdc9c3eSSadaf Ebrahimi       status->set_code(kRegexpBadCharRange);
1762*ccdc9c3eSSadaf Ebrahimi       status->set_error_arg(seq);
1763*ccdc9c3eSSadaf Ebrahimi       return kParseError;
1764*ccdc9c3eSSadaf Ebrahimi     }
1765*ccdc9c3eSSadaf Ebrahimi     name = StringPiece(s->begin(), end);  // without '}'
1766*ccdc9c3eSSadaf Ebrahimi     s->remove_prefix(end + 1);  // with '}'
1767*ccdc9c3eSSadaf Ebrahimi     if (!IsValidUTF8(name, status))
1768*ccdc9c3eSSadaf Ebrahimi       return kParseError;
1769*ccdc9c3eSSadaf Ebrahimi   }
1770*ccdc9c3eSSadaf Ebrahimi 
1771*ccdc9c3eSSadaf Ebrahimi   // Chop seq where s now begins.
1772*ccdc9c3eSSadaf Ebrahimi   seq = StringPiece(seq.begin(), static_cast<size_t>(s->begin() - seq.begin()));
1773*ccdc9c3eSSadaf Ebrahimi 
1774*ccdc9c3eSSadaf Ebrahimi   if (name.size() > 0 && name[0] == '^') {
1775*ccdc9c3eSSadaf Ebrahimi     sign = -sign;
1776*ccdc9c3eSSadaf Ebrahimi     name.remove_prefix(1);  // '^'
1777*ccdc9c3eSSadaf Ebrahimi   }
1778*ccdc9c3eSSadaf Ebrahimi 
1779*ccdc9c3eSSadaf Ebrahimi #if !defined(RE2_USE_ICU)
1780*ccdc9c3eSSadaf Ebrahimi   // Look up the group in the RE2 Unicode data.
1781*ccdc9c3eSSadaf Ebrahimi   const UGroup *g = LookupUnicodeGroup(name);
1782*ccdc9c3eSSadaf Ebrahimi   if (g == NULL) {
1783*ccdc9c3eSSadaf Ebrahimi     status->set_code(kRegexpBadCharRange);
1784*ccdc9c3eSSadaf Ebrahimi     status->set_error_arg(seq);
1785*ccdc9c3eSSadaf Ebrahimi     return kParseError;
1786*ccdc9c3eSSadaf Ebrahimi   }
1787*ccdc9c3eSSadaf Ebrahimi 
1788*ccdc9c3eSSadaf Ebrahimi   AddUGroup(cc, g, sign, parse_flags);
1789*ccdc9c3eSSadaf Ebrahimi #else
1790*ccdc9c3eSSadaf Ebrahimi   // Look up the group in the ICU Unicode data. Because ICU provides full
1791*ccdc9c3eSSadaf Ebrahimi   // Unicode properties support, this could be more than a lookup by name.
1792*ccdc9c3eSSadaf Ebrahimi   ::icu::UnicodeString ustr = ::icu::UnicodeString::fromUTF8(
1793*ccdc9c3eSSadaf Ebrahimi       string("\\p{") + string(name) + string("}"));
1794*ccdc9c3eSSadaf Ebrahimi   UErrorCode uerr = U_ZERO_ERROR;
1795*ccdc9c3eSSadaf Ebrahimi   ::icu::UnicodeSet uset(ustr, uerr);
1796*ccdc9c3eSSadaf Ebrahimi   if (U_FAILURE(uerr)) {
1797*ccdc9c3eSSadaf Ebrahimi     status->set_code(kRegexpBadCharRange);
1798*ccdc9c3eSSadaf Ebrahimi     status->set_error_arg(seq);
1799*ccdc9c3eSSadaf Ebrahimi     return kParseError;
1800*ccdc9c3eSSadaf Ebrahimi   }
1801*ccdc9c3eSSadaf Ebrahimi 
1802*ccdc9c3eSSadaf Ebrahimi   // Convert the UnicodeSet to a URange32 and UGroup that we can add.
1803*ccdc9c3eSSadaf Ebrahimi   int nr = uset.getRangeCount();
1804*ccdc9c3eSSadaf Ebrahimi   URange32* r = new URange32[nr];
1805*ccdc9c3eSSadaf Ebrahimi   for (int i = 0; i < nr; i++) {
1806*ccdc9c3eSSadaf Ebrahimi     r[i].lo = uset.getRangeStart(i);
1807*ccdc9c3eSSadaf Ebrahimi     r[i].hi = uset.getRangeEnd(i);
1808*ccdc9c3eSSadaf Ebrahimi   }
1809*ccdc9c3eSSadaf Ebrahimi   UGroup g = {"", +1, 0, 0, r, nr};
1810*ccdc9c3eSSadaf Ebrahimi   AddUGroup(cc, &g, sign, parse_flags);
1811*ccdc9c3eSSadaf Ebrahimi   delete[] r;
1812*ccdc9c3eSSadaf Ebrahimi #endif
1813*ccdc9c3eSSadaf Ebrahimi 
1814*ccdc9c3eSSadaf Ebrahimi   return kParseOk;
1815*ccdc9c3eSSadaf Ebrahimi }
1816*ccdc9c3eSSadaf Ebrahimi 
1817*ccdc9c3eSSadaf Ebrahimi // Parses a character class name like [:alnum:].
1818*ccdc9c3eSSadaf Ebrahimi // Sets *s to span the remainder of the string.
1819*ccdc9c3eSSadaf Ebrahimi // Adds the ranges corresponding to the class to ranges.
ParseCCName(StringPiece * s,Regexp::ParseFlags parse_flags,CharClassBuilder * cc,RegexpStatus * status)1820*ccdc9c3eSSadaf Ebrahimi static ParseStatus ParseCCName(StringPiece* s, Regexp::ParseFlags parse_flags,
1821*ccdc9c3eSSadaf Ebrahimi                                CharClassBuilder *cc,
1822*ccdc9c3eSSadaf Ebrahimi                                RegexpStatus* status) {
1823*ccdc9c3eSSadaf Ebrahimi   // Check begins with [:
1824*ccdc9c3eSSadaf Ebrahimi   const char* p = s->data();
1825*ccdc9c3eSSadaf Ebrahimi   const char* ep = s->data() + s->size();
1826*ccdc9c3eSSadaf Ebrahimi   if (ep - p < 2 || p[0] != '[' || p[1] != ':')
1827*ccdc9c3eSSadaf Ebrahimi     return kParseNothing;
1828*ccdc9c3eSSadaf Ebrahimi 
1829*ccdc9c3eSSadaf Ebrahimi   // Look for closing :].
1830*ccdc9c3eSSadaf Ebrahimi   const char* q;
1831*ccdc9c3eSSadaf Ebrahimi   for (q = p+2; q <= ep-2 && (*q != ':' || *(q+1) != ']'); q++)
1832*ccdc9c3eSSadaf Ebrahimi     ;
1833*ccdc9c3eSSadaf Ebrahimi 
1834*ccdc9c3eSSadaf Ebrahimi   // If no closing :], then ignore.
1835*ccdc9c3eSSadaf Ebrahimi   if (q > ep-2)
1836*ccdc9c3eSSadaf Ebrahimi     return kParseNothing;
1837*ccdc9c3eSSadaf Ebrahimi 
1838*ccdc9c3eSSadaf Ebrahimi   // Got it.  Check that it's valid.
1839*ccdc9c3eSSadaf Ebrahimi   q += 2;
1840*ccdc9c3eSSadaf Ebrahimi   StringPiece name(p, static_cast<size_t>(q - p));
1841*ccdc9c3eSSadaf Ebrahimi 
1842*ccdc9c3eSSadaf Ebrahimi   const UGroup *g = LookupPosixGroup(name);
1843*ccdc9c3eSSadaf Ebrahimi   if (g == NULL) {
1844*ccdc9c3eSSadaf Ebrahimi     status->set_code(kRegexpBadCharRange);
1845*ccdc9c3eSSadaf Ebrahimi     status->set_error_arg(name);
1846*ccdc9c3eSSadaf Ebrahimi     return kParseError;
1847*ccdc9c3eSSadaf Ebrahimi   }
1848*ccdc9c3eSSadaf Ebrahimi 
1849*ccdc9c3eSSadaf Ebrahimi   s->remove_prefix(name.size());
1850*ccdc9c3eSSadaf Ebrahimi   AddUGroup(cc, g, g->sign, parse_flags);
1851*ccdc9c3eSSadaf Ebrahimi   return kParseOk;
1852*ccdc9c3eSSadaf Ebrahimi }
1853*ccdc9c3eSSadaf Ebrahimi 
1854*ccdc9c3eSSadaf Ebrahimi // Parses a character inside a character class.
1855*ccdc9c3eSSadaf Ebrahimi // There are fewer special characters here than in the rest of the regexp.
1856*ccdc9c3eSSadaf Ebrahimi // Sets *s to span the remainder of the string.
1857*ccdc9c3eSSadaf Ebrahimi // Sets *rp to the character.
ParseCCCharacter(StringPiece * s,Rune * rp,const StringPiece & whole_class,RegexpStatus * status)1858*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::ParseCCCharacter(StringPiece* s, Rune *rp,
1859*ccdc9c3eSSadaf Ebrahimi                                           const StringPiece& whole_class,
1860*ccdc9c3eSSadaf Ebrahimi                                           RegexpStatus* status) {
1861*ccdc9c3eSSadaf Ebrahimi   if (s->size() == 0) {
1862*ccdc9c3eSSadaf Ebrahimi     status->set_code(kRegexpMissingBracket);
1863*ccdc9c3eSSadaf Ebrahimi     status->set_error_arg(whole_class);
1864*ccdc9c3eSSadaf Ebrahimi     return false;
1865*ccdc9c3eSSadaf Ebrahimi   }
1866*ccdc9c3eSSadaf Ebrahimi 
1867*ccdc9c3eSSadaf Ebrahimi   // Allow regular escape sequences even though
1868*ccdc9c3eSSadaf Ebrahimi   // many need not be escaped in this context.
1869*ccdc9c3eSSadaf Ebrahimi   if (s->size() >= 1 && (*s)[0] == '\\')
1870*ccdc9c3eSSadaf Ebrahimi     return ParseEscape(s, rp, status, rune_max_);
1871*ccdc9c3eSSadaf Ebrahimi 
1872*ccdc9c3eSSadaf Ebrahimi   // Otherwise take the next rune.
1873*ccdc9c3eSSadaf Ebrahimi   return StringPieceToRune(rp, s, status) >= 0;
1874*ccdc9c3eSSadaf Ebrahimi }
1875*ccdc9c3eSSadaf Ebrahimi 
1876*ccdc9c3eSSadaf Ebrahimi // Parses a character class character, or, if the character
1877*ccdc9c3eSSadaf Ebrahimi // is followed by a hyphen, parses a character class range.
1878*ccdc9c3eSSadaf Ebrahimi // For single characters, rr->lo == rr->hi.
1879*ccdc9c3eSSadaf Ebrahimi // Sets *s to span the remainder of the string.
1880*ccdc9c3eSSadaf Ebrahimi // Sets *rp to the character.
ParseCCRange(StringPiece * s,RuneRange * rr,const StringPiece & whole_class,RegexpStatus * status)1881*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::ParseCCRange(StringPiece* s, RuneRange* rr,
1882*ccdc9c3eSSadaf Ebrahimi                                       const StringPiece& whole_class,
1883*ccdc9c3eSSadaf Ebrahimi                                       RegexpStatus* status) {
1884*ccdc9c3eSSadaf Ebrahimi   StringPiece os = *s;
1885*ccdc9c3eSSadaf Ebrahimi   if (!ParseCCCharacter(s, &rr->lo, whole_class, status))
1886*ccdc9c3eSSadaf Ebrahimi     return false;
1887*ccdc9c3eSSadaf Ebrahimi   // [a-] means (a|-), so check for final ].
1888*ccdc9c3eSSadaf Ebrahimi   if (s->size() >= 2 && (*s)[0] == '-' && (*s)[1] != ']') {
1889*ccdc9c3eSSadaf Ebrahimi     s->remove_prefix(1);  // '-'
1890*ccdc9c3eSSadaf Ebrahimi     if (!ParseCCCharacter(s, &rr->hi, whole_class, status))
1891*ccdc9c3eSSadaf Ebrahimi       return false;
1892*ccdc9c3eSSadaf Ebrahimi     if (rr->hi < rr->lo) {
1893*ccdc9c3eSSadaf Ebrahimi       status->set_code(kRegexpBadCharRange);
1894*ccdc9c3eSSadaf Ebrahimi       status->set_error_arg(
1895*ccdc9c3eSSadaf Ebrahimi           StringPiece(os.data(), static_cast<size_t>(s->data() - os.data())));
1896*ccdc9c3eSSadaf Ebrahimi       return false;
1897*ccdc9c3eSSadaf Ebrahimi     }
1898*ccdc9c3eSSadaf Ebrahimi   } else {
1899*ccdc9c3eSSadaf Ebrahimi     rr->hi = rr->lo;
1900*ccdc9c3eSSadaf Ebrahimi   }
1901*ccdc9c3eSSadaf Ebrahimi   return true;
1902*ccdc9c3eSSadaf Ebrahimi }
1903*ccdc9c3eSSadaf Ebrahimi 
1904*ccdc9c3eSSadaf Ebrahimi // Parses a possibly-negated character class expression like [^abx-z[:digit:]].
1905*ccdc9c3eSSadaf Ebrahimi // Sets *s to span the remainder of the string.
1906*ccdc9c3eSSadaf Ebrahimi // Sets *out_re to the regexp for the class.
ParseCharClass(StringPiece * s,Regexp ** out_re,RegexpStatus * status)1907*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::ParseCharClass(StringPiece* s,
1908*ccdc9c3eSSadaf Ebrahimi                                         Regexp** out_re,
1909*ccdc9c3eSSadaf Ebrahimi                                         RegexpStatus* status) {
1910*ccdc9c3eSSadaf Ebrahimi   StringPiece whole_class = *s;
1911*ccdc9c3eSSadaf Ebrahimi   if (s->size() == 0 || (*s)[0] != '[') {
1912*ccdc9c3eSSadaf Ebrahimi     // Caller checked this.
1913*ccdc9c3eSSadaf Ebrahimi     status->set_code(kRegexpInternalError);
1914*ccdc9c3eSSadaf Ebrahimi     status->set_error_arg(StringPiece());
1915*ccdc9c3eSSadaf Ebrahimi     return false;
1916*ccdc9c3eSSadaf Ebrahimi   }
1917*ccdc9c3eSSadaf Ebrahimi   bool negated = false;
1918*ccdc9c3eSSadaf Ebrahimi   Regexp* re = new Regexp(kRegexpCharClass, flags_ & ~FoldCase);
1919*ccdc9c3eSSadaf Ebrahimi   re->ccb_ = new CharClassBuilder;
1920*ccdc9c3eSSadaf Ebrahimi   s->remove_prefix(1);  // '['
1921*ccdc9c3eSSadaf Ebrahimi   if (s->size() > 0 && (*s)[0] == '^') {
1922*ccdc9c3eSSadaf Ebrahimi     s->remove_prefix(1);  // '^'
1923*ccdc9c3eSSadaf Ebrahimi     negated = true;
1924*ccdc9c3eSSadaf Ebrahimi     if (!(flags_ & ClassNL) || (flags_ & NeverNL)) {
1925*ccdc9c3eSSadaf Ebrahimi       // If NL can't match implicitly, then pretend
1926*ccdc9c3eSSadaf Ebrahimi       // negated classes include a leading \n.
1927*ccdc9c3eSSadaf Ebrahimi       re->ccb_->AddRange('\n', '\n');
1928*ccdc9c3eSSadaf Ebrahimi     }
1929*ccdc9c3eSSadaf Ebrahimi   }
1930*ccdc9c3eSSadaf Ebrahimi   bool first = true;  // ] is okay as first char in class
1931*ccdc9c3eSSadaf Ebrahimi   while (s->size() > 0 && ((*s)[0] != ']' || first)) {
1932*ccdc9c3eSSadaf Ebrahimi     // - is only okay unescaped as first or last in class.
1933*ccdc9c3eSSadaf Ebrahimi     // Except that Perl allows - anywhere.
1934*ccdc9c3eSSadaf Ebrahimi     if ((*s)[0] == '-' && !first && !(flags_&PerlX) &&
1935*ccdc9c3eSSadaf Ebrahimi         (s->size() == 1 || (*s)[1] != ']')) {
1936*ccdc9c3eSSadaf Ebrahimi       StringPiece t = *s;
1937*ccdc9c3eSSadaf Ebrahimi       t.remove_prefix(1);  // '-'
1938*ccdc9c3eSSadaf Ebrahimi       Rune r;
1939*ccdc9c3eSSadaf Ebrahimi       int n = StringPieceToRune(&r, &t, status);
1940*ccdc9c3eSSadaf Ebrahimi       if (n < 0) {
1941*ccdc9c3eSSadaf Ebrahimi         re->Decref();
1942*ccdc9c3eSSadaf Ebrahimi         return false;
1943*ccdc9c3eSSadaf Ebrahimi       }
1944*ccdc9c3eSSadaf Ebrahimi       status->set_code(kRegexpBadCharRange);
1945*ccdc9c3eSSadaf Ebrahimi       status->set_error_arg(StringPiece(s->data(), 1+n));
1946*ccdc9c3eSSadaf Ebrahimi       re->Decref();
1947*ccdc9c3eSSadaf Ebrahimi       return false;
1948*ccdc9c3eSSadaf Ebrahimi     }
1949*ccdc9c3eSSadaf Ebrahimi     first = false;
1950*ccdc9c3eSSadaf Ebrahimi 
1951*ccdc9c3eSSadaf Ebrahimi     // Look for [:alnum:] etc.
1952*ccdc9c3eSSadaf Ebrahimi     if (s->size() > 2 && (*s)[0] == '[' && (*s)[1] == ':') {
1953*ccdc9c3eSSadaf Ebrahimi       switch (ParseCCName(s, flags_, re->ccb_, status)) {
1954*ccdc9c3eSSadaf Ebrahimi         case kParseOk:
1955*ccdc9c3eSSadaf Ebrahimi           continue;
1956*ccdc9c3eSSadaf Ebrahimi         case kParseError:
1957*ccdc9c3eSSadaf Ebrahimi           re->Decref();
1958*ccdc9c3eSSadaf Ebrahimi           return false;
1959*ccdc9c3eSSadaf Ebrahimi         case kParseNothing:
1960*ccdc9c3eSSadaf Ebrahimi           break;
1961*ccdc9c3eSSadaf Ebrahimi       }
1962*ccdc9c3eSSadaf Ebrahimi     }
1963*ccdc9c3eSSadaf Ebrahimi 
1964*ccdc9c3eSSadaf Ebrahimi     // Look for Unicode character group like \p{Han}
1965*ccdc9c3eSSadaf Ebrahimi     if (s->size() > 2 &&
1966*ccdc9c3eSSadaf Ebrahimi         (*s)[0] == '\\' &&
1967*ccdc9c3eSSadaf Ebrahimi         ((*s)[1] == 'p' || (*s)[1] == 'P')) {
1968*ccdc9c3eSSadaf Ebrahimi       switch (ParseUnicodeGroup(s, flags_, re->ccb_, status)) {
1969*ccdc9c3eSSadaf Ebrahimi         case kParseOk:
1970*ccdc9c3eSSadaf Ebrahimi           continue;
1971*ccdc9c3eSSadaf Ebrahimi         case kParseError:
1972*ccdc9c3eSSadaf Ebrahimi           re->Decref();
1973*ccdc9c3eSSadaf Ebrahimi           return false;
1974*ccdc9c3eSSadaf Ebrahimi         case kParseNothing:
1975*ccdc9c3eSSadaf Ebrahimi           break;
1976*ccdc9c3eSSadaf Ebrahimi       }
1977*ccdc9c3eSSadaf Ebrahimi     }
1978*ccdc9c3eSSadaf Ebrahimi 
1979*ccdc9c3eSSadaf Ebrahimi     // Look for Perl character class symbols (extension).
1980*ccdc9c3eSSadaf Ebrahimi     const UGroup *g = MaybeParsePerlCCEscape(s, flags_);
1981*ccdc9c3eSSadaf Ebrahimi     if (g != NULL) {
1982*ccdc9c3eSSadaf Ebrahimi       AddUGroup(re->ccb_, g, g->sign, flags_);
1983*ccdc9c3eSSadaf Ebrahimi       continue;
1984*ccdc9c3eSSadaf Ebrahimi     }
1985*ccdc9c3eSSadaf Ebrahimi 
1986*ccdc9c3eSSadaf Ebrahimi     // Otherwise assume single character or simple range.
1987*ccdc9c3eSSadaf Ebrahimi     RuneRange rr;
1988*ccdc9c3eSSadaf Ebrahimi     if (!ParseCCRange(s, &rr, whole_class, status)) {
1989*ccdc9c3eSSadaf Ebrahimi       re->Decref();
1990*ccdc9c3eSSadaf Ebrahimi       return false;
1991*ccdc9c3eSSadaf Ebrahimi     }
1992*ccdc9c3eSSadaf Ebrahimi     // AddRangeFlags is usually called in response to a class like
1993*ccdc9c3eSSadaf Ebrahimi     // \p{Foo} or [[:foo:]]; for those, it filters \n out unless
1994*ccdc9c3eSSadaf Ebrahimi     // Regexp::ClassNL is set.  In an explicit range or singleton
1995*ccdc9c3eSSadaf Ebrahimi     // like we just parsed, we do not filter \n out, so set ClassNL
1996*ccdc9c3eSSadaf Ebrahimi     // in the flags.
1997*ccdc9c3eSSadaf Ebrahimi     re->ccb_->AddRangeFlags(rr.lo, rr.hi, flags_ | Regexp::ClassNL);
1998*ccdc9c3eSSadaf Ebrahimi   }
1999*ccdc9c3eSSadaf Ebrahimi   if (s->size() == 0) {
2000*ccdc9c3eSSadaf Ebrahimi     status->set_code(kRegexpMissingBracket);
2001*ccdc9c3eSSadaf Ebrahimi     status->set_error_arg(whole_class);
2002*ccdc9c3eSSadaf Ebrahimi     re->Decref();
2003*ccdc9c3eSSadaf Ebrahimi     return false;
2004*ccdc9c3eSSadaf Ebrahimi   }
2005*ccdc9c3eSSadaf Ebrahimi   s->remove_prefix(1);  // ']'
2006*ccdc9c3eSSadaf Ebrahimi 
2007*ccdc9c3eSSadaf Ebrahimi   if (negated)
2008*ccdc9c3eSSadaf Ebrahimi     re->ccb_->Negate();
2009*ccdc9c3eSSadaf Ebrahimi 
2010*ccdc9c3eSSadaf Ebrahimi   *out_re = re;
2011*ccdc9c3eSSadaf Ebrahimi   return true;
2012*ccdc9c3eSSadaf Ebrahimi }
2013*ccdc9c3eSSadaf Ebrahimi 
2014*ccdc9c3eSSadaf Ebrahimi // Is this a valid capture name?  [A-Za-z0-9_]+
2015*ccdc9c3eSSadaf Ebrahimi // PCRE limits names to 32 bytes.
2016*ccdc9c3eSSadaf Ebrahimi // Python rejects names starting with digits.
2017*ccdc9c3eSSadaf Ebrahimi // We don't enforce either of those.
IsValidCaptureName(const StringPiece & name)2018*ccdc9c3eSSadaf Ebrahimi static bool IsValidCaptureName(const StringPiece& name) {
2019*ccdc9c3eSSadaf Ebrahimi   if (name.size() == 0)
2020*ccdc9c3eSSadaf Ebrahimi     return false;
2021*ccdc9c3eSSadaf Ebrahimi   for (size_t i = 0; i < name.size(); i++) {
2022*ccdc9c3eSSadaf Ebrahimi     int c = name[i];
2023*ccdc9c3eSSadaf Ebrahimi     if (('0' <= c && c <= '9') ||
2024*ccdc9c3eSSadaf Ebrahimi         ('a' <= c && c <= 'z') ||
2025*ccdc9c3eSSadaf Ebrahimi         ('A' <= c && c <= 'Z') ||
2026*ccdc9c3eSSadaf Ebrahimi         c == '_')
2027*ccdc9c3eSSadaf Ebrahimi       continue;
2028*ccdc9c3eSSadaf Ebrahimi     return false;
2029*ccdc9c3eSSadaf Ebrahimi   }
2030*ccdc9c3eSSadaf Ebrahimi   return true;
2031*ccdc9c3eSSadaf Ebrahimi }
2032*ccdc9c3eSSadaf Ebrahimi 
2033*ccdc9c3eSSadaf Ebrahimi // Parses a Perl flag setting or non-capturing group or both,
2034*ccdc9c3eSSadaf Ebrahimi // like (?i) or (?: or (?i:.  Removes from s, updates parse state.
2035*ccdc9c3eSSadaf Ebrahimi // The caller must check that s begins with "(?".
2036*ccdc9c3eSSadaf Ebrahimi // Returns true on success.  If the Perl flag is not
2037*ccdc9c3eSSadaf Ebrahimi // well-formed or not supported, sets status_ and returns false.
ParsePerlFlags(StringPiece * s)2038*ccdc9c3eSSadaf Ebrahimi bool Regexp::ParseState::ParsePerlFlags(StringPiece* s) {
2039*ccdc9c3eSSadaf Ebrahimi   StringPiece t = *s;
2040*ccdc9c3eSSadaf Ebrahimi 
2041*ccdc9c3eSSadaf Ebrahimi   // Caller is supposed to check this.
2042*ccdc9c3eSSadaf Ebrahimi   if (!(flags_ & PerlX) || t.size() < 2 || t[0] != '(' || t[1] != '?') {
2043*ccdc9c3eSSadaf Ebrahimi     LOG(DFATAL) << "Bad call to ParseState::ParsePerlFlags";
2044*ccdc9c3eSSadaf Ebrahimi     status_->set_code(kRegexpInternalError);
2045*ccdc9c3eSSadaf Ebrahimi     return false;
2046*ccdc9c3eSSadaf Ebrahimi   }
2047*ccdc9c3eSSadaf Ebrahimi 
2048*ccdc9c3eSSadaf Ebrahimi   t.remove_prefix(2);  // "(?"
2049*ccdc9c3eSSadaf Ebrahimi 
2050*ccdc9c3eSSadaf Ebrahimi   // Check for named captures, first introduced in Python's regexp library.
2051*ccdc9c3eSSadaf Ebrahimi   // As usual, there are three slightly different syntaxes:
2052*ccdc9c3eSSadaf Ebrahimi   //
2053*ccdc9c3eSSadaf Ebrahimi   //   (?P<name>expr)   the original, introduced by Python
2054*ccdc9c3eSSadaf Ebrahimi   //   (?<name>expr)    the .NET alteration, adopted by Perl 5.10
2055*ccdc9c3eSSadaf Ebrahimi   //   (?'name'expr)    another .NET alteration, adopted by Perl 5.10
2056*ccdc9c3eSSadaf Ebrahimi   //
2057*ccdc9c3eSSadaf Ebrahimi   // Perl 5.10 gave in and implemented the Python version too,
2058*ccdc9c3eSSadaf Ebrahimi   // but they claim that the last two are the preferred forms.
2059*ccdc9c3eSSadaf Ebrahimi   // PCRE and languages based on it (specifically, PHP and Ruby)
2060*ccdc9c3eSSadaf Ebrahimi   // support all three as well.  EcmaScript 4 uses only the Python form.
2061*ccdc9c3eSSadaf Ebrahimi   //
2062*ccdc9c3eSSadaf Ebrahimi   // In both the open source world (via Code Search) and the
2063*ccdc9c3eSSadaf Ebrahimi   // Google source tree, (?P<expr>name) is the dominant form,
2064*ccdc9c3eSSadaf Ebrahimi   // so that's the one we implement.  One is enough.
2065*ccdc9c3eSSadaf Ebrahimi   if (t.size() > 2 && t[0] == 'P' && t[1] == '<') {
2066*ccdc9c3eSSadaf Ebrahimi     // Pull out name.
2067*ccdc9c3eSSadaf Ebrahimi     size_t end = t.find('>', 2);
2068*ccdc9c3eSSadaf Ebrahimi     if (end == StringPiece::npos) {
2069*ccdc9c3eSSadaf Ebrahimi       if (!IsValidUTF8(*s, status_))
2070*ccdc9c3eSSadaf Ebrahimi         return false;
2071*ccdc9c3eSSadaf Ebrahimi       status_->set_code(kRegexpBadNamedCapture);
2072*ccdc9c3eSSadaf Ebrahimi       status_->set_error_arg(*s);
2073*ccdc9c3eSSadaf Ebrahimi       return false;
2074*ccdc9c3eSSadaf Ebrahimi     }
2075*ccdc9c3eSSadaf Ebrahimi 
2076*ccdc9c3eSSadaf Ebrahimi     // t is "P<name>...", t[end] == '>'
2077*ccdc9c3eSSadaf Ebrahimi     StringPiece capture(t.begin()-2, end+3);  // "(?P<name>"
2078*ccdc9c3eSSadaf Ebrahimi     StringPiece name(t.begin()+2, end-2);     // "name"
2079*ccdc9c3eSSadaf Ebrahimi     if (!IsValidUTF8(name, status_))
2080*ccdc9c3eSSadaf Ebrahimi       return false;
2081*ccdc9c3eSSadaf Ebrahimi     if (!IsValidCaptureName(name)) {
2082*ccdc9c3eSSadaf Ebrahimi       status_->set_code(kRegexpBadNamedCapture);
2083*ccdc9c3eSSadaf Ebrahimi       status_->set_error_arg(capture);
2084*ccdc9c3eSSadaf Ebrahimi       return false;
2085*ccdc9c3eSSadaf Ebrahimi     }
2086*ccdc9c3eSSadaf Ebrahimi 
2087*ccdc9c3eSSadaf Ebrahimi     if (!DoLeftParen(name)) {
2088*ccdc9c3eSSadaf Ebrahimi       // DoLeftParen's failure set status_.
2089*ccdc9c3eSSadaf Ebrahimi       return false;
2090*ccdc9c3eSSadaf Ebrahimi     }
2091*ccdc9c3eSSadaf Ebrahimi 
2092*ccdc9c3eSSadaf Ebrahimi     s->remove_prefix(static_cast<size_t>(capture.end() - s->begin()));
2093*ccdc9c3eSSadaf Ebrahimi     return true;
2094*ccdc9c3eSSadaf Ebrahimi   }
2095*ccdc9c3eSSadaf Ebrahimi 
2096*ccdc9c3eSSadaf Ebrahimi   bool negated = false;
2097*ccdc9c3eSSadaf Ebrahimi   bool sawflags = false;
2098*ccdc9c3eSSadaf Ebrahimi   int nflags = flags_;
2099*ccdc9c3eSSadaf Ebrahimi   Rune c;
2100*ccdc9c3eSSadaf Ebrahimi   for (bool done = false; !done; ) {
2101*ccdc9c3eSSadaf Ebrahimi     if (t.size() == 0)
2102*ccdc9c3eSSadaf Ebrahimi       goto BadPerlOp;
2103*ccdc9c3eSSadaf Ebrahimi     if (StringPieceToRune(&c, &t, status_) < 0)
2104*ccdc9c3eSSadaf Ebrahimi       return false;
2105*ccdc9c3eSSadaf Ebrahimi     switch (c) {
2106*ccdc9c3eSSadaf Ebrahimi       default:
2107*ccdc9c3eSSadaf Ebrahimi         goto BadPerlOp;
2108*ccdc9c3eSSadaf Ebrahimi 
2109*ccdc9c3eSSadaf Ebrahimi       // Parse flags.
2110*ccdc9c3eSSadaf Ebrahimi       case 'i':
2111*ccdc9c3eSSadaf Ebrahimi         sawflags = true;
2112*ccdc9c3eSSadaf Ebrahimi         if (negated)
2113*ccdc9c3eSSadaf Ebrahimi           nflags &= ~FoldCase;
2114*ccdc9c3eSSadaf Ebrahimi         else
2115*ccdc9c3eSSadaf Ebrahimi           nflags |= FoldCase;
2116*ccdc9c3eSSadaf Ebrahimi         break;
2117*ccdc9c3eSSadaf Ebrahimi 
2118*ccdc9c3eSSadaf Ebrahimi       case 'm':  // opposite of our OneLine
2119*ccdc9c3eSSadaf Ebrahimi         sawflags = true;
2120*ccdc9c3eSSadaf Ebrahimi         if (negated)
2121*ccdc9c3eSSadaf Ebrahimi           nflags |= OneLine;
2122*ccdc9c3eSSadaf Ebrahimi         else
2123*ccdc9c3eSSadaf Ebrahimi           nflags &= ~OneLine;
2124*ccdc9c3eSSadaf Ebrahimi         break;
2125*ccdc9c3eSSadaf Ebrahimi 
2126*ccdc9c3eSSadaf Ebrahimi       case 's':
2127*ccdc9c3eSSadaf Ebrahimi         sawflags = true;
2128*ccdc9c3eSSadaf Ebrahimi         if (negated)
2129*ccdc9c3eSSadaf Ebrahimi           nflags &= ~DotNL;
2130*ccdc9c3eSSadaf Ebrahimi         else
2131*ccdc9c3eSSadaf Ebrahimi           nflags |= DotNL;
2132*ccdc9c3eSSadaf Ebrahimi         break;
2133*ccdc9c3eSSadaf Ebrahimi 
2134*ccdc9c3eSSadaf Ebrahimi       case 'U':
2135*ccdc9c3eSSadaf Ebrahimi         sawflags = true;
2136*ccdc9c3eSSadaf Ebrahimi         if (negated)
2137*ccdc9c3eSSadaf Ebrahimi           nflags &= ~NonGreedy;
2138*ccdc9c3eSSadaf Ebrahimi         else
2139*ccdc9c3eSSadaf Ebrahimi           nflags |= NonGreedy;
2140*ccdc9c3eSSadaf Ebrahimi         break;
2141*ccdc9c3eSSadaf Ebrahimi 
2142*ccdc9c3eSSadaf Ebrahimi       // Negation
2143*ccdc9c3eSSadaf Ebrahimi       case '-':
2144*ccdc9c3eSSadaf Ebrahimi         if (negated)
2145*ccdc9c3eSSadaf Ebrahimi           goto BadPerlOp;
2146*ccdc9c3eSSadaf Ebrahimi         negated = true;
2147*ccdc9c3eSSadaf Ebrahimi         sawflags = false;
2148*ccdc9c3eSSadaf Ebrahimi         break;
2149*ccdc9c3eSSadaf Ebrahimi 
2150*ccdc9c3eSSadaf Ebrahimi       // Open new group.
2151*ccdc9c3eSSadaf Ebrahimi       case ':':
2152*ccdc9c3eSSadaf Ebrahimi         if (!DoLeftParenNoCapture()) {
2153*ccdc9c3eSSadaf Ebrahimi           // DoLeftParenNoCapture's failure set status_.
2154*ccdc9c3eSSadaf Ebrahimi           return false;
2155*ccdc9c3eSSadaf Ebrahimi         }
2156*ccdc9c3eSSadaf Ebrahimi         done = true;
2157*ccdc9c3eSSadaf Ebrahimi         break;
2158*ccdc9c3eSSadaf Ebrahimi 
2159*ccdc9c3eSSadaf Ebrahimi       // Finish flags.
2160*ccdc9c3eSSadaf Ebrahimi       case ')':
2161*ccdc9c3eSSadaf Ebrahimi         done = true;
2162*ccdc9c3eSSadaf Ebrahimi         break;
2163*ccdc9c3eSSadaf Ebrahimi     }
2164*ccdc9c3eSSadaf Ebrahimi   }
2165*ccdc9c3eSSadaf Ebrahimi 
2166*ccdc9c3eSSadaf Ebrahimi   if (negated && !sawflags)
2167*ccdc9c3eSSadaf Ebrahimi     goto BadPerlOp;
2168*ccdc9c3eSSadaf Ebrahimi 
2169*ccdc9c3eSSadaf Ebrahimi   flags_ = static_cast<Regexp::ParseFlags>(nflags);
2170*ccdc9c3eSSadaf Ebrahimi   *s = t;
2171*ccdc9c3eSSadaf Ebrahimi   return true;
2172*ccdc9c3eSSadaf Ebrahimi 
2173*ccdc9c3eSSadaf Ebrahimi BadPerlOp:
2174*ccdc9c3eSSadaf Ebrahimi   status_->set_code(kRegexpBadPerlOp);
2175*ccdc9c3eSSadaf Ebrahimi   status_->set_error_arg(
2176*ccdc9c3eSSadaf Ebrahimi       StringPiece(s->begin(), static_cast<size_t>(t.begin() - s->begin())));
2177*ccdc9c3eSSadaf Ebrahimi   return false;
2178*ccdc9c3eSSadaf Ebrahimi }
2179*ccdc9c3eSSadaf Ebrahimi 
2180*ccdc9c3eSSadaf Ebrahimi // Converts latin1 (assumed to be encoded as Latin1 bytes)
2181*ccdc9c3eSSadaf Ebrahimi // into UTF8 encoding in string.
2182*ccdc9c3eSSadaf Ebrahimi // Can't use EncodingUtils::EncodeLatin1AsUTF8 because it is
2183*ccdc9c3eSSadaf Ebrahimi // deprecated and because it rejects code points 0x80-0x9F.
ConvertLatin1ToUTF8(const StringPiece & latin1,string * utf)2184*ccdc9c3eSSadaf Ebrahimi void ConvertLatin1ToUTF8(const StringPiece& latin1, string* utf) {
2185*ccdc9c3eSSadaf Ebrahimi   char buf[UTFmax];
2186*ccdc9c3eSSadaf Ebrahimi 
2187*ccdc9c3eSSadaf Ebrahimi   utf->clear();
2188*ccdc9c3eSSadaf Ebrahimi   for (size_t i = 0; i < latin1.size(); i++) {
2189*ccdc9c3eSSadaf Ebrahimi     Rune r = latin1[i] & 0xFF;
2190*ccdc9c3eSSadaf Ebrahimi     int n = runetochar(buf, &r);
2191*ccdc9c3eSSadaf Ebrahimi     utf->append(buf, n);
2192*ccdc9c3eSSadaf Ebrahimi   }
2193*ccdc9c3eSSadaf Ebrahimi }
2194*ccdc9c3eSSadaf Ebrahimi 
2195*ccdc9c3eSSadaf Ebrahimi // Parses the regular expression given by s,
2196*ccdc9c3eSSadaf Ebrahimi // returning the corresponding Regexp tree.
2197*ccdc9c3eSSadaf Ebrahimi // The caller must Decref the return value when done with it.
2198*ccdc9c3eSSadaf Ebrahimi // Returns NULL on error.
Parse(const StringPiece & s,ParseFlags global_flags,RegexpStatus * status)2199*ccdc9c3eSSadaf Ebrahimi Regexp* Regexp::Parse(const StringPiece& s, ParseFlags global_flags,
2200*ccdc9c3eSSadaf Ebrahimi                       RegexpStatus* status) {
2201*ccdc9c3eSSadaf Ebrahimi   // Make status non-NULL (easier on everyone else).
2202*ccdc9c3eSSadaf Ebrahimi   RegexpStatus xstatus;
2203*ccdc9c3eSSadaf Ebrahimi   if (status == NULL)
2204*ccdc9c3eSSadaf Ebrahimi     status = &xstatus;
2205*ccdc9c3eSSadaf Ebrahimi 
2206*ccdc9c3eSSadaf Ebrahimi   ParseState ps(global_flags, s, status);
2207*ccdc9c3eSSadaf Ebrahimi   StringPiece t = s;
2208*ccdc9c3eSSadaf Ebrahimi 
2209*ccdc9c3eSSadaf Ebrahimi   // Convert regexp to UTF-8 (easier on the rest of the parser).
2210*ccdc9c3eSSadaf Ebrahimi   if (global_flags & Latin1) {
2211*ccdc9c3eSSadaf Ebrahimi     string* tmp = new string;
2212*ccdc9c3eSSadaf Ebrahimi     ConvertLatin1ToUTF8(t, tmp);
2213*ccdc9c3eSSadaf Ebrahimi     status->set_tmp(tmp);
2214*ccdc9c3eSSadaf Ebrahimi     t = *tmp;
2215*ccdc9c3eSSadaf Ebrahimi   }
2216*ccdc9c3eSSadaf Ebrahimi 
2217*ccdc9c3eSSadaf Ebrahimi   if (global_flags & Literal) {
2218*ccdc9c3eSSadaf Ebrahimi     // Special parse loop for literal string.
2219*ccdc9c3eSSadaf Ebrahimi     while (t.size() > 0) {
2220*ccdc9c3eSSadaf Ebrahimi       Rune r;
2221*ccdc9c3eSSadaf Ebrahimi       if (StringPieceToRune(&r, &t, status) < 0)
2222*ccdc9c3eSSadaf Ebrahimi         return NULL;
2223*ccdc9c3eSSadaf Ebrahimi       if (!ps.PushLiteral(r))
2224*ccdc9c3eSSadaf Ebrahimi         return NULL;
2225*ccdc9c3eSSadaf Ebrahimi     }
2226*ccdc9c3eSSadaf Ebrahimi     return ps.DoFinish();
2227*ccdc9c3eSSadaf Ebrahimi   }
2228*ccdc9c3eSSadaf Ebrahimi 
2229*ccdc9c3eSSadaf Ebrahimi   StringPiece lastunary = StringPiece();
2230*ccdc9c3eSSadaf Ebrahimi   while (t.size() > 0) {
2231*ccdc9c3eSSadaf Ebrahimi     StringPiece isunary = StringPiece();
2232*ccdc9c3eSSadaf Ebrahimi     switch (t[0]) {
2233*ccdc9c3eSSadaf Ebrahimi       default: {
2234*ccdc9c3eSSadaf Ebrahimi         Rune r;
2235*ccdc9c3eSSadaf Ebrahimi         if (StringPieceToRune(&r, &t, status) < 0)
2236*ccdc9c3eSSadaf Ebrahimi           return NULL;
2237*ccdc9c3eSSadaf Ebrahimi         if (!ps.PushLiteral(r))
2238*ccdc9c3eSSadaf Ebrahimi           return NULL;
2239*ccdc9c3eSSadaf Ebrahimi         break;
2240*ccdc9c3eSSadaf Ebrahimi       }
2241*ccdc9c3eSSadaf Ebrahimi 
2242*ccdc9c3eSSadaf Ebrahimi       case '(':
2243*ccdc9c3eSSadaf Ebrahimi         // "(?" introduces Perl escape.
2244*ccdc9c3eSSadaf Ebrahimi         if ((ps.flags() & PerlX) && (t.size() >= 2 && t[1] == '?')) {
2245*ccdc9c3eSSadaf Ebrahimi           // Flag changes and non-capturing groups.
2246*ccdc9c3eSSadaf Ebrahimi           if (!ps.ParsePerlFlags(&t))
2247*ccdc9c3eSSadaf Ebrahimi             return NULL;
2248*ccdc9c3eSSadaf Ebrahimi           break;
2249*ccdc9c3eSSadaf Ebrahimi         }
2250*ccdc9c3eSSadaf Ebrahimi         if (ps.flags() & NeverCapture) {
2251*ccdc9c3eSSadaf Ebrahimi           if (!ps.DoLeftParenNoCapture())
2252*ccdc9c3eSSadaf Ebrahimi             return NULL;
2253*ccdc9c3eSSadaf Ebrahimi         } else {
2254*ccdc9c3eSSadaf Ebrahimi           if (!ps.DoLeftParen(StringPiece()))
2255*ccdc9c3eSSadaf Ebrahimi             return NULL;
2256*ccdc9c3eSSadaf Ebrahimi         }
2257*ccdc9c3eSSadaf Ebrahimi         t.remove_prefix(1);  // '('
2258*ccdc9c3eSSadaf Ebrahimi         break;
2259*ccdc9c3eSSadaf Ebrahimi 
2260*ccdc9c3eSSadaf Ebrahimi       case '|':
2261*ccdc9c3eSSadaf Ebrahimi         if (!ps.DoVerticalBar())
2262*ccdc9c3eSSadaf Ebrahimi           return NULL;
2263*ccdc9c3eSSadaf Ebrahimi         t.remove_prefix(1);  // '|'
2264*ccdc9c3eSSadaf Ebrahimi         break;
2265*ccdc9c3eSSadaf Ebrahimi 
2266*ccdc9c3eSSadaf Ebrahimi       case ')':
2267*ccdc9c3eSSadaf Ebrahimi         if (!ps.DoRightParen())
2268*ccdc9c3eSSadaf Ebrahimi           return NULL;
2269*ccdc9c3eSSadaf Ebrahimi         t.remove_prefix(1);  // ')'
2270*ccdc9c3eSSadaf Ebrahimi         break;
2271*ccdc9c3eSSadaf Ebrahimi 
2272*ccdc9c3eSSadaf Ebrahimi       case '^':  // Beginning of line.
2273*ccdc9c3eSSadaf Ebrahimi         if (!ps.PushCarat())
2274*ccdc9c3eSSadaf Ebrahimi           return NULL;
2275*ccdc9c3eSSadaf Ebrahimi         t.remove_prefix(1);  // '^'
2276*ccdc9c3eSSadaf Ebrahimi         break;
2277*ccdc9c3eSSadaf Ebrahimi 
2278*ccdc9c3eSSadaf Ebrahimi       case '$':  // End of line.
2279*ccdc9c3eSSadaf Ebrahimi         if (!ps.PushDollar())
2280*ccdc9c3eSSadaf Ebrahimi           return NULL;
2281*ccdc9c3eSSadaf Ebrahimi         t.remove_prefix(1);  // '$'
2282*ccdc9c3eSSadaf Ebrahimi         break;
2283*ccdc9c3eSSadaf Ebrahimi 
2284*ccdc9c3eSSadaf Ebrahimi       case '.':  // Any character (possibly except newline).
2285*ccdc9c3eSSadaf Ebrahimi         if (!ps.PushDot())
2286*ccdc9c3eSSadaf Ebrahimi           return NULL;
2287*ccdc9c3eSSadaf Ebrahimi         t.remove_prefix(1);  // '.'
2288*ccdc9c3eSSadaf Ebrahimi         break;
2289*ccdc9c3eSSadaf Ebrahimi 
2290*ccdc9c3eSSadaf Ebrahimi       case '[': {  // Character class.
2291*ccdc9c3eSSadaf Ebrahimi         Regexp* re;
2292*ccdc9c3eSSadaf Ebrahimi         if (!ps.ParseCharClass(&t, &re, status))
2293*ccdc9c3eSSadaf Ebrahimi           return NULL;
2294*ccdc9c3eSSadaf Ebrahimi         if (!ps.PushRegexp(re))
2295*ccdc9c3eSSadaf Ebrahimi           return NULL;
2296*ccdc9c3eSSadaf Ebrahimi         break;
2297*ccdc9c3eSSadaf Ebrahimi       }
2298*ccdc9c3eSSadaf Ebrahimi 
2299*ccdc9c3eSSadaf Ebrahimi       case '*': {  // Zero or more.
2300*ccdc9c3eSSadaf Ebrahimi         RegexpOp op;
2301*ccdc9c3eSSadaf Ebrahimi         op = kRegexpStar;
2302*ccdc9c3eSSadaf Ebrahimi         goto Rep;
2303*ccdc9c3eSSadaf Ebrahimi       case '+':  // One or more.
2304*ccdc9c3eSSadaf Ebrahimi         op = kRegexpPlus;
2305*ccdc9c3eSSadaf Ebrahimi         goto Rep;
2306*ccdc9c3eSSadaf Ebrahimi       case '?':  // Zero or one.
2307*ccdc9c3eSSadaf Ebrahimi         op = kRegexpQuest;
2308*ccdc9c3eSSadaf Ebrahimi         goto Rep;
2309*ccdc9c3eSSadaf Ebrahimi       Rep:
2310*ccdc9c3eSSadaf Ebrahimi         StringPiece opstr = t;
2311*ccdc9c3eSSadaf Ebrahimi         bool nongreedy = false;
2312*ccdc9c3eSSadaf Ebrahimi         t.remove_prefix(1);  // '*' or '+' or '?'
2313*ccdc9c3eSSadaf Ebrahimi         if (ps.flags() & PerlX) {
2314*ccdc9c3eSSadaf Ebrahimi           if (t.size() > 0 && t[0] == '?') {
2315*ccdc9c3eSSadaf Ebrahimi             nongreedy = true;
2316*ccdc9c3eSSadaf Ebrahimi             t.remove_prefix(1);  // '?'
2317*ccdc9c3eSSadaf Ebrahimi           }
2318*ccdc9c3eSSadaf Ebrahimi           if (lastunary.size() > 0) {
2319*ccdc9c3eSSadaf Ebrahimi             // In Perl it is not allowed to stack repetition operators:
2320*ccdc9c3eSSadaf Ebrahimi             //   a** is a syntax error, not a double-star.
2321*ccdc9c3eSSadaf Ebrahimi             // (and a++ means something else entirely, which we don't support!)
2322*ccdc9c3eSSadaf Ebrahimi             status->set_code(kRegexpRepeatOp);
2323*ccdc9c3eSSadaf Ebrahimi             status->set_error_arg(StringPiece(
2324*ccdc9c3eSSadaf Ebrahimi                 lastunary.begin(),
2325*ccdc9c3eSSadaf Ebrahimi                 static_cast<size_t>(t.begin() - lastunary.begin())));
2326*ccdc9c3eSSadaf Ebrahimi             return NULL;
2327*ccdc9c3eSSadaf Ebrahimi           }
2328*ccdc9c3eSSadaf Ebrahimi         }
2329*ccdc9c3eSSadaf Ebrahimi         opstr = StringPiece(opstr.data(),
2330*ccdc9c3eSSadaf Ebrahimi                             static_cast<size_t>(t.data() - opstr.data()));
2331*ccdc9c3eSSadaf Ebrahimi         if (!ps.PushRepeatOp(op, opstr, nongreedy))
2332*ccdc9c3eSSadaf Ebrahimi           return NULL;
2333*ccdc9c3eSSadaf Ebrahimi         isunary = opstr;
2334*ccdc9c3eSSadaf Ebrahimi         break;
2335*ccdc9c3eSSadaf Ebrahimi       }
2336*ccdc9c3eSSadaf Ebrahimi 
2337*ccdc9c3eSSadaf Ebrahimi       case '{': {  // Counted repetition.
2338*ccdc9c3eSSadaf Ebrahimi         int lo, hi;
2339*ccdc9c3eSSadaf Ebrahimi         StringPiece opstr = t;
2340*ccdc9c3eSSadaf Ebrahimi         if (!MaybeParseRepetition(&t, &lo, &hi)) {
2341*ccdc9c3eSSadaf Ebrahimi           // Treat like a literal.
2342*ccdc9c3eSSadaf Ebrahimi           if (!ps.PushLiteral('{'))
2343*ccdc9c3eSSadaf Ebrahimi             return NULL;
2344*ccdc9c3eSSadaf Ebrahimi           t.remove_prefix(1);  // '{'
2345*ccdc9c3eSSadaf Ebrahimi           break;
2346*ccdc9c3eSSadaf Ebrahimi         }
2347*ccdc9c3eSSadaf Ebrahimi         bool nongreedy = false;
2348*ccdc9c3eSSadaf Ebrahimi         if (ps.flags() & PerlX) {
2349*ccdc9c3eSSadaf Ebrahimi           if (t.size() > 0 && t[0] == '?') {
2350*ccdc9c3eSSadaf Ebrahimi             nongreedy = true;
2351*ccdc9c3eSSadaf Ebrahimi             t.remove_prefix(1);  // '?'
2352*ccdc9c3eSSadaf Ebrahimi           }
2353*ccdc9c3eSSadaf Ebrahimi           if (lastunary.size() > 0) {
2354*ccdc9c3eSSadaf Ebrahimi             // Not allowed to stack repetition operators.
2355*ccdc9c3eSSadaf Ebrahimi             status->set_code(kRegexpRepeatOp);
2356*ccdc9c3eSSadaf Ebrahimi             status->set_error_arg(StringPiece(
2357*ccdc9c3eSSadaf Ebrahimi                 lastunary.begin(),
2358*ccdc9c3eSSadaf Ebrahimi                 static_cast<size_t>(t.begin() - lastunary.begin())));
2359*ccdc9c3eSSadaf Ebrahimi             return NULL;
2360*ccdc9c3eSSadaf Ebrahimi           }
2361*ccdc9c3eSSadaf Ebrahimi         }
2362*ccdc9c3eSSadaf Ebrahimi         opstr = StringPiece(opstr.data(),
2363*ccdc9c3eSSadaf Ebrahimi                             static_cast<size_t>(t.data() - opstr.data()));
2364*ccdc9c3eSSadaf Ebrahimi         if (!ps.PushRepetition(lo, hi, opstr, nongreedy))
2365*ccdc9c3eSSadaf Ebrahimi           return NULL;
2366*ccdc9c3eSSadaf Ebrahimi         isunary = opstr;
2367*ccdc9c3eSSadaf Ebrahimi         break;
2368*ccdc9c3eSSadaf Ebrahimi       }
2369*ccdc9c3eSSadaf Ebrahimi 
2370*ccdc9c3eSSadaf Ebrahimi       case '\\': {  // Escaped character or Perl sequence.
2371*ccdc9c3eSSadaf Ebrahimi         // \b and \B: word boundary or not
2372*ccdc9c3eSSadaf Ebrahimi         if ((ps.flags() & Regexp::PerlB) &&
2373*ccdc9c3eSSadaf Ebrahimi             t.size() >= 2 && (t[1] == 'b' || t[1] == 'B')) {
2374*ccdc9c3eSSadaf Ebrahimi           if (!ps.PushWordBoundary(t[1] == 'b'))
2375*ccdc9c3eSSadaf Ebrahimi             return NULL;
2376*ccdc9c3eSSadaf Ebrahimi           t.remove_prefix(2);  // '\\', 'b'
2377*ccdc9c3eSSadaf Ebrahimi           break;
2378*ccdc9c3eSSadaf Ebrahimi         }
2379*ccdc9c3eSSadaf Ebrahimi 
2380*ccdc9c3eSSadaf Ebrahimi         if ((ps.flags() & Regexp::PerlX) && t.size() >= 2) {
2381*ccdc9c3eSSadaf Ebrahimi           if (t[1] == 'A') {
2382*ccdc9c3eSSadaf Ebrahimi             if (!ps.PushSimpleOp(kRegexpBeginText))
2383*ccdc9c3eSSadaf Ebrahimi               return NULL;
2384*ccdc9c3eSSadaf Ebrahimi             t.remove_prefix(2);  // '\\', 'A'
2385*ccdc9c3eSSadaf Ebrahimi             break;
2386*ccdc9c3eSSadaf Ebrahimi           }
2387*ccdc9c3eSSadaf Ebrahimi           if (t[1] == 'z') {
2388*ccdc9c3eSSadaf Ebrahimi             if (!ps.PushSimpleOp(kRegexpEndText))
2389*ccdc9c3eSSadaf Ebrahimi               return NULL;
2390*ccdc9c3eSSadaf Ebrahimi             t.remove_prefix(2);  // '\\', 'z'
2391*ccdc9c3eSSadaf Ebrahimi             break;
2392*ccdc9c3eSSadaf Ebrahimi           }
2393*ccdc9c3eSSadaf Ebrahimi           // Do not recognize \Z, because this library can't
2394*ccdc9c3eSSadaf Ebrahimi           // implement the exact Perl/PCRE semantics.
2395*ccdc9c3eSSadaf Ebrahimi           // (This library treats "(?-m)$" as \z, even though
2396*ccdc9c3eSSadaf Ebrahimi           // in Perl and PCRE it is equivalent to \Z.)
2397*ccdc9c3eSSadaf Ebrahimi 
2398*ccdc9c3eSSadaf Ebrahimi           if (t[1] == 'C') {  // \C: any byte [sic]
2399*ccdc9c3eSSadaf Ebrahimi             if (!ps.PushSimpleOp(kRegexpAnyByte))
2400*ccdc9c3eSSadaf Ebrahimi               return NULL;
2401*ccdc9c3eSSadaf Ebrahimi             t.remove_prefix(2);  // '\\', 'C'
2402*ccdc9c3eSSadaf Ebrahimi             break;
2403*ccdc9c3eSSadaf Ebrahimi           }
2404*ccdc9c3eSSadaf Ebrahimi 
2405*ccdc9c3eSSadaf Ebrahimi           if (t[1] == 'Q') {  // \Q ... \E: the ... is always literals
2406*ccdc9c3eSSadaf Ebrahimi             t.remove_prefix(2);  // '\\', 'Q'
2407*ccdc9c3eSSadaf Ebrahimi             while (t.size() > 0) {
2408*ccdc9c3eSSadaf Ebrahimi               if (t.size() >= 2 && t[0] == '\\' && t[1] == 'E') {
2409*ccdc9c3eSSadaf Ebrahimi                 t.remove_prefix(2);  // '\\', 'E'
2410*ccdc9c3eSSadaf Ebrahimi                 break;
2411*ccdc9c3eSSadaf Ebrahimi               }
2412*ccdc9c3eSSadaf Ebrahimi               Rune r;
2413*ccdc9c3eSSadaf Ebrahimi               if (StringPieceToRune(&r, &t, status) < 0)
2414*ccdc9c3eSSadaf Ebrahimi                 return NULL;
2415*ccdc9c3eSSadaf Ebrahimi               if (!ps.PushLiteral(r))
2416*ccdc9c3eSSadaf Ebrahimi                 return NULL;
2417*ccdc9c3eSSadaf Ebrahimi             }
2418*ccdc9c3eSSadaf Ebrahimi             break;
2419*ccdc9c3eSSadaf Ebrahimi           }
2420*ccdc9c3eSSadaf Ebrahimi         }
2421*ccdc9c3eSSadaf Ebrahimi 
2422*ccdc9c3eSSadaf Ebrahimi         if (t.size() >= 2 && (t[1] == 'p' || t[1] == 'P')) {
2423*ccdc9c3eSSadaf Ebrahimi           Regexp* re = new Regexp(kRegexpCharClass, ps.flags() & ~FoldCase);
2424*ccdc9c3eSSadaf Ebrahimi           re->ccb_ = new CharClassBuilder;
2425*ccdc9c3eSSadaf Ebrahimi           switch (ParseUnicodeGroup(&t, ps.flags(), re->ccb_, status)) {
2426*ccdc9c3eSSadaf Ebrahimi             case kParseOk:
2427*ccdc9c3eSSadaf Ebrahimi               if (!ps.PushRegexp(re))
2428*ccdc9c3eSSadaf Ebrahimi                 return NULL;
2429*ccdc9c3eSSadaf Ebrahimi               goto Break2;
2430*ccdc9c3eSSadaf Ebrahimi             case kParseError:
2431*ccdc9c3eSSadaf Ebrahimi               re->Decref();
2432*ccdc9c3eSSadaf Ebrahimi               return NULL;
2433*ccdc9c3eSSadaf Ebrahimi             case kParseNothing:
2434*ccdc9c3eSSadaf Ebrahimi               re->Decref();
2435*ccdc9c3eSSadaf Ebrahimi               break;
2436*ccdc9c3eSSadaf Ebrahimi           }
2437*ccdc9c3eSSadaf Ebrahimi         }
2438*ccdc9c3eSSadaf Ebrahimi 
2439*ccdc9c3eSSadaf Ebrahimi         const UGroup *g = MaybeParsePerlCCEscape(&t, ps.flags());
2440*ccdc9c3eSSadaf Ebrahimi         if (g != NULL) {
2441*ccdc9c3eSSadaf Ebrahimi           Regexp* re = new Regexp(kRegexpCharClass, ps.flags() & ~FoldCase);
2442*ccdc9c3eSSadaf Ebrahimi           re->ccb_ = new CharClassBuilder;
2443*ccdc9c3eSSadaf Ebrahimi           AddUGroup(re->ccb_, g, g->sign, ps.flags());
2444*ccdc9c3eSSadaf Ebrahimi           if (!ps.PushRegexp(re))
2445*ccdc9c3eSSadaf Ebrahimi             return NULL;
2446*ccdc9c3eSSadaf Ebrahimi           break;
2447*ccdc9c3eSSadaf Ebrahimi         }
2448*ccdc9c3eSSadaf Ebrahimi 
2449*ccdc9c3eSSadaf Ebrahimi         Rune r;
2450*ccdc9c3eSSadaf Ebrahimi         if (!ParseEscape(&t, &r, status, ps.rune_max()))
2451*ccdc9c3eSSadaf Ebrahimi           return NULL;
2452*ccdc9c3eSSadaf Ebrahimi         if (!ps.PushLiteral(r))
2453*ccdc9c3eSSadaf Ebrahimi           return NULL;
2454*ccdc9c3eSSadaf Ebrahimi         break;
2455*ccdc9c3eSSadaf Ebrahimi       }
2456*ccdc9c3eSSadaf Ebrahimi     }
2457*ccdc9c3eSSadaf Ebrahimi   Break2:
2458*ccdc9c3eSSadaf Ebrahimi     lastunary = isunary;
2459*ccdc9c3eSSadaf Ebrahimi   }
2460*ccdc9c3eSSadaf Ebrahimi   return ps.DoFinish();
2461*ccdc9c3eSSadaf Ebrahimi }
2462*ccdc9c3eSSadaf Ebrahimi 
2463*ccdc9c3eSSadaf Ebrahimi }  // namespace re2
2464