fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / external / icu / icu.changeset_36801.patch.1
blob4a926d9126ed51c547bd03c74973a441a703ae8d
1 diff -ru icu/source/common/unicode/utypes.h icu/source/common/unicode/utypes.h
2 --- icu/source/common/unicode/utypes.h  2014-10-03 18:11:02.000000000 +0200
3 +++ icu/source/common/unicode/utypes.h  2015-04-10 15:28:06.149993491 +0200
4 @@ -647,6 +647,7 @@
5      U_REGEX_STACK_OVERFLOW,               /**< Regular expression backtrack stack overflow.       */
6      U_REGEX_TIME_OUT,                     /**< Maximum allowed match time exceeded                */
7      U_REGEX_STOPPED_BY_CALLER,            /**< Matching operation aborted by user callback fn.    */
8 +    U_REGEX_PATTERN_TOO_BIG,              /**< Pattern exceeds limits on size or complexity.   @draft ICU 55   */
9      U_REGEX_ERROR_LIMIT,                  /**< This must always be the last value to indicate the limit for regexp errors */
11      /*
12 diff -ru icu/source/common/utypes.c icu/source/common/utypes.c
13 --- icu/source/common/utypes.c  2014-10-03 18:11:14.000000000 +0200
14 +++ icu/source/common/utypes.c  2015-04-10 15:28:06.149993491 +0200
15 @@ -1,7 +1,7 @@
16  /*
17  ******************************************************************************
18  *
19 -*   Copyright (C) 1997-2011, International Business Machines
20 +*   Copyright (C) 1997-2014, International Business Machines
21  *   Corporation and others.  All Rights Reserved.
22  *
23  ******************************************************************************
24 @@ -165,7 +165,8 @@
25      "U_REGEX_INVALID_RANGE",
26      "U_REGEX_STACK_OVERFLOW",
27      "U_REGEX_TIME_OUT",
28 -    "U_REGEX_STOPPED_BY_CALLER"
29 +    "U_REGEX_STOPPED_BY_CALLER",
30 +    "U_REGEX_PATTERN_TOO_BIG"
31  };
33  static const char * const
34 diff -ru icu/source/i18n/regexcmp.cpp icu/source/i18n/regexcmp.cpp
35 --- icu/source/i18n/regexcmp.cpp        2015-04-10 15:27:31.369772849 +0200
36 +++ icu/source/i18n/regexcmp.cpp        2015-04-10 15:28:06.152993511 +0200
37 @@ -301,7 +301,7 @@
38      //   present in the saved state:  the input string position (int64_t) and
39      //   the position in the compiled pattern.
40      //
41 -    fRXPat->fFrameSize+=RESTACKFRAME_HDRCOUNT;
42 +    allocateStackData(RESTACKFRAME_HDRCOUNT);
44      //
45      // Optimization pass 1: NOPs, back-references, and case-folding
46 @@ -367,9 +367,9 @@
47          //                    the start of an ( grouping.
48          //4   NOP             Resreved, will be replaced by a save if there are
49          //                    OR | operators at the top level
50 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_STATE_SAVE, 2), *fStatus);
51 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_JMP,  3), *fStatus);
52 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_FAIL, 0), *fStatus);
53 +        appendOp(URX_STATE_SAVE, 2);
54 +        appendOp(URX_JMP,  3);
55 +        appendOp(URX_FAIL, 0);
57          // Standard open nonCapture paren action emits the two NOPs and
58          //   sets up the paren stack frame.
59 @@ -392,7 +392,7 @@
60          }
62          // add the END operation to the compiled pattern.
63 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_END, 0), *fStatus);
64 +        appendOp(URX_END, 0);
66          // Terminate the pattern compilation state machine.
67          returnVal = FALSE;
68 @@ -414,14 +414,13 @@
69              int32_t savePosition = fParenStack.popi();
70              int32_t op = (int32_t)fRXPat->fCompiledPat->elementAti(savePosition);
71              U_ASSERT(URX_TYPE(op) == URX_NOP);  // original contents of reserved location
72 -            op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+1);
73 +            op = buildOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+1);
74              fRXPat->fCompiledPat->setElementAt(op, savePosition);
76              // Append an JMP operation into the compiled pattern.  The operand for
77              //  the JMP will eventually be the location following the ')' for the
78              //  group.  This will be patched in later, when the ')' is encountered.
79 -            op = URX_BUILD(URX_JMP, 0);
80 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
81 +            appendOp(URX_JMP, 0);
83              // Push the position of the newly added JMP op onto the parentheses stack.
84              // This registers if for fixup when this block's close paren is encountered.
85 @@ -430,7 +429,7 @@
86              // Append a NOP to the compiled pattern.  This is the slot reserved
87              //   for a SAVE in the event that there is yet another '|' following
88              //   this one.
89 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
90 +            appendOp(URX_NOP, 0);
91              fParenStack.push(fRXPat->fCompiledPat->size()-1, *fStatus);
92          }
93          break;
94 @@ -456,12 +455,10 @@
95          //      END_CAPTURE is encountered.
96          {
97              fixLiterals();
98 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
99 -            int32_t  varsLoc    = fRXPat->fFrameSize;    // Reserve three slots in match stack frame.
100 -            fRXPat->fFrameSize += 3;
101 -            int32_t  cop        = URX_BUILD(URX_START_CAPTURE, varsLoc);
102 -            fRXPat->fCompiledPat->addElement(cop, *fStatus);
103 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
104 +            appendOp(URX_NOP, 0);
105 +            int32_t  varsLoc = allocateStackData(3);    // Reserve three slots in match stack frame.
106 +            appendOp(URX_START_CAPTURE, varsLoc);
107 +            appendOp(URX_NOP, 0);
109              // On the Parentheses stack, start a new frame and add the postions
110              //   of the two NOPs.  Depending on what follows in the pattern, the
111 @@ -486,8 +483,8 @@
112          //             is an '|' alternation within the parens.
113          {
114              fixLiterals();
115 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
116 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
117 +            appendOp(URX_NOP, 0);
118 +            appendOp(URX_NOP, 0);
120              // On the Parentheses stack, start a new frame and add the postions
121              //   of the two NOPs.
122 @@ -509,12 +506,10 @@
123          //             is an '|' alternation within the parens.
124          {
125              fixLiterals();
126 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
127 -            int32_t  varLoc    = fRXPat->fDataSize;    // Reserve a data location for saving the
128 -            fRXPat->fDataSize += 1;                    //  state stack ptr.
129 -            int32_t  stoOp     = URX_BUILD(URX_STO_SP, varLoc);
130 -            fRXPat->fCompiledPat->addElement(stoOp, *fStatus);
131 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
132 +            appendOp(URX_NOP, 0);
133 +            int32_t  varLoc = allocateData(1);    // Reserve a data location for saving the state stack ptr.
134 +            appendOp(URX_STO_SP, varLoc);
135 +            appendOp(URX_NOP, 0);
137              // On the Parentheses stack, start a new frame and add the postions
138              //   of the two NOPs.  Depending on what follows in the pattern, the
139 @@ -557,26 +552,14 @@
140          //  Two data slots are reserved, for saving the stack ptr and the input position.
141          {
142              fixLiterals();
143 -            int32_t dataLoc = fRXPat->fDataSize;
144 -            fRXPat->fDataSize += 2;
145 -            int32_t op = URX_BUILD(URX_LA_START, dataLoc);
146 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
148 -            op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+ 2);
149 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
151 -            op = URX_BUILD(URX_JMP, fRXPat->fCompiledPat->size()+ 3);
152 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
154 -            op = URX_BUILD(URX_LA_END, dataLoc);
155 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
157 -            op = URX_BUILD(URX_BACKTRACK, 0);
158 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
160 -            op = URX_BUILD(URX_NOP, 0);
161 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
162 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
163 +            int32_t dataLoc = allocateData(2);
164 +            appendOp(URX_LA_START, dataLoc);
165 +            appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+ 2);
166 +            appendOp(URX_JMP, fRXPat->fCompiledPat->size()+ 3);
167 +            appendOp(URX_LA_END, dataLoc);
168 +            appendOp(URX_BACKTRACK, 0);
169 +            appendOp(URX_NOP, 0);
170 +            appendOp(URX_NOP, 0);
172              // On the Parentheses stack, start a new frame and add the postions
173              //   of the NOPs.
174 @@ -601,16 +584,10 @@
175          //                                        an alternate (transparent) region.
176          {
177              fixLiterals();
178 -            int32_t dataLoc = fRXPat->fDataSize;
179 -            fRXPat->fDataSize += 2;
180 -            int32_t op = URX_BUILD(URX_LA_START, dataLoc);
181 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
183 -            op = URX_BUILD(URX_STATE_SAVE, 0);    // dest address will be patched later.
184 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
186 -            op = URX_BUILD(URX_NOP, 0);
187 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
188 +            int32_t dataLoc = allocateData(2);
189 +            appendOp(URX_LA_START, dataLoc);
190 +            appendOp(URX_STATE_SAVE, 0);    // dest address will be patched later.
191 +            appendOp(URX_NOP, 0);
193              // On the Parentheses stack, start a new frame and add the postions
194              //   of the StateSave and NOP.
195 @@ -648,23 +625,19 @@
196              fixLiterals();
198              // Allocate data space
199 -            int32_t dataLoc = fRXPat->fDataSize;
200 -            fRXPat->fDataSize += 4;
201 +            int32_t dataLoc = allocateData(4);
203              // Emit URX_LB_START
204 -            int32_t op = URX_BUILD(URX_LB_START, dataLoc);
205 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
206 +            appendOp(URX_LB_START, dataLoc);
208              // Emit URX_LB_CONT
209 -            op = URX_BUILD(URX_LB_CONT, dataLoc);
210 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
211 -            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MinMatchLength.  To be filled later.
212 -            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MaxMatchLength.  To be filled later.
214 -            // Emit the NOP
215 -            op = URX_BUILD(URX_NOP, 0);
216 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
217 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
218 +            appendOp(URX_LB_CONT, dataLoc);
219 +            appendOp(URX_RESERVED_OP, 0);    // MinMatchLength.  To be filled later.
220 +            appendOp(URX_RESERVED_OP, 0);    // MaxMatchLength.  To be filled later.
222 +            // Emit the NOPs
223 +            appendOp(URX_NOP, 0);
224 +            appendOp(URX_NOP, 0);
226              // On the Parentheses stack, start a new frame and add the postions
227              //   of the URX_LB_CONT and the NOP.
228 @@ -704,24 +677,20 @@
229              fixLiterals();
231              // Allocate data space
232 -            int32_t dataLoc = fRXPat->fDataSize;
233 -            fRXPat->fDataSize += 4;
234 +            int32_t dataLoc = allocateData(4);
236              // Emit URX_LB_START
237 -            int32_t op = URX_BUILD(URX_LB_START, dataLoc);
238 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
239 +            appendOp(URX_LB_START, dataLoc);
241              // Emit URX_LBN_CONT
242 -            op = URX_BUILD(URX_LBN_CONT, dataLoc);
243 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
244 -            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MinMatchLength.  To be filled later.
245 -            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // MaxMatchLength.  To be filled later.
246 -            fRXPat->fCompiledPat->addElement(0,  *fStatus);    // Continue Loc.    To be filled later.
248 -            // Emit the NOP
249 -            op = URX_BUILD(URX_NOP, 0);
250 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
251 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
252 +            appendOp(URX_LBN_CONT, dataLoc);
253 +            appendOp(URX_RESERVED_OP, 0);    // MinMatchLength.  To be filled later.
254 +            appendOp(URX_RESERVED_OP, 0);    // MaxMatchLength.  To be filled later.
255 +            appendOp(URX_RESERVED_OP, 0);    // Continue Loc.    To be filled later.
257 +            // Emit the NOPs
258 +            appendOp(URX_NOP, 0);
259 +            appendOp(URX_NOP, 0);
261              // On the Parentheses stack, start a new frame and add the postions
262              //   of the URX_LB_CONT and the NOP.
263 @@ -791,12 +760,9 @@
265                  if (URX_TYPE(repeatedOp) == URX_SETREF) {
266                      // Emit optimized code for [char set]+
267 -                    int32_t loopOpI = URX_BUILD(URX_LOOP_SR_I, URX_VAL(repeatedOp));
268 -                    fRXPat->fCompiledPat->addElement(loopOpI, *fStatus);
269 -                    frameLoc = fRXPat->fFrameSize;
270 -                    fRXPat->fFrameSize++;
271 -                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, frameLoc);
272 -                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);
273 +                    appendOp(URX_LOOP_SR_I, URX_VAL(repeatedOp));
274 +                    frameLoc = allocateStackData(1);
275 +                    appendOp(URX_LOOP_C, frameLoc);
276                      break;
277                  }
279 @@ -804,7 +770,7 @@
280                      URX_TYPE(repeatedOp) == URX_DOTANY_ALL ||
281                      URX_TYPE(repeatedOp) == URX_DOTANY_UNIX) {
282                      // Emit Optimized code for .+ operations.
283 -                    int32_t loopOpI = URX_BUILD(URX_LOOP_DOT_I, 0);
284 +                    int32_t loopOpI = buildOp(URX_LOOP_DOT_I, 0);
285                      if (URX_TYPE(repeatedOp) == URX_DOTANY_ALL) {
286                          // URX_LOOP_DOT_I operand is a flag indicating ". matches any" mode.
287                          loopOpI |= 1;
288 @@ -812,11 +778,9 @@
289                      if (fModeFlags & UREGEX_UNIX_LINES) {
290                          loopOpI |= 2;
291                      }
292 -                    fRXPat->fCompiledPat->addElement(loopOpI, *fStatus);
293 -                    frameLoc = fRXPat->fFrameSize;
294 -                    fRXPat->fFrameSize++;
295 -                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, frameLoc);
296 -                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);
297 +                    appendOp(loopOpI);
298 +                    frameLoc = allocateStackData(1);
299 +                    appendOp(URX_LOOP_C, frameLoc);
300                      break;
301                  }
303 @@ -830,18 +794,15 @@
304                  // Zero length match is possible.
305                  // Emit the code sequence that can handle it.
306                  insertOp(topLoc);
307 -                frameLoc =  fRXPat->fFrameSize;
308 -                fRXPat->fFrameSize++;
309 +                frameLoc = allocateStackData(1);
311 -                int32_t op = URX_BUILD(URX_STO_INP_LOC, frameLoc);
312 +                int32_t op = buildOp(URX_STO_INP_LOC, frameLoc);
313                  fRXPat->fCompiledPat->setElementAt(op, topLoc);
315 -                op = URX_BUILD(URX_JMP_SAV_X, topLoc+1);
316 -                fRXPat->fCompiledPat->addElement(op, *fStatus);
317 +                appendOp(URX_JMP_SAV_X, topLoc+1);
318              } else {
319                  // Simpler code when the repeated body must match something non-empty
320 -                int32_t  jmpOp  = URX_BUILD(URX_JMP_SAV, topLoc);
321 -                fRXPat->fCompiledPat->addElement(jmpOp, *fStatus);
322 +                appendOp(URX_JMP_SAV, topLoc);
323              }
324          }
325          break;
326 @@ -853,8 +814,7 @@
327          //     3.   ...
328          {
329              int32_t topLoc      = blockTopLoc(FALSE);
330 -            int32_t saveStateOp = URX_BUILD(URX_STATE_SAVE, topLoc);
331 -            fRXPat->fCompiledPat->addElement(saveStateOp, *fStatus);
332 +            appendOp(URX_STATE_SAVE, topLoc);
333          }
334          break;
336 @@ -868,7 +828,7 @@
337          // Insert the state save into the compiled pattern, and we're done.
338          {
339              int32_t   saveStateLoc = blockTopLoc(TRUE);
340 -            int32_t   saveStateOp  = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size());
341 +            int32_t   saveStateOp  = buildOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size());
342              fRXPat->fCompiledPat->setElementAt(saveStateOp, saveStateLoc);
343          }
344          break;
345 @@ -887,14 +847,12 @@
346              int32_t  jmp1_loc = blockTopLoc(TRUE);
347              int32_t  jmp2_loc = fRXPat->fCompiledPat->size();
349 -            int32_t  jmp1_op  = URX_BUILD(URX_JMP, jmp2_loc+1);
350 +            int32_t  jmp1_op  = buildOp(URX_JMP, jmp2_loc+1);
351              fRXPat->fCompiledPat->setElementAt(jmp1_op, jmp1_loc);
353 -            int32_t  jmp2_op  = URX_BUILD(URX_JMP, jmp2_loc+2);
354 -            fRXPat->fCompiledPat->addElement(jmp2_op, *fStatus);
355 +            appendOp(URX_JMP, jmp2_loc+2);
357 -            int32_t  save_op  = URX_BUILD(URX_STATE_SAVE, jmp1_loc+1);
358 -            fRXPat->fCompiledPat->addElement(save_op, *fStatus);
359 +            appendOp(URX_STATE_SAVE, jmp1_loc+1);
360          }
361          break;
363 @@ -934,12 +892,10 @@
365                  if (URX_TYPE(repeatedOp) == URX_SETREF) {
366                      // Emit optimized code for a [char set]*
367 -                    int32_t loopOpI = URX_BUILD(URX_LOOP_SR_I, URX_VAL(repeatedOp));
368 +                    int32_t loopOpI = buildOp(URX_LOOP_SR_I, URX_VAL(repeatedOp));
369                      fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc);
370 -                    dataLoc = fRXPat->fFrameSize;
371 -                    fRXPat->fFrameSize++;
372 -                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, dataLoc);
373 -                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);
374 +                    dataLoc = allocateStackData(1);
375 +                    appendOp(URX_LOOP_C, dataLoc);
376                      break;
377                  }
379 @@ -947,7 +903,7 @@
380                      URX_TYPE(repeatedOp) == URX_DOTANY_ALL ||
381                      URX_TYPE(repeatedOp) == URX_DOTANY_UNIX) {
382                      // Emit Optimized code for .* operations.
383 -                    int32_t loopOpI = URX_BUILD(URX_LOOP_DOT_I, 0);
384 +                    int32_t loopOpI = buildOp(URX_LOOP_DOT_I, 0);
385                      if (URX_TYPE(repeatedOp) == URX_DOTANY_ALL) {
386                          // URX_LOOP_DOT_I operand is a flag indicating . matches any mode.
387                          loopOpI |= 1;
388 @@ -956,10 +912,8 @@
389                          loopOpI |= 2;
390                      }
391                      fRXPat->fCompiledPat->setElementAt(loopOpI, topLoc);
392 -                    dataLoc = fRXPat->fFrameSize;
393 -                    fRXPat->fFrameSize++;
394 -                    int32_t loopOpC = URX_BUILD(URX_LOOP_C, dataLoc);
395 -                    fRXPat->fCompiledPat->addElement(loopOpC, *fStatus);
396 +                    dataLoc = allocateStackData(1);
397 +                    appendOp(URX_LOOP_C, dataLoc);
398                      break;
399                  }
400              }
401 @@ -968,30 +922,29 @@
402              // The optimizations did not apply.
404              int32_t   saveStateLoc = blockTopLoc(TRUE);
405 -            int32_t   jmpOp        = URX_BUILD(URX_JMP_SAV, saveStateLoc+1);
406 +            int32_t   jmpOp        = buildOp(URX_JMP_SAV, saveStateLoc+1);
408              // Check for minimum match length of zero, which requires
409              //    extra loop-breaking code.
410              if (minMatchLength(saveStateLoc, fRXPat->fCompiledPat->size()-1) == 0) {
411                  insertOp(saveStateLoc);
412 -                dataLoc =  fRXPat->fFrameSize;
413 -                fRXPat->fFrameSize++;
414 +                dataLoc = allocateStackData(1);
416 -                int32_t op = URX_BUILD(URX_STO_INP_LOC, dataLoc);
417 +                int32_t op = buildOp(URX_STO_INP_LOC, dataLoc);
418                  fRXPat->fCompiledPat->setElementAt(op, saveStateLoc+1);
419 -                jmpOp      = URX_BUILD(URX_JMP_SAV_X, saveStateLoc+2);
420 +                jmpOp      = buildOp(URX_JMP_SAV_X, saveStateLoc+2);
421              }
423              // Locate the position in the compiled pattern where the match will continue
424              //   after completing the *.   (4 or 5 in the comment above)
425              int32_t continueLoc = fRXPat->fCompiledPat->size()+1;
427 -            // Put together the save state op store it into the compiled code.
428 -            int32_t saveStateOp = URX_BUILD(URX_STATE_SAVE, continueLoc);
429 +            // Put together the save state op and store it into the compiled code.
430 +            int32_t saveStateOp = buildOp(URX_STATE_SAVE, continueLoc);
431              fRXPat->fCompiledPat->setElementAt(saveStateOp, saveStateLoc);
433              // Append the URX_JMP_SAV or URX_JMPX operation to the compiled pattern.
434 -            fRXPat->fCompiledPat->addElement(jmpOp, *fStatus);
435 +            appendOp(jmpOp);
436          }
437          break;
439 @@ -1005,10 +958,9 @@
440          {
441              int32_t     jmpLoc  = blockTopLoc(TRUE);                   // loc  1.
442              int32_t     saveLoc = fRXPat->fCompiledPat->size();        // loc  3.
443 -            int32_t     jmpOp   = URX_BUILD(URX_JMP, saveLoc);
444 -            int32_t     stateSaveOp = URX_BUILD(URX_STATE_SAVE, jmpLoc+1);
445 +            int32_t     jmpOp   = buildOp(URX_JMP, saveLoc);
446              fRXPat->fCompiledPat->setElementAt(jmpOp, jmpLoc);
447 -            fRXPat->fCompiledPat->addElement(stateSaveOp, *fStatus);
448 +            appendOp(URX_STATE_SAVE, jmpLoc+1);
449          }
450          break;
452 @@ -1077,9 +1029,9 @@
454              // First the STO_SP before the start of the loop
455              insertOp(topLoc);
456 -            int32_t  varLoc    = fRXPat->fDataSize;    // Reserve a data location for saving the
457 -            fRXPat->fDataSize += 1;                    //  state stack ptr.
458 -            int32_t  op        = URX_BUILD(URX_STO_SP, varLoc);
460 +            int32_t  varLoc = allocateData(1);   // Reserve a data location for saving the
461 +            int32_t  op     = buildOp(URX_STO_SP, varLoc);
462              fRXPat->fCompiledPat->setElementAt(op, topLoc);
464              int32_t loopOp = (int32_t)fRXPat->fCompiledPat->popi();
465 @@ -1088,8 +1040,7 @@
466              fRXPat->fCompiledPat->push(loopOp, *fStatus);
468              // Then the LD_SP after the end of the loop
469 -            op = URX_BUILD(URX_LD_SP, varLoc);
470 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
471 +            appendOp(URX_LD_SP, varLoc);
472          }
474          break;
475 @@ -1125,55 +1076,49 @@
476          // scanned a ".",  match any single character.
477          {
478              fixLiterals(FALSE);
479 -            int32_t   op;
480              if (fModeFlags & UREGEX_DOTALL) {
481 -                op = URX_BUILD(URX_DOTANY_ALL, 0);
482 +                appendOp(URX_DOTANY_ALL, 0);
483              } else if (fModeFlags & UREGEX_UNIX_LINES) {
484 -                op = URX_BUILD(URX_DOTANY_UNIX, 0);
485 +                appendOp(URX_DOTANY_UNIX, 0);
486              } else {
487 -                op = URX_BUILD(URX_DOTANY, 0);
488 +                appendOp(URX_DOTANY, 0);
489              }
490 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
491          }
492          break;
494      case doCaret:
495          {
496              fixLiterals(FALSE);
497 -            int32_t op = 0;
498              if (       (fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {
499 -                op = URX_CARET;
500 +                appendOp(URX_CARET, 0);
501              } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {
502 -                op = URX_CARET_M;
503 +                appendOp(URX_CARET_M, 0);
504              } else if ((fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {
505 -                op = URX_CARET;   // Only testing true start of input.
506 +                appendOp(URX_CARET, 0);   // Only testing true start of input.
507              } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {
508 -                op = URX_CARET_M_UNIX;
509 +                appendOp(URX_CARET_M_UNIX, 0);
510              }
511 -            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus);
512          }
513          break;
515      case doDollar:
516          {
517              fixLiterals(FALSE);
518 -            int32_t op = 0;
519              if (       (fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {
520 -                op = URX_DOLLAR;
521 +                appendOp(URX_DOLLAR, 0);
522              } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) == 0) {
523 -                op = URX_DOLLAR_M;
524 +                appendOp(URX_DOLLAR_M, 0);
525              } else if ((fModeFlags & UREGEX_MULTILINE) == 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {
526 -                op = URX_DOLLAR_D;
527 +                appendOp(URX_DOLLAR_D, 0);
528              } else if ((fModeFlags & UREGEX_MULTILINE) != 0 && (fModeFlags & UREGEX_UNIX_LINES) != 0) {
529 -                op = URX_DOLLAR_MD;
530 +                appendOp(URX_DOLLAR_MD, 0);
531              }
532 -            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus);
533          }
534          break;
536      case doBackslashA:
537          fixLiterals(FALSE);
538 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_CARET, 0), *fStatus);
539 +        appendOp(URX_CARET, 0);
540          break;
542      case doBackslashB:
543 @@ -1185,7 +1130,7 @@
544              #endif
545              fixLiterals(FALSE);
546              int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B;
547 -            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 1), *fStatus);
548 +            appendOp(op, 1);
549          }
550          break;
552 @@ -1198,63 +1143,59 @@
553              #endif
554              fixLiterals(FALSE);
555              int32_t op = (fModeFlags & UREGEX_UWORD)? URX_BACKSLASH_BU : URX_BACKSLASH_B;
556 -            fRXPat->fCompiledPat->addElement(URX_BUILD(op, 0), *fStatus);
557 +            appendOp(op, 0);
558          }
559          break;
561      case doBackslashD:
562          fixLiterals(FALSE);
563 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_D, 1), *fStatus);
564 +        appendOp(URX_BACKSLASH_D, 1);
565          break;
567      case doBackslashd:
568          fixLiterals(FALSE);
569 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_D, 0), *fStatus);
570 +        appendOp(URX_BACKSLASH_D, 0);
571          break;
573      case doBackslashG:
574          fixLiterals(FALSE);
575 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_G, 0), *fStatus);
576 +        appendOp(URX_BACKSLASH_G, 0);
577          break;
579      case doBackslashS:
580          fixLiterals(FALSE);
581 -        fRXPat->fCompiledPat->addElement(
582 -            URX_BUILD(URX_STAT_SETREF_N, URX_ISSPACE_SET), *fStatus);
583 +        appendOp(URX_STAT_SETREF_N, URX_ISSPACE_SET);
584          break;
586      case doBackslashs:
587          fixLiterals(FALSE);
588 -        fRXPat->fCompiledPat->addElement(
589 -            URX_BUILD(URX_STATIC_SETREF, URX_ISSPACE_SET), *fStatus);
590 +        appendOp(URX_STATIC_SETREF, URX_ISSPACE_SET);
591          break;
593      case doBackslashW:
594          fixLiterals(FALSE);
595 -        fRXPat->fCompiledPat->addElement(
596 -            URX_BUILD(URX_STAT_SETREF_N, URX_ISWORD_SET), *fStatus);
597 +        appendOp(URX_STAT_SETREF_N, URX_ISWORD_SET);
598          break;
600      case doBackslashw:
601          fixLiterals(FALSE);
602 -        fRXPat->fCompiledPat->addElement(
603 -            URX_BUILD(URX_STATIC_SETREF, URX_ISWORD_SET), *fStatus);
604 +        appendOp(URX_STATIC_SETREF, URX_ISWORD_SET);
605          break;
607      case doBackslashX:
608          fixLiterals(FALSE);
609 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_X, 0), *fStatus);
610 +        appendOp(URX_BACKSLASH_X, 0);
611          break;
614      case doBackslashZ:
615          fixLiterals(FALSE);
616 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_DOLLAR, 0), *fStatus);
617 +        appendOp(URX_DOLLAR, 0);
618          break;
620      case doBackslashz:
621          fixLiterals(FALSE);
622 -        fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKSLASH_Z, 0), *fStatus);
623 +        appendOp(URX_BACKSLASH_Z, 0);
624          break;
626      case doEscapeError:
627 @@ -1314,13 +1255,11 @@
628              U_ASSERT(groupNum > 0);  // Shouldn't happen.  '\0' begins an octal escape sequence,
629                                       //    and shouldn't enter this code path at all.
630              fixLiterals(FALSE);
631 -            int32_t  op;
632              if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
633 -                op = URX_BUILD(URX_BACKREF_I, groupNum);
634 +                appendOp(URX_BACKREF_I, groupNum);
635              } else {
636 -                op = URX_BUILD(URX_BACKREF, groupNum);
637 +                appendOp(URX_BACKREF, groupNum);
638              }
639 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
640          }
641          break;
643 @@ -1341,22 +1280,18 @@
644          {
645              // Emit the STO_SP
646              int32_t   topLoc = blockTopLoc(TRUE);
647 -            int32_t   stoLoc = fRXPat->fDataSize;
648 -            fRXPat->fDataSize++;       // Reserve the data location for storing save stack ptr.
649 -            int32_t   op     = URX_BUILD(URX_STO_SP, stoLoc);
650 +            int32_t   stoLoc = allocateData(1);  // Reserve the data location for storing save stack ptr.
651 +            int32_t   op     = buildOp(URX_STO_SP, stoLoc);
652              fRXPat->fCompiledPat->setElementAt(op, topLoc);
654              // Emit the STATE_SAVE
655 -            op = URX_BUILD(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+2);
656 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
657 +            appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+2);
659              // Emit the JMP
660 -            op = URX_BUILD(URX_JMP, topLoc+1);
661 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
662 +            appendOp(URX_JMP, topLoc+1);
664              // Emit the LD_SP
665 -            op = URX_BUILD(URX_LD_SP, stoLoc);
666 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
667 +            appendOp(URX_LD_SP, stoLoc);
668          }
669          break;
671 @@ -1376,23 +1311,20 @@
672              insertOp(topLoc);
674              // emit   STO_SP     loc
675 -            int32_t   stoLoc = fRXPat->fDataSize;
676 -            fRXPat->fDataSize++;       // Reserve the data location for storing save stack ptr.
677 -            int32_t   op     = URX_BUILD(URX_STO_SP, stoLoc);
678 +            int32_t   stoLoc = allocateData(1);    // Reserve the data location for storing save stack ptr.
679 +            int32_t   op     = buildOp(URX_STO_SP, stoLoc);
680              fRXPat->fCompiledPat->setElementAt(op, topLoc);
682              // Emit the SAVE_STATE   5
683              int32_t L7 = fRXPat->fCompiledPat->size()+1;
684 -            op = URX_BUILD(URX_STATE_SAVE, L7);
685 +            op = buildOp(URX_STATE_SAVE, L7);
686              fRXPat->fCompiledPat->setElementAt(op, topLoc+1);
688              // Append the JMP operation.
689 -            op = URX_BUILD(URX_JMP, topLoc+1);
690 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
691 +            appendOp(URX_JMP, topLoc+1);
693              // Emit the LD_SP       loc
694 -            op = URX_BUILD(URX_LD_SP, stoLoc);
695 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
696 +            appendOp(URX_LD_SP, stoLoc);
697          }
698          break;
700 @@ -1411,19 +1343,17 @@
701              insertOp(topLoc);
703              // Emit the STO_SP
704 -            int32_t   stoLoc = fRXPat->fDataSize;
705 -            fRXPat->fDataSize++;       // Reserve the data location for storing save stack ptr.
706 -            int32_t   op     = URX_BUILD(URX_STO_SP, stoLoc);
707 +            int32_t   stoLoc = allocateData(1);   // Reserve the data location for storing save stack ptr.
708 +            int32_t   op     = buildOp(URX_STO_SP, stoLoc);
709              fRXPat->fCompiledPat->setElementAt(op, topLoc);
711              // Emit the SAVE_STATE
712              int32_t   continueLoc = fRXPat->fCompiledPat->size()+1;
713 -            op = URX_BUILD(URX_STATE_SAVE, continueLoc);
714 +            op = buildOp(URX_STATE_SAVE, continueLoc);
715              fRXPat->fCompiledPat->setElementAt(op, topLoc+1);
717              // Emit the LD_SP
718 -            op = URX_BUILD(URX_LD_SP, stoLoc);
719 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
720 +            appendOp(URX_LD_SP, stoLoc);
721          }
722          break;
724 @@ -1480,8 +1410,8 @@
725          //             is an '|' alternation within the parens.
726          {
727              fixLiterals(FALSE);
728 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
729 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_NOP, 0), *fStatus);
730 +            appendOp(URX_NOP, 0);
731 +            appendOp(URX_NOP, 0);
733              // On the Parentheses stack, start a new frame and add the postions
734              //   of the two NOPs (a normal non-capturing () frame, except for the
735 @@ -1818,7 +1748,6 @@
736  //
737  //------------------------------------------------------------------------------
738  void    RegexCompile::fixLiterals(UBool split) {
739 -    int32_t  op = 0;                       // An op from/for the compiled pattern.
741      // If no literal characters have been scanned but not yet had code generated
742      //   for them, nothing needs to be done.
743 @@ -1857,23 +1786,23 @@
744          // Single character, emit a URX_ONECHAR op to match it.
745          if ((fModeFlags & UREGEX_CASE_INSENSITIVE) &&
746                   u_hasBinaryProperty(lastCodePoint, UCHAR_CASE_SENSITIVE)) {
747 -            op = URX_BUILD(URX_ONECHAR_I, lastCodePoint);
748 +            appendOp(URX_ONECHAR_I, lastCodePoint);
749          } else {
750 -            op = URX_BUILD(URX_ONECHAR, lastCodePoint);
751 +            appendOp(URX_ONECHAR, lastCodePoint);
752          }
753 -        fRXPat->fCompiledPat->addElement(op, *fStatus);
754      } else {
755          // Two or more chars, emit a URX_STRING to match them.
756 +        if (fLiteralChars.length() > 0x00ffffff || fRXPat->fLiteralText.length() > 0x00ffffff) {
757 +            error(U_REGEX_PATTERN_TOO_BIG);
758 +        }
759          if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
760 -            op = URX_BUILD(URX_STRING_I, fRXPat->fLiteralText.length());
761 +            appendOp(URX_STRING_I, fRXPat->fLiteralText.length());
762          } else {
763              // TODO here:  add optimization to split case sensitive strings of length two
764              //             into two single char ops, for efficiency.
765 -            op = URX_BUILD(URX_STRING, fRXPat->fLiteralText.length());
766 +            appendOp(URX_STRING, fRXPat->fLiteralText.length());
767          }
768 -        fRXPat->fCompiledPat->addElement(op, *fStatus);
769 -        op = URX_BUILD(URX_STRING_LEN, fLiteralChars.length());
770 -        fRXPat->fCompiledPat->addElement(op, *fStatus);
771 +        appendOp(URX_STRING_LEN, fLiteralChars.length());
773          // Add this string into the accumulated strings of the compiled pattern.
774          fRXPat->fLiteralText.append(fLiteralChars);
775 @@ -1883,8 +1812,58 @@
779 +int32_t RegexCompile::buildOp(int32_t type, int32_t val) {
780 +    if (U_FAILURE(*fStatus)) {
781 +        return 0;
782 +    }
783 +    if (type < 0 || type > 255) {
784 +        U_ASSERT(FALSE);
785 +        error(U_REGEX_INTERNAL_ERROR);
786 +        type = URX_RESERVED_OP;
787 +    }
788 +    if (val > 0x00ffffff) {
789 +        U_ASSERT(FALSE);
790 +        error(U_REGEX_INTERNAL_ERROR);
791 +        val = 0;
792 +    }
793 +    if (val < 0) {
794 +        if (!(type == URX_RESERVED_OP_N || type == URX_RESERVED_OP)) {
795 +            U_ASSERT(FALSE);
796 +            error(U_REGEX_INTERNAL_ERROR);
797 +            return -1;
798 +        }
799 +        if (URX_TYPE(val) != 0xff) {
800 +            U_ASSERT(FALSE);
801 +            error(U_REGEX_INTERNAL_ERROR);
802 +            return -1;
803 +        }
804 +        type = URX_RESERVED_OP_N;
805 +    }
806 +    return (type << 24) | val;
810 +//------------------------------------------------------------------------------
812 +//   appendOp()             Append a new instruction onto the compiled pattern
813 +//                          Includes error checking, limiting the size of the
814 +//                          pattern to lengths that can be represented in the
815 +//                          24 bit operand field of an instruction.
817 +//------------------------------------------------------------------------------
818 +void RegexCompile::appendOp(int32_t op) {
819 +    if (U_FAILURE(*fStatus)) {
820 +        return;
821 +    }
822 +    fRXPat->fCompiledPat->addElement(op, *fStatus);
823 +    if ((fRXPat->fCompiledPat->size() > 0x00fffff0) && U_SUCCESS(*fStatus)) {
824 +        error(U_REGEX_PATTERN_TOO_BIG);
825 +    }
828 +void RegexCompile::appendOp(int32_t type, int32_t val) {
829 +    appendOp(buildOp(type, val));
833  //------------------------------------------------------------------------------
834 @@ -1900,7 +1879,7 @@
835      UVector64 *code = fRXPat->fCompiledPat;
836      U_ASSERT(where>0 && where < code->size());
838 -    int32_t  nop = URX_BUILD(URX_NOP, 0);
839 +    int32_t  nop = buildOp(URX_NOP, 0);
840      code->insertElementAt(nop, where, *fStatus);
842      // Walk through the pattern, looking for any ops with targets that
843 @@ -1921,7 +1900,7 @@
844              // Target location for this opcode is after the insertion point and
845              //   needs to be incremented to adjust for the insertion.
846              opValue++;
847 -            op = URX_BUILD(opType, opValue);
848 +            op = buildOp(opType, opValue);
849              code->setElementAt(op, loc);
850          }
851      }
852 @@ -1946,6 +1925,58 @@
856 +//------------------------------------------------------------------------------
858 +//   allocateData()        Allocate storage in the matcher's static data area.
859 +//                         Return the index for the newly allocated data.
860 +//                         The storage won't actually exist until we are running a match
861 +//                         operation, but the storage indexes are inserted into various
862 +//                         opcodes while compiling the pattern.
864 +//------------------------------------------------------------------------------
865 +int32_t RegexCompile::allocateData(int32_t size) {
866 +    if (U_FAILURE(*fStatus)) {
867 +        return 0;
868 +    }
869 +    if (size <= 0 || size > 0x100 || fRXPat->fDataSize < 0) {
870 +        error(U_REGEX_INTERNAL_ERROR);
871 +        return 0;
872 +    }
873 +    int32_t dataIndex = fRXPat->fDataSize;
874 +    fRXPat->fDataSize += size;
875 +    if (fRXPat->fDataSize >= 0x00fffff0) {
876 +        error(U_REGEX_INTERNAL_ERROR);
877 +    }
878 +    return dataIndex;
882 +//------------------------------------------------------------------------------
884 +//   allocateStackData()   Allocate space in the back-tracking stack frame.
885 +//                         Return the index for the newly allocated data.
886 +//                         The frame indexes are inserted into various
887 +//                         opcodes while compiling the pattern, meaning that frame
888 +//                         size must be restricted to the size that will fit
889 +//                         as an operand (24 bits).
891 +//------------------------------------------------------------------------------
892 +int32_t RegexCompile::allocateStackData(int32_t size) {
893 +    if (U_FAILURE(*fStatus)) {
894 +        return 0;
895 +    }
896 +    if (size <= 0 || size > 0x100 || fRXPat->fFrameSize < 0) {
897 +        error(U_REGEX_INTERNAL_ERROR);
898 +        return 0;
899 +    }
900 +    int32_t dataIndex = fRXPat->fFrameSize;
901 +    fRXPat->fFrameSize += size;
902 +    if (fRXPat->fFrameSize >= 0x00fffff0) {
903 +        error(U_REGEX_PATTERN_TOO_BIG);
904 +    }
905 +    return dataIndex;
909  //------------------------------------------------------------------------------
910  //
911 @@ -1988,7 +2019,7 @@
912              theLoc--;
913          }
914          if (reserveLoc) {
915 -            int32_t  nop = URX_BUILD(URX_NOP, 0);
916 +            int32_t  nop = buildOp(URX_NOP, 0);
917              fRXPat->fCompiledPat->insertElementAt(nop, theLoc, *fStatus);
918          }
919      }
920 @@ -2063,8 +2094,7 @@
921              U_ASSERT(URX_TYPE(captureOp) == URX_START_CAPTURE);
923              int32_t   frameVarLocation = URX_VAL(captureOp);
924 -            int32_t   endCaptureOp = URX_BUILD(URX_END_CAPTURE, frameVarLocation);
925 -            fRXPat->fCompiledPat->addElement(endCaptureOp, *fStatus);
926 +            appendOp(URX_END_CAPTURE, frameVarLocation);
927          }
928          break;
929      case atomic:
930 @@ -2075,8 +2105,7 @@
931              int32_t   stoOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen+1);
932              U_ASSERT(URX_TYPE(stoOp) == URX_STO_SP);
933              int32_t   stoLoc = URX_VAL(stoOp);
934 -            int32_t   ldOp   = URX_BUILD(URX_LD_SP, stoLoc);
935 -            fRXPat->fCompiledPat->addElement(ldOp, *fStatus);
936 +            appendOp(URX_LD_SP, stoLoc);
937          }
938          break;
940 @@ -2085,8 +2114,7 @@
941              int32_t  startOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen-5);
942              U_ASSERT(URX_TYPE(startOp) == URX_LA_START);
943              int32_t dataLoc  = URX_VAL(startOp);
944 -            int32_t op       = URX_BUILD(URX_LA_END, dataLoc);
945 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
946 +            appendOp(URX_LA_END, dataLoc);
947          }
948          break;
950 @@ -2096,19 +2124,16 @@
951              int32_t  startOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen-1);
952              U_ASSERT(URX_TYPE(startOp) == URX_LA_START);
953              int32_t dataLoc  = URX_VAL(startOp);
954 -            int32_t op       = URX_BUILD(URX_LA_END, dataLoc);
955 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
956 -            op               = URX_BUILD(URX_BACKTRACK, 0);
957 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
958 -            op               = URX_BUILD(URX_LA_END, dataLoc);
959 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
960 +            appendOp(URX_LA_END, dataLoc);
961 +            appendOp(URX_BACKTRACK, 0);
962 +            appendOp(URX_LA_END, dataLoc);
964              // Patch the URX_SAVE near the top of the block.
965              // The destination of the SAVE is the final LA_END that was just added.
966              int32_t saveOp   = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen);
967              U_ASSERT(URX_TYPE(saveOp) == URX_STATE_SAVE);
968              int32_t dest     = fRXPat->fCompiledPat->size()-1;
969 -            saveOp           = URX_BUILD(URX_STATE_SAVE, dest);
970 +            saveOp           = buildOp(URX_STATE_SAVE, dest);
971              fRXPat->fCompiledPat->setElementAt(saveOp, fMatchOpenParen);
972          }
973          break;
974 @@ -2121,10 +2146,8 @@
975              int32_t  startOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen-4);
976              U_ASSERT(URX_TYPE(startOp) == URX_LB_START);
977              int32_t dataLoc  = URX_VAL(startOp);
978 -            int32_t op       = URX_BUILD(URX_LB_END, dataLoc);
979 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
980 -                    op       = URX_BUILD(URX_LA_END, dataLoc);
981 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
982 +            appendOp(URX_LB_END, dataLoc);
983 +            appendOp(URX_LA_END, dataLoc);
985              // Determine the min and max bounds for the length of the
986              //  string that the pattern can match.
987 @@ -2160,8 +2183,7 @@
988              int32_t  startOp = (int32_t)fRXPat->fCompiledPat->elementAti(fMatchOpenParen-5);
989              U_ASSERT(URX_TYPE(startOp) == URX_LB_START);
990              int32_t dataLoc  = URX_VAL(startOp);
991 -            int32_t op       = URX_BUILD(URX_LBN_END, dataLoc);
992 -            fRXPat->fCompiledPat->addElement(op, *fStatus);
993 +            appendOp(URX_LBN_END, dataLoc);
995              // Determine the min and max bounds for the length of the
996              //  string that the pattern can match.
997 @@ -2186,7 +2208,7 @@
999              // Insert the pattern location to continue at after a successful match
1000              //  as the last operand of the URX_LBN_CONT
1001 -            op = URX_BUILD(URX_RELOC_OPRND, fRXPat->fCompiledPat->size());
1002 +            int32_t op = buildOp(URX_RELOC_OPRND, fRXPat->fCompiledPat->size());
1003              fRXPat->fCompiledPat->setElementAt(op,  fMatchOpenParen-1);
1004          }
1005          break;
1006 @@ -2227,7 +2249,7 @@
1007      case 0:
1008          {
1009              // Set of no elements.   Always fails to match.
1010 -            fRXPat->fCompiledPat->addElement(URX_BUILD(URX_BACKTRACK, 0), *fStatus);
1011 +            appendOp(URX_BACKTRACK, 0);
1012              delete theSet;
1013          }
1014          break;
1015 @@ -2248,8 +2270,7 @@
1016              //  Put it into the compiled pattern as a set.
1017              int32_t setNumber = fRXPat->fSets->size();
1018              fRXPat->fSets->addElement(theSet, *fStatus);
1019 -            int32_t setOp = URX_BUILD(URX_SETREF, setNumber);
1020 -            fRXPat->fCompiledPat->addElement(setOp, *fStatus);
1021 +            appendOp(URX_SETREF, setNumber);
1022          }
1023      }
1025 @@ -2288,13 +2309,10 @@
1026      //        counterLoc   -->  Loop counter
1027      //               +1    -->  Input index (for breaking non-progressing loops)
1028      //                          (Only present if unbounded upper limit on loop)
1029 -    int32_t   counterLoc = fRXPat->fFrameSize;
1030 -    fRXPat->fFrameSize++;
1031 -    if (fIntervalUpper < 0) {
1032 -        fRXPat->fFrameSize++;
1033 -    }
1034 +    int32_t   dataSize = fIntervalUpper < 0 ? 2 : 1;
1035 +    int32_t   counterLoc = allocateStackData(dataSize);
1037 -    int32_t   op = URX_BUILD(InitOp, counterLoc);
1038 +    int32_t   op = buildOp(InitOp, counterLoc);
1039      fRXPat->fCompiledPat->setElementAt(op, topOfBlock);
1041      // The second operand of CTR_INIT is the location following the end of the loop.
1042 @@ -2302,7 +2320,7 @@
1043      //   compilation of something later on causes the code to grow and the target
1044      //   position to move.
1045      int32_t loopEnd = fRXPat->fCompiledPat->size();
1046 -    op = URX_BUILD(URX_RELOC_OPRND, loopEnd);
1047 +    op = buildOp(URX_RELOC_OPRND, loopEnd);
1048      fRXPat->fCompiledPat->setElementAt(op, topOfBlock+1);
1050      // Followed by the min and max counts.
1051 @@ -2311,8 +2329,7 @@
1053      // Apend the CTR_LOOP op.  The operand is the location of the CTR_INIT op.
1054      //   Goes at end of the block being looped over, so just append to the code so far.
1055 -    op = URX_BUILD(LoopOp, topOfBlock);
1056 -    fRXPat->fCompiledPat->addElement(op, *fStatus);
1057 +    appendOp(LoopOp, topOfBlock);
1059      if ((fIntervalLow & 0xff000000) != 0 ||
1060          (fIntervalUpper > 0 && (fIntervalUpper & 0xff000000) != 0)) {
1061 @@ -2365,7 +2382,7 @@
1062      //
1063      int32_t endOfSequenceLoc = fRXPat->fCompiledPat->size()-1
1064                                  + fIntervalUpper + (fIntervalUpper-fIntervalLow);
1065 -    int32_t saveOp = URX_BUILD(URX_STATE_SAVE, endOfSequenceLoc);
1066 +    int32_t saveOp = buildOp(URX_STATE_SAVE, endOfSequenceLoc);
1067      if (fIntervalLow == 0) {
1068          insertOp(topOfBlock);
1069          fRXPat->fCompiledPat->setElementAt(saveOp, topOfBlock);
1070 @@ -2378,13 +2395,10 @@
1071      //    it was put there when it was originally encountered.
1072      int32_t i;
1073      for (i=1; i<fIntervalUpper; i++ ) {
1074 -        if (i == fIntervalLow) {
1075 -            fRXPat->fCompiledPat->addElement(saveOp, *fStatus);
1076 -        }
1077 -        if (i > fIntervalLow) {
1078 -            fRXPat->fCompiledPat->addElement(saveOp, *fStatus);
1079 +        if (i >= fIntervalLow) {
1080 +            appendOp(saveOp);
1081          }
1082 -        fRXPat->fCompiledPat->addElement(op, *fStatus);
1083 +        appendOp(op);
1084      }
1085      return TRUE;
1087 @@ -3603,7 +3617,7 @@
1088                  int32_t  operandAddress = URX_VAL(op);
1089                  U_ASSERT(operandAddress>=0 && operandAddress<deltas.size());
1090                  int32_t fixedOperandAddress = operandAddress - deltas.elementAti(operandAddress);
1091 -                op = URX_BUILD(opType, fixedOperandAddress);
1092 +                op = buildOp(opType, fixedOperandAddress);
1093                  fRXPat->fCompiledPat->setElementAt(op, dst);
1094                  dst++;
1095                  break;
1096 @@ -3618,7 +3632,7 @@
1097                      break;
1098                  }
1099                  where = fRXPat->fGroupMap->elementAti(where-1);
1100 -                op    = URX_BUILD(opType, where);
1101 +                op    = buildOp(opType, where);
1102                  fRXPat->fCompiledPat->setElementAt(op, dst);
1103                  dst++;
1105 @@ -3970,7 +3984,7 @@
1106  //------------------------------------------------------------------------------
1107  //
1108  //  scanNamedChar
1109 - //            Get a UChar32 from a \N{UNICODE CHARACTER NAME} in the pattern.
1110 +//            Get a UChar32 from a \N{UNICODE CHARACTER NAME} in the pattern.
1111  //
1112  //             The scan position will be at the 'N'.  On return
1113  //             the scan position should be just after the '}'
1114 diff -ru icu/source/i18n/regexcmp.h icu/source/i18n/regexcmp.h
1115 --- icu/source/i18n/regexcmp.h  2015-04-10 15:27:31.370772856 +0200
1116 +++ icu/source/i18n/regexcmp.h  2015-04-10 15:28:06.152993511 +0200
1117 @@ -104,6 +104,13 @@
1118      void        fixLiterals(UBool split=FALSE);      // Generate code for pending literal characters.
1119      void        insertOp(int32_t where);             // Open up a slot for a new op in the
1120                                                       //   generated code at the specified location.
1121 +    void        appendOp(int32_t op);                // Append a new op to the compiled pattern.
1122 +    void        appendOp(int32_t type, int32_t val); // Build & append a new op to the compiled pattern.
1123 +    int32_t     buildOp(int32_t type, int32_t val);  // Construct a new pcode instruction.
1124 +    int32_t     allocateData(int32_t size);          // Allocate space in the matcher data area.
1125 +                                                     //   Return index of the newly allocated data.
1126 +    int32_t     allocateStackData(int32_t size);     // Allocate space in the match back-track stack frame.
1127 +                                                     //   Return offset index in the frame.
1128      int32_t     minMatchLength(int32_t start,
1129                                 int32_t end);
1130      int32_t     maxMatchLength(int32_t start,
1131 diff -ru icu/source/i18n/regeximp.h icu/source/i18n/regeximp.h
1132 --- icu/source/i18n/regeximp.h  2014-10-03 18:10:44.000000000 +0200
1133 +++ icu/source/i18n/regeximp.h  2015-04-10 15:28:06.153993517 +0200
1134 @@ -1,5 +1,5 @@
1135  //
1136 -//   Copyright (C) 2002-2013 International Business Machines Corporation
1137 +//   Copyright (C) 2002-2014 International Business Machines Corporation
1138  //   and others. All rights reserved.
1139  //
1140  //   file:  regeximp.h
1141 @@ -241,7 +241,6 @@
1142  //
1143  //  Convenience macros for assembling and disassembling a compiled operation.
1144  //
1145 -#define URX_BUILD(type, val) (int32_t)((type << 24) | (val))
1146  #define URX_TYPE(x)          ((uint32_t)(x) >> 24)
1147  #define URX_VAL(x)           ((x) & 0xffffff)
1149 diff -ru icu/source/test/intltest/regextst.cpp icu/source/test/intltest/regextst.cpp
1150 --- icu/source/test/intltest/regextst.cpp       2014-10-03 18:09:44.000000000 +0200
1151 +++ icu/source/test/intltest/regextst.cpp       2015-04-10 15:28:06.154993523 +0200
1152 @@ -144,6 +144,9 @@
1153          case 24: name = "TestBug11049";
1154              if (exec) TestBug11049();
1155              break;
1156 +        case 25: name = "TestBug11371";
1157 +            if (exec) TestBug11371();
1158 +            break;
1159          default: name = "";
1160              break; //needed to end loop
1161      }
1162 @@ -5367,6 +5370,49 @@
1166 +void RegexTest::TestBug11371() {
1167 +    if (quick) {
1168 +        logln("Skipping test. Runs in exhuastive mode only.");
1169 +        return;
1170 +    }
1171 +    UErrorCode status = U_ZERO_ERROR;
1172 +    UnicodeString patternString;
1174 +    for (int i=0; i<8000000; i++) {
1175 +        patternString.append(UnicodeString("()"));
1176 +    }
1177 +    LocalPointer<RegexPattern> compiledPat(RegexPattern::compile(patternString, 0, status));
1178 +    if (status != U_REGEX_PATTERN_TOO_BIG) {
1179 +        errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.",
1180 +              __FILE__, __LINE__, u_errorName(status));
1181 +    }
1183 +    status = U_ZERO_ERROR;
1184 +    patternString = "(";
1185 +    for (int i=0; i<20000000; i++) {
1186 +        patternString.append(UnicodeString("A++"));
1187 +    }
1188 +    patternString.append(UnicodeString("){0}B++"));
1189 +    LocalPointer<RegexPattern> compiledPat2(RegexPattern::compile(patternString, 0, status));
1190 +    if (status != U_REGEX_PATTERN_TOO_BIG) {
1191 +        errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.",
1192 +              __FILE__, __LINE__, u_errorName(status));
1193 +    }
1195 +    // Pattern with too much string data, such that string indexes overflow operand data field size
1196 +    // in compiled instruction.
1197 +    status = U_ZERO_ERROR;
1198 +    patternString = "";
1199 +    while (patternString.length() < 0x00ffffff) {
1200 +        patternString.append(UnicodeString("stuff and things dont you know, these are a few of my favorite strings\n"));
1201 +    }
1202 +    patternString.append(UnicodeString("X? trailing string"));
1203 +    LocalPointer<RegexPattern> compiledPat3(RegexPattern::compile(patternString, 0, status));
1204 +    if (status != U_REGEX_PATTERN_TOO_BIG) {
1205 +        errln("File %s, line %d expected status=U_REGEX_PATTERN_TOO_BIG; got %s.",
1206 +              __FILE__, __LINE__, u_errorName(status));
1207 +    }
1210  #endif  /* !UCONFIG_NO_REGULAR_EXPRESSIONS  */
1212 diff -ru icu/source/test/intltest/regextst.h icu/source/test/intltest/regextst.h
1213 --- icu/source/test/intltest/regextst.h 2014-10-03 18:09:40.000000000 +0200
1214 +++ icu/source/test/intltest/regextst.h 2015-04-10 15:28:06.154993523 +0200
1215 @@ -50,6 +50,7 @@
1216      virtual void Bug10459();
1217      virtual void TestCaseInsensitiveStarters();
1218      virtual void TestBug11049();
1219 +    virtual void TestBug11371();
1220      
1221      // The following functions are internal to the regexp tests.
1222      virtual void assertUText(const char *expected, UText *actual, const char *file, int line);