rugged 1.9.4 → 1.9.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/CMakeLists.txt +1 -1
  4. data/vendor/libgit2/COPYING +83 -11
  5. data/vendor/libgit2/cmake/SelectRegex.cmake +8 -3
  6. data/vendor/libgit2/deps/pcre2/CMakeLists.txt +110 -0
  7. data/vendor/libgit2/deps/pcre2/LICENCE.md +104 -0
  8. data/vendor/libgit2/deps/pcre2/config.h.in +54 -0
  9. data/vendor/libgit2/deps/pcre2/pcre2.h +1079 -0
  10. data/vendor/libgit2/deps/pcre2/pcre2_auto_possess.c +1416 -0
  11. data/vendor/libgit2/deps/{pcre/pcre_chartables.c → pcre2/pcre2_chartables.c} +41 -47
  12. data/vendor/libgit2/deps/{pcre/pcre_ord2utf8.c → pcre2/pcre2_chkdint.c} +36 -36
  13. data/vendor/libgit2/deps/pcre2/pcre2_compile.c +11345 -0
  14. data/vendor/libgit2/deps/pcre2/pcre2_compile.h +356 -0
  15. data/vendor/libgit2/deps/pcre2/pcre2_compile_cgroup.c +632 -0
  16. data/vendor/libgit2/deps/pcre2/pcre2_compile_class.c +2777 -0
  17. data/vendor/libgit2/deps/pcre2/pcre2_config.c +250 -0
  18. data/vendor/libgit2/deps/pcre2/pcre2_context.c +557 -0
  19. data/vendor/libgit2/deps/pcre2/pcre2_convert.c +1263 -0
  20. data/vendor/libgit2/deps/{pcre/pcre_dfa_exec.c → pcre2/pcre2_dfa_match.c} +1402 -943
  21. data/vendor/libgit2/deps/pcre2/pcre2_error.c +384 -0
  22. data/vendor/libgit2/deps/pcre2/pcre2_extuni.c +159 -0
  23. data/vendor/libgit2/deps/pcre2/pcre2_find_bracket.c +217 -0
  24. data/vendor/libgit2/deps/pcre2/pcre2_fuzzsupport.c +844 -0
  25. data/vendor/libgit2/deps/pcre2/pcre2_internal.h +2353 -0
  26. data/vendor/libgit2/deps/pcre2/pcre2_intmodedep.h +1044 -0
  27. data/vendor/libgit2/deps/pcre2/pcre2_maketables.c +177 -0
  28. data/vendor/libgit2/deps/pcre2/pcre2_match.c +8244 -0
  29. data/vendor/libgit2/deps/pcre2/pcre2_match_data.c +184 -0
  30. data/vendor/libgit2/deps/pcre2/pcre2_match_next.c +171 -0
  31. data/vendor/libgit2/deps/{pcre/pcre_newline.c → pcre2/pcre2_newline.c} +92 -63
  32. data/vendor/libgit2/deps/{pcre/pcre_refcount.c → pcre2/pcre2_ord2utf.c} +64 -38
  33. data/vendor/libgit2/deps/pcre2/pcre2_pattern_info.c +430 -0
  34. data/vendor/libgit2/deps/pcre2/pcre2_printint_inc.h +1098 -0
  35. data/vendor/libgit2/deps/pcre2/pcre2_script_run.c +344 -0
  36. data/vendor/libgit2/deps/pcre2/pcre2_serialize.c +284 -0
  37. data/vendor/libgit2/deps/pcre2/pcre2_string_utils.c +199 -0
  38. data/vendor/libgit2/deps/pcre2/pcre2_study.c +2087 -0
  39. data/vendor/libgit2/deps/pcre2/pcre2_substitute.c +1761 -0
  40. data/vendor/libgit2/deps/pcre2/pcre2_substring.c +553 -0
  41. data/vendor/libgit2/deps/pcre2/pcre2_tables.c +310 -0
  42. data/vendor/libgit2/deps/pcre2/pcre2_ucd.c +5805 -0
  43. data/vendor/libgit2/deps/pcre2/pcre2_ucp.h +408 -0
  44. data/vendor/libgit2/deps/pcre2/pcre2_ucptables_inc.h +1596 -0
  45. data/vendor/libgit2/deps/pcre2/pcre2_util.h +179 -0
  46. data/vendor/libgit2/deps/pcre2/pcre2_valid_utf.c +397 -0
  47. data/vendor/libgit2/deps/pcre2/pcre2_xclass.c +547 -0
  48. data/vendor/libgit2/include/git2/common.h +13 -1
  49. data/vendor/libgit2/include/git2/version.h +2 -2
  50. data/vendor/libgit2/src/libgit2/blame.c +6 -0
  51. data/vendor/libgit2/src/libgit2/delta.c +8 -0
  52. data/vendor/libgit2/src/libgit2/indexer.c +3 -2
  53. data/vendor/libgit2/src/libgit2/settings.c +9 -0
  54. data/vendor/libgit2/src/libgit2/streams/openssl.c +4 -1
  55. data/vendor/libgit2/src/libgit2/submodule.c +77 -12
  56. data/vendor/libgit2/src/libgit2/transports/http.c +4 -4
  57. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +2 -1
  58. data/vendor/libgit2/src/util/fs_path.h +10 -10
  59. data/vendor/libgit2/src/util/regexp.c +27 -12
  60. data/vendor/libgit2/src/util/regexp.h +7 -2
  61. metadata +44 -37
  62. data/vendor/libgit2/deps/pcre/CMakeLists.txt +0 -140
  63. data/vendor/libgit2/deps/pcre/COPYING +0 -5
  64. data/vendor/libgit2/deps/pcre/LICENCE +0 -93
  65. data/vendor/libgit2/deps/pcre/cmake/COPYING-CMAKE-SCRIPTS +0 -22
  66. data/vendor/libgit2/deps/pcre/cmake/FindEditline.cmake +0 -17
  67. data/vendor/libgit2/deps/pcre/cmake/FindPackageHandleStandardArgs.cmake +0 -58
  68. data/vendor/libgit2/deps/pcre/cmake/FindReadline.cmake +0 -29
  69. data/vendor/libgit2/deps/pcre/config.h.in +0 -57
  70. data/vendor/libgit2/deps/pcre/pcre.h +0 -641
  71. data/vendor/libgit2/deps/pcre/pcre_byte_order.c +0 -319
  72. data/vendor/libgit2/deps/pcre/pcre_compile.c +0 -9815
  73. data/vendor/libgit2/deps/pcre/pcre_config.c +0 -190
  74. data/vendor/libgit2/deps/pcre/pcre_exec.c +0 -7173
  75. data/vendor/libgit2/deps/pcre/pcre_fullinfo.c +0 -245
  76. data/vendor/libgit2/deps/pcre/pcre_get.c +0 -669
  77. data/vendor/libgit2/deps/pcre/pcre_globals.c +0 -86
  78. data/vendor/libgit2/deps/pcre/pcre_internal.h +0 -2787
  79. data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +0 -11913
  80. data/vendor/libgit2/deps/pcre/pcre_maketables.c +0 -156
  81. data/vendor/libgit2/deps/pcre/pcre_printint.c +0 -834
  82. data/vendor/libgit2/deps/pcre/pcre_string_utils.c +0 -211
  83. data/vendor/libgit2/deps/pcre/pcre_study.c +0 -1686
  84. data/vendor/libgit2/deps/pcre/pcre_tables.c +0 -727
  85. data/vendor/libgit2/deps/pcre/pcre_ucd.c +0 -3644
  86. data/vendor/libgit2/deps/pcre/pcre_valid_utf8.c +0 -301
  87. data/vendor/libgit2/deps/pcre/pcre_version.c +0 -98
  88. data/vendor/libgit2/deps/pcre/pcre_xclass.c +0 -268
  89. data/vendor/libgit2/deps/pcre/pcreposix.c +0 -420
  90. data/vendor/libgit2/deps/pcre/pcreposix.h +0 -117
  91. data/vendor/libgit2/deps/pcre/ucp.h +0 -224
@@ -3,11 +3,11 @@
3
3
  *************************************************/
4
4
 
5
5
  /* PCRE is a library of functions to support regular expressions whose syntax
6
- and semantics are as close as possible to those of the Perl 5 language (but see
7
- below for why this module is different).
6
+ and semantics are as close as possible to those of the Perl 5 language.
8
7
 
9
8
  Written by Philip Hazel
10
- Copyright (c) 1997-2017 University of Cambridge
9
+ Original API code Copyright (c) 1997-2012 University of Cambridge
10
+ New API code Copyright (c) 2016-2024 University of Cambridge
11
11
 
12
12
  -----------------------------------------------------------------------------
13
13
  Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,8 @@ POSSIBILITY OF SUCH DAMAGE.
38
38
  -----------------------------------------------------------------------------
39
39
  */
40
40
 
41
- /* This module contains the external function pcre_dfa_exec(), which is an
41
+
42
+ /* This module contains the external function pcre2_dfa_match(), which is an
42
43
  alternative matching function that uses a sort of DFA algorithm (not a true
43
44
  FSM). This is NOT Perl-compatible, but it has advantages in certain
44
45
  applications. */
@@ -64,28 +65,26 @@ on the stack. It did give a 13% improvement with one specially constructed
64
65
  pattern for certain subject strings, but on other strings and on many of the
65
66
  simpler patterns in the test suite it did worse. The major problem, I think,
66
67
  was the extra time to initialize the index. This had to be done for each call
67
- of internal_dfa_exec(). (The supplied patch used a static vector, initialized
68
+ of internal_dfa_match(). (The supplied patch used a static vector, initialized
68
69
  only once - I suspect this was the cause of the problems with the tests.)
69
70
 
70
71
  Overall, I concluded that the gains in some cases did not outweigh the losses
71
72
  in others, so I abandoned this code. */
72
73
 
73
74
 
75
+ #include "pcre2_internal.h"
76
+
74
77
 
75
- #ifdef HAVE_CONFIG_H
76
- #include "config.h"
77
- #endif
78
78
 
79
- #define NLBLOCK md /* Block containing newline information */
79
+ #define NLBLOCK mb /* Block containing newline information */
80
80
  #define PSSTART start_subject /* Field containing processed string start */
81
81
  #define PSEND end_subject /* Field containing processed string end */
82
82
 
83
- #include "pcre_internal.h"
84
-
85
-
86
- /* For use to indent debugging output */
87
-
88
- #define SP " "
83
+ #define PUBLIC_DFA_MATCH_OPTIONS \
84
+ (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
85
+ PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
86
+ PCRE2_PARTIAL_SOFT|PCRE2_DFA_SHORTEST|PCRE2_DFA_RESTART| \
87
+ PCRE2_COPY_MATCHED_SUBJECT)
89
88
 
90
89
 
91
90
  /*************************************************
@@ -112,7 +111,7 @@ small value. Non-zero values in the table are the offsets from the opcode where
112
111
  the character is to be found. ***NOTE*** If the start of this table is
113
112
  modified, the three tables that follow must also be modified. */
114
113
 
115
- static const pcre_uint8 coptable[] = {
114
+ static const uint8_t coptable[] = {
116
115
  0, /* End */
117
116
  0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */
118
117
  0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */
@@ -155,33 +154,41 @@ static const pcre_uint8 coptable[] = {
155
154
  0, /* CLASS */
156
155
  0, /* NCLASS */
157
156
  0, /* XCLASS - variable length */
157
+ 0, /* ECLASS - variable length */
158
158
  0, /* REF */
159
159
  0, /* REFI */
160
160
  0, /* DNREF */
161
161
  0, /* DNREFI */
162
162
  0, /* RECURSE */
163
163
  0, /* CALLOUT */
164
+ 0, /* CALLOUT_STR */
164
165
  0, /* Alt */
165
166
  0, /* Ket */
166
167
  0, /* KetRmax */
167
168
  0, /* KetRmin */
168
169
  0, /* KetRpos */
169
- 0, /* Reverse */
170
+ 0, 0, /* Reverse, Vreverse */
170
171
  0, /* Assert */
171
172
  0, /* Assert not */
172
173
  0, /* Assert behind */
173
174
  0, /* Assert behind not */
174
- 0, 0, /* ONCE, ONCE_NC */
175
+ 0, /* NA assert */
176
+ 0, /* NA assert behind */
177
+ 0, /* Assert scan substring */
178
+ 0, /* ONCE */
179
+ 0, /* SCRIPT_RUN */
175
180
  0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
176
181
  0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
177
182
  0, 0, /* CREF, DNCREF */
178
183
  0, 0, /* RREF, DNRREF */
179
- 0, /* DEF */
184
+ 0, 0, /* FALSE, TRUE */
180
185
  0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
181
186
  0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
182
187
  0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
183
- 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
184
- 0, 0 /* CLOSE, SKIPZERO */
188
+ 0, 0, /* COMMIT, COMMIT_ARG */
189
+ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */
190
+ 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */
191
+ 0, 0, /* \B and \b in UCP mode */
185
192
  };
186
193
 
187
194
  /* This table identifies those opcodes that inspect a character. It is used to
@@ -189,7 +196,7 @@ remember the fact that a character could have been inspected when the end of
189
196
  the subject is reached. ***NOTE*** If the start of this table is modified, the
190
197
  two tables that follow must also be modified. */
191
198
 
192
- static const pcre_uint8 poptable[] = {
199
+ static const uint8_t poptable[] = {
193
200
  0, /* End */
194
201
  0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */
195
202
  1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */
@@ -227,39 +234,51 @@ static const pcre_uint8 poptable[] = {
227
234
  1, /* CLASS */
228
235
  1, /* NCLASS */
229
236
  1, /* XCLASS - variable length */
237
+ 1, /* ECLASS - variable length */
230
238
  0, /* REF */
231
239
  0, /* REFI */
232
240
  0, /* DNREF */
233
241
  0, /* DNREFI */
234
242
  0, /* RECURSE */
235
243
  0, /* CALLOUT */
244
+ 0, /* CALLOUT_STR */
236
245
  0, /* Alt */
237
246
  0, /* Ket */
238
247
  0, /* KetRmax */
239
248
  0, /* KetRmin */
240
249
  0, /* KetRpos */
241
- 0, /* Reverse */
250
+ 0, 0, /* Reverse, Vreverse */
242
251
  0, /* Assert */
243
252
  0, /* Assert not */
244
253
  0, /* Assert behind */
245
254
  0, /* Assert behind not */
246
- 0, 0, /* ONCE, ONCE_NC */
255
+ 0, /* NA assert */
256
+ 0, /* NA assert behind */
257
+ 0, /* Assert scan substring */
258
+ 0, /* ONCE */
259
+ 0, /* SCRIPT_RUN */
247
260
  0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
248
261
  0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
249
262
  0, 0, /* CREF, DNCREF */
250
263
  0, 0, /* RREF, DNRREF */
251
- 0, /* DEF */
264
+ 0, 0, /* FALSE, TRUE */
252
265
  0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
253
266
  0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
254
267
  0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
255
- 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
256
- 0, 0 /* CLOSE, SKIPZERO */
268
+ 0, 0, /* COMMIT, COMMIT_ARG */
269
+ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */
270
+ 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */
271
+ 1, 1, /* \B and \b in UCP mode */
257
272
  };
258
273
 
274
+ /* Compile-time check that these tables have the correct size. */
275
+ STATIC_ASSERT(sizeof(coptable) == OP_TABLE_LENGTH, coptable);
276
+ STATIC_ASSERT(sizeof(poptable) == OP_TABLE_LENGTH, poptable);
277
+
259
278
  /* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
260
279
  and \w */
261
280
 
262
- static const pcre_uint8 toptable1[] = {
281
+ static const uint8_t toptable1[] = {
263
282
  0, 0, 0, 0, 0, 0,
264
283
  ctype_digit, ctype_digit,
265
284
  ctype_space, ctype_space,
@@ -267,7 +286,7 @@ static const pcre_uint8 toptable1[] = {
267
286
  0, 0 /* OP_ANY, OP_ALLANY */
268
287
  };
269
288
 
270
- static const pcre_uint8 toptable2[] = {
289
+ static const uint8_t toptable2[] = {
271
290
  0, 0, 0, 0, 0, 0,
272
291
  ctype_digit, 0,
273
292
  ctype_space, 0,
@@ -282,7 +301,7 @@ entirely of ints because the working vector we are passed, and which we put
282
301
  these structures in, is a vector of ints. */
283
302
 
284
303
  typedef struct stateblock {
285
- int offset; /* Offset to opcode */
304
+ int offset; /* Offset to opcode (-ve has meaning) */
286
305
  int count; /* Count for repeats */
287
306
  int data; /* Some use extra data */
288
307
  } stateblock;
@@ -290,39 +309,157 @@ typedef struct stateblock {
290
309
  #define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int))
291
310
 
292
311
 
293
- #ifdef PCRE_DEBUG
312
+ /* Before version 10.32 the recursive calls of internal_dfa_match() were passed
313
+ local working space and output vectors that were created on the stack. This has
314
+ caused issues for some patterns, especially in small-stack environments such as
315
+ Windows. A new scheme is now in use which sets up a vector on the stack, but if
316
+ this is too small, heap memory is used, up to the heap_limit. The main
317
+ parameters are all numbers of ints because the workspace is a vector of ints.
318
+
319
+ The size of the starting stack vector, DFA_START_RWS_SIZE, is in bytes, and is
320
+ defined in pcre2_internal.h so as to be available to pcre2test when it is
321
+ finding the minimum heap requirement for a match. */
322
+
323
+ #define OVEC_UNIT (sizeof(PCRE2_SIZE)/sizeof(int))
324
+
325
+ #define RWS_BASE_SIZE (DFA_START_RWS_SIZE/sizeof(int)) /* Stack vector */
326
+ #define RWS_RSIZE 1000 /* Work size for recursion */
327
+ #define RWS_OVEC_RSIZE (1000*OVEC_UNIT) /* Ovector for recursion */
328
+ #define RWS_OVEC_OSIZE (2*OVEC_UNIT) /* Ovector in other cases */
329
+
330
+ /* This structure is at the start of each workspace block. */
331
+
332
+ typedef struct RWS_anchor {
333
+ struct RWS_anchor *next;
334
+ uint32_t size; /* Number of ints */
335
+ uint32_t free; /* Number of ints */
336
+ } RWS_anchor;
337
+
338
+ #define RWS_ANCHOR_SIZE (sizeof(RWS_anchor)/sizeof(int))
339
+
340
+
341
+
294
342
  /*************************************************
295
- * Print character string *
343
+ * Process a callout *
296
344
  *************************************************/
297
345
 
298
- /* Character string printing function for debugging.
346
+ /* This function is called to perform a callout.
299
347
 
300
348
  Arguments:
301
- p points to string
302
- length number of bytes
303
- f where to print
349
+ code current code pointer
350
+ offsets points to current capture offsets
351
+ current_subject start of current subject match
352
+ ptr current position in subject
353
+ mb the match block
354
+ extracode extra code offset when called from condition
355
+ lengthptr where to return the callout length
356
+
357
+ Returns: the return from the callout
358
+ */
359
+
360
+ static int
361
+ do_callout_dfa(PCRE2_SPTR code, PCRE2_SIZE *offsets, PCRE2_SPTR current_subject,
362
+ PCRE2_SPTR ptr, dfa_match_block *mb, PCRE2_SIZE extracode,
363
+ PCRE2_SIZE *lengthptr)
364
+ {
365
+ pcre2_callout_block *cb = mb->cb;
366
+
367
+ *lengthptr = (code[extracode] == OP_CALLOUT)?
368
+ (PCRE2_SIZE)PRIV(OP_lengths)[OP_CALLOUT] :
369
+ (PCRE2_SIZE)GET(code, 1 + 2*LINK_SIZE + extracode);
370
+
371
+ if (mb->callout == NULL) return 0; /* No callout provided */
372
+
373
+ /* Fixed fields in the callout block are set once and for all at the start of
374
+ matching. */
375
+
376
+ cb->offset_vector = offsets;
377
+ cb->start_match = (PCRE2_SIZE)(current_subject - mb->start_subject);
378
+ cb->current_position = (PCRE2_SIZE)(ptr - mb->start_subject);
379
+ cb->pattern_position = GET(code, 1 + extracode);
380
+ cb->next_item_length = GET(code, 1 + LINK_SIZE + extracode);
304
381
 
305
- Returns: nothing
382
+ if (code[extracode] == OP_CALLOUT)
383
+ {
384
+ cb->callout_number = code[1 + 2*LINK_SIZE + extracode];
385
+ cb->callout_string_offset = 0;
386
+ cb->callout_string = NULL;
387
+ cb->callout_string_length = 0;
388
+ }
389
+ else
390
+ {
391
+ cb->callout_number = 0;
392
+ cb->callout_string_offset = GET(code, 1 + 3*LINK_SIZE + extracode);
393
+ cb->callout_string = code + (1 + 4*LINK_SIZE + extracode) + 1;
394
+ cb->callout_string_length = *lengthptr - (1 + 4*LINK_SIZE) - 2;
395
+ }
396
+
397
+ return (mb->callout)(cb, mb->callout_data);
398
+ }
399
+
400
+
401
+
402
+ /*************************************************
403
+ * Expand local workspace memory *
404
+ *************************************************/
405
+
406
+ /* This function is called when internal_dfa_match() is about to be called
407
+ recursively and there is insufficient working space left in the current
408
+ workspace block. If there's an existing next block, use it; otherwise get a new
409
+ block unless the heap limit is reached.
410
+
411
+ Arguments:
412
+ rwsptr pointer to block pointer (updated)
413
+ ovecsize space needed for an ovector
414
+ mb the match block
415
+
416
+ Returns: 0 rwsptr has been updated
417
+ !0 an error code
306
418
  */
307
419
 
308
- static void
309
- pchars(const pcre_uchar *p, int length, FILE *f)
420
+ static int
421
+ more_workspace(RWS_anchor **rwsptr, unsigned int ovecsize, dfa_match_block *mb)
310
422
  {
311
- pcre_uint32 c;
312
- while (length-- > 0)
423
+ RWS_anchor *rws = *rwsptr;
424
+ RWS_anchor *new;
425
+
426
+ if (rws->next != NULL)
313
427
  {
314
- if (isprint(c = *(p++)))
315
- fprintf(f, "%c", c);
316
- else
317
- fprintf(f, "\\x{%02x}", c);
428
+ new = rws->next;
318
429
  }
430
+
431
+ /* Sizes in the RWS_anchor blocks are in units of sizeof(int), but
432
+ mb->heap_limit and mb->heap_used are in kibibytes. Play carefully, to avoid
433
+ overflow. */
434
+
435
+ else
436
+ {
437
+ uint32_t newsize = (rws->size >= UINT32_MAX/(sizeof(int)*2))? UINT32_MAX/sizeof(int) : rws->size * 2;
438
+ uint32_t newsizeK = newsize/(1024/sizeof(int));
439
+
440
+ if (newsizeK + mb->heap_used > mb->heap_limit)
441
+ newsizeK = (uint32_t)(mb->heap_limit - mb->heap_used);
442
+ newsize = newsizeK*(1024/sizeof(int));
443
+
444
+ if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE)
445
+ return PCRE2_ERROR_HEAPLIMIT;
446
+ new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data);
447
+ if (new == NULL) return PCRE2_ERROR_NOMEMORY;
448
+ mb->heap_used += newsizeK;
449
+ new->next = NULL;
450
+ new->size = newsize;
451
+ rws->next = new;
452
+ }
453
+
454
+ new->free = new->size - RWS_ANCHOR_SIZE;
455
+ *rwsptr = new;
456
+ return 0;
319
457
  }
320
- #endif
321
458
 
322
459
 
323
460
 
324
461
  /*************************************************
325
- * Execute a Regular Expression - DFA engine *
462
+ * Match a Regular Expression - DFA engine *
326
463
  *************************************************/
327
464
 
328
465
  /* This internal function applies a compiled pattern to a subject string,
@@ -331,7 +468,7 @@ external one, possibly multiple times if the pattern is not anchored. The
331
468
  function calls itself recursively for some kinds of subpattern.
332
469
 
333
470
  Arguments:
334
- md the match_data block with fixed information
471
+ mb the match_data block with fixed information
335
472
  this_start_code the opening bracket of this subexpression's code
336
473
  current_subject where we currently are in the subject string
337
474
  start_offset start offset in the subject string
@@ -355,9 +492,8 @@ for the current character, one for the following character). */
355
492
  next_active_state->offset = (x); \
356
493
  next_active_state->count = (y); \
357
494
  next_active_state++; \
358
- DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
359
495
  } \
360
- else return PCRE_ERROR_DFA_WSSIZE
496
+ else return PCRE2_ERROR_DFA_WSSIZE
361
497
 
362
498
  #define ADD_ACTIVE_DATA(x,y,z) \
363
499
  if (active_count++ < wscount) \
@@ -366,9 +502,8 @@ for the current character, one for the following character). */
366
502
  next_active_state->count = (y); \
367
503
  next_active_state->data = (z); \
368
504
  next_active_state++; \
369
- DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
370
505
  } \
371
- else return PCRE_ERROR_DFA_WSSIZE
506
+ else return PCRE2_ERROR_DFA_WSSIZE
372
507
 
373
508
  #define ADD_NEW(x,y) \
374
509
  if (new_count++ < wscount) \
@@ -376,9 +511,8 @@ for the current character, one for the following character). */
376
511
  next_new_state->offset = (x); \
377
512
  next_new_state->count = (y); \
378
513
  next_new_state++; \
379
- DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
380
514
  } \
381
- else return PCRE_ERROR_DFA_WSSIZE
515
+ else return PCRE2_ERROR_DFA_WSSIZE
382
516
 
383
517
  #define ADD_NEW_DATA(x,y,z) \
384
518
  if (new_count++ < wscount) \
@@ -387,95 +521,83 @@ for the current character, one for the following character). */
387
521
  next_new_state->count = (y); \
388
522
  next_new_state->data = (z); \
389
523
  next_new_state++; \
390
- DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d) line %d\n", rlevel*2-2, SP, \
391
- (x), (y), (z), __LINE__)); \
392
524
  } \
393
- else return PCRE_ERROR_DFA_WSSIZE
525
+ else return PCRE2_ERROR_DFA_WSSIZE
394
526
 
395
527
  /* And now, here is the code */
396
528
 
397
529
  static int
398
- internal_dfa_exec(
399
- dfa_match_data *md,
400
- const pcre_uchar *this_start_code,
401
- const pcre_uchar *current_subject,
402
- int start_offset,
403
- int *offsets,
404
- int offsetcount,
530
+ internal_dfa_match(
531
+ dfa_match_block *mb,
532
+ PCRE2_SPTR this_start_code,
533
+ PCRE2_SPTR current_subject,
534
+ PCRE2_SIZE start_offset,
535
+ PCRE2_SIZE *offsets,
536
+ uint32_t offsetcount,
405
537
  int *workspace,
406
538
  int wscount,
407
- int rlevel)
539
+ uint32_t rlevel,
540
+ int *RWS)
408
541
  {
409
542
  stateblock *active_states, *new_states, *temp_states;
410
543
  stateblock *next_active_state, *next_new_state;
411
-
412
- const pcre_uint8 *ctypes, *lcc, *fcc;
413
- const pcre_uchar *ptr;
414
- const pcre_uchar *end_code, *first_op;
415
-
544
+ const uint8_t *ctypes, *lcc, *fcc;
545
+ PCRE2_SPTR ptr;
546
+ PCRE2_SPTR end_code;
416
547
  dfa_recursion_info new_recursive;
417
-
418
548
  int active_count, new_count, match_count;
419
549
 
420
- /* Some fields in the md block are frequently referenced, so we load them into
550
+ /* Some fields in the mb block are frequently referenced, so we load them into
421
551
  independent variables in the hope that this will perform better. */
422
552
 
423
- const pcre_uchar *start_subject = md->start_subject;
424
- const pcre_uchar *end_subject = md->end_subject;
425
- const pcre_uchar *start_code = md->start_code;
553
+ PCRE2_SPTR start_subject = mb->start_subject;
554
+ PCRE2_SPTR end_subject = mb->end_subject;
555
+ PCRE2_SPTR start_code = mb->start_code;
426
556
 
427
- #ifdef SUPPORT_UTF
428
- BOOL utf = (md->poptions & PCRE_UTF8) != 0;
557
+ #ifdef SUPPORT_UNICODE
558
+ BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
559
+ BOOL utf_or_ucp = utf || (mb->poptions & PCRE2_UCP) != 0;
429
560
  #else
430
561
  BOOL utf = FALSE;
431
562
  #endif
432
563
 
433
564
  BOOL reset_could_continue = FALSE;
434
565
 
435
- rlevel++;
436
- offsetcount &= (-2);
566
+ if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;
567
+ if (rlevel++ > mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;
568
+ offsetcount &= (uint32_t)(-2); /* Round down */
437
569
 
438
570
  wscount -= 2;
439
571
  wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /
440
572
  (2 * INTS_PER_STATEBLOCK);
441
573
 
442
- DPRINTF(("\n%.*s---------------------\n"
443
- "%.*sCall to internal_dfa_exec f=%d\n",
444
- rlevel*2-2, SP, rlevel*2-2, SP, rlevel));
574
+ ctypes = mb->tables + ctypes_offset;
575
+ lcc = mb->tables + lcc_offset;
576
+ fcc = mb->tables + fcc_offset;
445
577
 
446
- ctypes = md->tables + ctypes_offset;
447
- lcc = md->tables + lcc_offset;
448
- fcc = md->tables + fcc_offset;
449
-
450
- match_count = PCRE_ERROR_NOMATCH; /* A negative number */
578
+ match_count = PCRE2_ERROR_NOMATCH; /* A negative number */
451
579
 
452
580
  active_states = (stateblock *)(workspace + 2);
453
581
  next_new_state = new_states = active_states + wscount;
454
582
  new_count = 0;
455
583
 
456
- first_op = this_start_code + 1 + LINK_SIZE +
457
- ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
458
- *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
459
- ? IMM2_SIZE:0);
460
-
461
584
  /* The first thing in any (sub) pattern is a bracket of some sort. Push all
462
585
  the alternative states onto the list, and find out where the end is. This
463
586
  makes is possible to use this function recursively, when we want to stop at a
464
587
  matching internal ket rather than at the end.
465
588
 
466
- If the first opcode in the first alternative is OP_REVERSE, we are dealing with
467
- a backward assertion. In that case, we have to find out the maximum amount to
468
- move back, and set up each alternative appropriately. */
589
+ If we are dealing with a backward assertion we have to find out the maximum
590
+ amount to move back, and set up each alternative appropriately. */
469
591
 
470
- if (*first_op == OP_REVERSE)
592
+ if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT)
471
593
  {
472
- int max_back = 0;
473
- int gone_back;
594
+ size_t max_back = 0;
595
+ size_t gone_back;
474
596
 
475
597
  end_code = this_start_code;
476
598
  do
477
599
  {
478
- int back = GET(end_code, 2+LINK_SIZE);
600
+ size_t back = (size_t)GET2(end_code, 2+LINK_SIZE);
479
601
  if (back > max_back) max_back = back;
480
602
  end_code += GET(end_code, 1);
481
603
  }
@@ -484,7 +606,7 @@ if (*first_op == OP_REVERSE)
484
606
  /* If we can't go back the amount required for the longest lookbehind
485
607
  pattern, go back as far as we can; some alternatives may still be viable. */
486
608
 
487
- #ifdef SUPPORT_UTF
609
+ #ifdef SUPPORT_UNICODE
488
610
  /* In character mode we have to step back character by character */
489
611
 
490
612
  if (utf)
@@ -493,7 +615,8 @@ if (*first_op == OP_REVERSE)
493
615
  {
494
616
  if (current_subject <= start_subject) break;
495
617
  current_subject--;
496
- ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--);
618
+ ACROSSCHAR(current_subject > start_subject, current_subject,
619
+ current_subject--);
497
620
  }
498
621
  }
499
622
  else
@@ -502,26 +625,28 @@ if (*first_op == OP_REVERSE)
502
625
  /* In byte-mode we can do this quickly. */
503
626
 
504
627
  {
505
- gone_back = (current_subject - max_back < start_subject)?
506
- (int)(current_subject - start_subject) : max_back;
628
+ size_t current_offset = (size_t)(current_subject - start_subject);
629
+ gone_back = (current_offset < max_back)? current_offset : max_back;
507
630
  current_subject -= gone_back;
508
631
  }
509
632
 
510
633
  /* Save the earliest consulted character */
511
634
 
512
- if (current_subject < md->start_used_ptr)
513
- md->start_used_ptr = current_subject;
635
+ if (current_subject < mb->start_used_ptr)
636
+ mb->start_used_ptr = current_subject;
514
637
 
515
- /* Now we can process the individual branches. */
638
+ /* Now we can process the individual branches. There will be an OP_REVERSE at
639
+ the start of each branch, except when the length of the branch is zero. */
516
640
 
517
641
  end_code = this_start_code;
518
642
  do
519
643
  {
520
- int back = GET(end_code, 2+LINK_SIZE);
644
+ uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + IMM2_SIZE : 0;
645
+ size_t back = (revlen == 0)? 0 : (size_t)GET2(end_code, 2+LINK_SIZE);
521
646
  if (back <= gone_back)
522
647
  {
523
- int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE);
524
- ADD_NEW_DATA(-bstate, 0, gone_back - back);
648
+ int bstate = (int)(end_code - start_code + 1 + LINK_SIZE + revlen);
649
+ ADD_NEW_DATA(-bstate, 0, (int)(gone_back - back));
525
650
  }
526
651
  end_code += GET(end_code, 1);
527
652
  }
@@ -540,12 +665,12 @@ else
540
665
 
541
666
  /* Restarting */
542
667
 
543
- if (rlevel == 1 && (md->moptions & PCRE_DFA_RESTART) != 0)
668
+ if (rlevel == 1 && (mb->moptions & PCRE2_DFA_RESTART) != 0)
544
669
  {
545
670
  do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);
546
671
  new_count = workspace[1];
547
672
  if (!workspace[0])
548
- memcpy(new_states, active_states, new_count * sizeof(stateblock));
673
+ memcpy(new_states, active_states, (size_t)new_count * sizeof(stateblock));
549
674
  }
550
675
 
551
676
  /* Not restarting */
@@ -568,8 +693,6 @@ else
568
693
 
569
694
  workspace[0] = 0; /* Bit indicating which vector is current */
570
695
 
571
- DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, (int)(end_code - start_code)));
572
-
573
696
  /* Loop for scanning the subject */
574
697
 
575
698
  ptr = current_subject;
@@ -577,12 +700,13 @@ for (;;)
577
700
  {
578
701
  int i, j;
579
702
  int clen, dlen;
580
- pcre_uint32 c, d;
581
- int forced_fail = 0;
703
+ uint32_t c, d;
582
704
  BOOL partial_newline = FALSE;
583
705
  BOOL could_continue = reset_could_continue;
584
706
  reset_could_continue = FALSE;
585
707
 
708
+ if (ptr > mb->last_used_ptr) mb->last_used_ptr = ptr;
709
+
586
710
  /* Make the new state list into the active state list and empty the
587
711
  new state list. */
588
712
 
@@ -595,17 +719,6 @@ for (;;)
595
719
  workspace[0] ^= 1; /* Remember for the restarting feature */
596
720
  workspace[1] = active_count;
597
721
 
598
- #ifdef PCRE_DEBUG
599
- printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP);
600
- pchars(ptr, STRLEN_UC(ptr), stdout);
601
- printf("\"\n");
602
-
603
- printf("%.*sActive states: ", rlevel*2-2, SP);
604
- for (i = 0; i < active_count; i++)
605
- printf("%d/%d ", active_states[i].offset, active_states[i].count);
606
- printf("\n");
607
- #endif
608
-
609
722
  /* Set the pointers for adding new states */
610
723
 
611
724
  next_active_state = active_states + active_count;
@@ -618,11 +731,11 @@ for (;;)
618
731
  if (ptr < end_subject)
619
732
  {
620
733
  clen = 1; /* Number of data items in the character */
621
- #ifdef SUPPORT_UTF
734
+ #ifdef SUPPORT_UNICODE
622
735
  GETCHARLENTEST(c, ptr, clen);
623
736
  #else
624
737
  c = *ptr;
625
- #endif /* SUPPORT_UTF */
738
+ #endif /* SUPPORT_UNICODE */
626
739
  }
627
740
  else
628
741
  {
@@ -639,18 +752,12 @@ for (;;)
639
752
  {
640
753
  stateblock *current_state = active_states + i;
641
754
  BOOL caseless = FALSE;
642
- const pcre_uchar *code;
755
+ PCRE2_SPTR code;
756
+ uint32_t codevalue;
643
757
  int state_offset = current_state->offset;
644
- int codevalue, rrc;
758
+ int rrc;
645
759
  int count;
646
760
 
647
- #ifdef PCRE_DEBUG
648
- printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
649
- if (clen == 0) printf("EOL\n");
650
- else if (c > 32 && c < 127) printf("'%c'\n", c);
651
- else printf("0x%02x\n", c);
652
- #endif
653
-
654
761
  /* A negative offset is a special case meaning "hold off going to this
655
762
  (negated) state until the number of characters in the data field have
656
763
  been skipped". If the could_continue flag was passed over from a previous
@@ -660,7 +767,6 @@ for (;;)
660
767
  {
661
768
  if (current_state->data > 0)
662
769
  {
663
- DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));
664
770
  ADD_NEW_DATA(state_offset, current_state->count,
665
771
  current_state->data - 1);
666
772
  if (could_continue) reset_could_continue = TRUE;
@@ -680,10 +786,7 @@ for (;;)
680
786
  {
681
787
  if (active_states[j].offset == state_offset &&
682
788
  active_states[j].count == current_state->count)
683
- {
684
- DPRINTF(("%.*sDuplicate state: skipped\n", rlevel*2-2, SP));
685
789
  goto NEXT_ACTIVE_STATE;
686
- }
687
790
  }
688
791
 
689
792
  /* The state offset is the offset to the opcode */
@@ -711,15 +814,15 @@ for (;;)
711
814
  if (coptable[codevalue] > 0)
712
815
  {
713
816
  dlen = 1;
714
- #ifdef SUPPORT_UTF
817
+ #ifdef SUPPORT_UNICODE
715
818
  if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
716
- #endif /* SUPPORT_UTF */
819
+ #endif /* SUPPORT_UNICODE */
717
820
  d = code[coptable[codevalue]];
718
821
  if (codevalue >= OP_TYPESTAR)
719
822
  {
720
823
  switch(d)
721
824
  {
722
- case OP_ANYBYTE: return PCRE_ERROR_DFA_UITEM;
825
+ case OP_ANYBYTE: return PCRE2_ERROR_DFA_UITEM;
723
826
  case OP_NOTPROP:
724
827
  case OP_PROP: codevalue += OP_PROP_EXTRA; break;
725
828
  case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;
@@ -743,19 +846,6 @@ for (;;)
743
846
 
744
847
  switch (codevalue)
745
848
  {
746
- /* ========================================================================== */
747
- /* These cases are never obeyed. This is a fudge that causes a compile-
748
- time error if the vectors coptable or poptable, which are indexed by
749
- opcode, are not the correct length. It seems to be the only way to do
750
- such a check at compile time, as the sizeof() operator does not work
751
- in the C preprocessor. */
752
-
753
- case OP_TABLE_LENGTH:
754
- case OP_TABLE_LENGTH +
755
- ((sizeof(coptable) == OP_TABLE_LENGTH) &&
756
- (sizeof(poptable) == OP_TABLE_LENGTH)):
757
- break;
758
-
759
849
  /* ========================================================================== */
760
850
  /* Reached a closing bracket. If not at the end of the pattern, carry
761
851
  on with the next opcode. For repeating opcodes, also add the repeat
@@ -764,7 +854,7 @@ for (;;)
764
854
  using recursive calls. Thus, it never adds any new states.
765
855
 
766
856
  At the end of the (sub)pattern, unless we have an empty string and
767
- PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the
857
+ PCRE2_NOTEMPTY is set, or PCRE2_NOTEMPTY_ATSTART is set and we are at the
768
858
  start of the subject, save the match data, shifting up all previous
769
859
  matches so we always have the longest first. */
770
860
 
@@ -777,35 +867,28 @@ for (;;)
777
867
  ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
778
868
  if (codevalue != OP_KET)
779
869
  {
780
- ADD_ACTIVE(state_offset - GET(code, 1), 0);
870
+ ADD_ACTIVE(state_offset - (int)GET(code, 1), 0);
781
871
  }
782
872
  }
783
873
  else
784
874
  {
785
875
  if (ptr > current_subject ||
786
- ((md->moptions & PCRE_NOTEMPTY) == 0 &&
787
- ((md->moptions & PCRE_NOTEMPTY_ATSTART) == 0 ||
788
- current_subject > start_subject + md->start_offset)))
876
+ ((mb->moptions & PCRE2_NOTEMPTY) == 0 &&
877
+ ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) == 0 ||
878
+ current_subject > start_subject + mb->start_offset)))
789
879
  {
790
880
  if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;
791
- else if (match_count > 0 && ++match_count * 2 > offsetcount)
881
+ else if (match_count > 0 && ++match_count * 2 > (int)offsetcount)
792
882
  match_count = 0;
793
- count = ((match_count == 0)? offsetcount : match_count * 2) - 2;
794
- if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int));
883
+ count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2;
884
+ if (count > 0) (void)memmove(offsets + 2, offsets,
885
+ (size_t)count * sizeof(PCRE2_SIZE));
795
886
  if (offsetcount >= 2)
796
887
  {
797
- offsets[0] = (int)(current_subject - start_subject);
798
- offsets[1] = (int)(ptr - start_subject);
799
- DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
800
- offsets[1] - offsets[0], (char *)current_subject));
801
- }
802
- if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
803
- {
804
- DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
805
- "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel,
806
- match_count, rlevel*2-2, SP));
807
- return match_count;
888
+ offsets[0] = (PCRE2_SIZE)(current_subject - start_subject);
889
+ offsets[1] = (PCRE2_SIZE)(ptr - start_subject);
808
890
  }
891
+ if ((mb->moptions & PCRE2_DFA_SHORTEST) != 0) return match_count;
809
892
  }
810
893
  }
811
894
  break;
@@ -861,14 +944,15 @@ for (;;)
861
944
 
862
945
  /*-----------------------------------------------------------------*/
863
946
  case OP_CIRC:
864
- if (ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0)
947
+ if (ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0)
865
948
  { ADD_ACTIVE(state_offset + 1, 0); }
866
949
  break;
867
950
 
868
951
  /*-----------------------------------------------------------------*/
869
952
  case OP_CIRCM:
870
- if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) ||
871
- (ptr != end_subject && WAS_NEWLINE(ptr)))
953
+ if ((ptr == start_subject && (mb->moptions & PCRE2_NOTBOL) == 0) ||
954
+ ((ptr != end_subject || (mb->poptions & PCRE2_ALT_CIRCUMFLEX) != 0 )
955
+ && WAS_NEWLINE(ptr)))
872
956
  { ADD_ACTIVE(state_offset + 1, 0); }
873
957
  break;
874
958
 
@@ -876,8 +960,8 @@ for (;;)
876
960
  case OP_EOD:
877
961
  if (ptr >= end_subject)
878
962
  {
879
- if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
880
- could_continue = TRUE;
963
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
964
+ return PCRE2_ERROR_PARTIAL;
881
965
  else { ADD_ACTIVE(state_offset + 1, 0); }
882
966
  }
883
967
  break;
@@ -903,8 +987,8 @@ for (;;)
903
987
  case OP_ANY:
904
988
  if (clen > 0 && !IS_NEWLINE(ptr))
905
989
  {
906
- if (ptr + 1 >= md->end_subject &&
907
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
990
+ if (ptr + 1 >= mb->end_subject &&
991
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
908
992
  NLBLOCK->nltype == NLTYPE_FIXED &&
909
993
  NLBLOCK->nllen == 2 &&
910
994
  c == NLBLOCK->nl[0])
@@ -926,30 +1010,32 @@ for (;;)
926
1010
 
927
1011
  /*-----------------------------------------------------------------*/
928
1012
  case OP_EODN:
929
- if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
930
- could_continue = TRUE;
931
- else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen))
932
- { ADD_ACTIVE(state_offset + 1, 0); }
1013
+ if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen))
1014
+ {
1015
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
1016
+ return PCRE2_ERROR_PARTIAL;
1017
+ ADD_ACTIVE(state_offset + 1, 0);
1018
+ }
933
1019
  break;
934
1020
 
935
1021
  /*-----------------------------------------------------------------*/
936
1022
  case OP_DOLL:
937
- if ((md->moptions & PCRE_NOTEOL) == 0)
1023
+ if ((mb->moptions & PCRE2_NOTEOL) == 0)
938
1024
  {
939
- if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
1025
+ if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
940
1026
  could_continue = TRUE;
941
1027
  else if (clen == 0 ||
942
- ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
943
- (ptr == end_subject - md->nllen)
1028
+ ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
1029
+ (ptr == end_subject - mb->nllen)
944
1030
  ))
945
1031
  { ADD_ACTIVE(state_offset + 1, 0); }
946
- else if (ptr + 1 >= md->end_subject &&
947
- (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
1032
+ else if (ptr + 1 >= mb->end_subject &&
1033
+ (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
948
1034
  NLBLOCK->nltype == NLTYPE_FIXED &&
949
1035
  NLBLOCK->nllen == 2 &&
950
1036
  c == NLBLOCK->nl[0])
951
1037
  {
952
- if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
1038
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
953
1039
  {
954
1040
  reset_could_continue = TRUE;
955
1041
  ADD_NEW_DATA(-(state_offset + 1), 0, 1);
@@ -961,20 +1047,20 @@ for (;;)
961
1047
 
962
1048
  /*-----------------------------------------------------------------*/
963
1049
  case OP_DOLLM:
964
- if ((md->moptions & PCRE_NOTEOL) == 0)
1050
+ if ((mb->moptions & PCRE2_NOTEOL) == 0)
965
1051
  {
966
- if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
1052
+ if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
967
1053
  could_continue = TRUE;
968
1054
  else if (clen == 0 ||
969
- ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
1055
+ ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
970
1056
  { ADD_ACTIVE(state_offset + 1, 0); }
971
- else if (ptr + 1 >= md->end_subject &&
972
- (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
1057
+ else if (ptr + 1 >= mb->end_subject &&
1058
+ (mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
973
1059
  NLBLOCK->nltype == NLTYPE_FIXED &&
974
1060
  NLBLOCK->nllen == 2 &&
975
1061
  c == NLBLOCK->nl[0])
976
1062
  {
977
- if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
1063
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
978
1064
  {
979
1065
  reset_could_continue = TRUE;
980
1066
  ADD_NEW_DATA(-(state_offset + 1), 0, 1);
@@ -1008,25 +1094,27 @@ for (;;)
1008
1094
  /*-----------------------------------------------------------------*/
1009
1095
  case OP_WORD_BOUNDARY:
1010
1096
  case OP_NOT_WORD_BOUNDARY:
1097
+ case OP_NOT_UCP_WORD_BOUNDARY:
1098
+ case OP_UCP_WORD_BOUNDARY:
1011
1099
  {
1012
1100
  int left_word, right_word;
1013
1101
 
1014
1102
  if (ptr > start_subject)
1015
1103
  {
1016
- const pcre_uchar *temp = ptr - 1;
1017
- if (temp < md->start_used_ptr) md->start_used_ptr = temp;
1018
- #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1104
+ PCRE2_SPTR temp = ptr - 1;
1105
+ if (temp < mb->start_used_ptr) mb->start_used_ptr = temp;
1106
+ #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
1019
1107
  if (utf) { BACKCHAR(temp); }
1020
1108
  #endif
1021
1109
  GETCHARTEST(d, temp);
1022
- #ifdef SUPPORT_UCP
1023
- if ((md->poptions & PCRE_UCP) != 0)
1110
+ #ifdef SUPPORT_UNICODE
1111
+ if (codevalue == OP_UCP_WORD_BOUNDARY ||
1112
+ codevalue == OP_NOT_UCP_WORD_BOUNDARY)
1024
1113
  {
1025
- if (d == '_') left_word = TRUE; else
1026
- {
1027
- int cat = UCD_CATEGORY(d);
1028
- left_word = (cat == ucp_L || cat == ucp_N);
1029
- }
1114
+ int chartype = UCD_CHARTYPE(d);
1115
+ int category = PRIV(ucp_gentype)[chartype];
1116
+ left_word = (category == ucp_L || category == ucp_N ||
1117
+ chartype == ucp_Mn || chartype == ucp_Pc);
1030
1118
  }
1031
1119
  else
1032
1120
  #endif
@@ -1036,14 +1124,22 @@ for (;;)
1036
1124
 
1037
1125
  if (clen > 0)
1038
1126
  {
1039
- #ifdef SUPPORT_UCP
1040
- if ((md->poptions & PCRE_UCP) != 0)
1127
+ if (ptr >= mb->last_used_ptr)
1041
1128
  {
1042
- if (c == '_') right_word = TRUE; else
1043
- {
1044
- int cat = UCD_CATEGORY(c);
1045
- right_word = (cat == ucp_L || cat == ucp_N);
1046
- }
1129
+ PCRE2_SPTR temp = ptr + 1;
1130
+ #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
1131
+ if (utf) { FORWARDCHARTEST(temp, mb->end_subject); }
1132
+ #endif
1133
+ mb->last_used_ptr = temp;
1134
+ }
1135
+ #ifdef SUPPORT_UNICODE
1136
+ if (codevalue == OP_UCP_WORD_BOUNDARY ||
1137
+ codevalue == OP_NOT_UCP_WORD_BOUNDARY)
1138
+ {
1139
+ int chartype = UCD_CHARTYPE(c);
1140
+ int category = PRIV(ucp_gentype)[chartype];
1141
+ right_word = (category == ucp_L || category == ucp_N ||
1142
+ chartype == ucp_Mn || chartype == ucp_Pc);
1047
1143
  }
1048
1144
  else
1049
1145
  #endif
@@ -1051,7 +1147,9 @@ for (;;)
1051
1147
  }
1052
1148
  else right_word = FALSE;
1053
1149
 
1054
- if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
1150
+ if ((left_word == right_word) ==
1151
+ (codevalue == OP_NOT_WORD_BOUNDARY ||
1152
+ codevalue == OP_NOT_UCP_WORD_BOUNDARY))
1055
1153
  { ADD_ACTIVE(state_offset + 1, 0); }
1056
1154
  }
1057
1155
  break;
@@ -1062,23 +1160,21 @@ for (;;)
1062
1160
  if the support is in the binary; otherwise a compile-time error occurs.
1063
1161
  */
1064
1162
 
1065
- #ifdef SUPPORT_UCP
1163
+ #ifdef SUPPORT_UNICODE
1066
1164
  case OP_PROP:
1067
1165
  case OP_NOTPROP:
1068
1166
  if (clen > 0)
1069
1167
  {
1070
1168
  BOOL OK;
1071
- const pcre_uint32 *cp;
1169
+ int chartype;
1170
+ const uint32_t *cp;
1072
1171
  const ucd_record * prop = GET_UCD(c);
1073
1172
  switch(code[1])
1074
1173
  {
1075
- case PT_ANY:
1076
- OK = TRUE;
1077
- break;
1078
-
1079
1174
  case PT_LAMP:
1080
- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
1081
- prop->chartype == ucp_Lt;
1175
+ chartype = prop->chartype;
1176
+ OK = chartype == ucp_Lu || chartype == ucp_Ll ||
1177
+ chartype == ucp_Lt;
1082
1178
  break;
1083
1179
 
1084
1180
  case PT_GC:
@@ -1093,11 +1189,17 @@ for (;;)
1093
1189
  OK = prop->script == code[2];
1094
1190
  break;
1095
1191
 
1192
+ case PT_SCX:
1193
+ OK = (prop->script == code[2] ||
1194
+ MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), code[2]) != 0);
1195
+ break;
1196
+
1096
1197
  /* These are specials for combination cases. */
1097
1198
 
1098
1199
  case PT_ALNUM:
1099
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
1100
- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1200
+ chartype = prop->chartype;
1201
+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
1202
+ PRIV(ucp_gentype)[chartype] == ucp_N;
1101
1203
  break;
1102
1204
 
1103
1205
  /* Perl space used to exclude VT, but from Perl 5.18 it is included,
@@ -1120,12 +1222,20 @@ for (;;)
1120
1222
  break;
1121
1223
 
1122
1224
  case PT_WORD:
1123
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
1124
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
1125
- c == CHAR_UNDERSCORE;
1225
+ chartype = prop->chartype;
1226
+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
1227
+ PRIV(ucp_gentype)[chartype] == ucp_N ||
1228
+ chartype == ucp_Mn || chartype == ucp_Pc;
1126
1229
  break;
1127
1230
 
1128
1231
  case PT_CLIST:
1232
+ #if PCRE2_CODE_UNIT_WIDTH == 32
1233
+ if (c > MAX_UTF_CODE_POINT)
1234
+ {
1235
+ OK = FALSE;
1236
+ break;
1237
+ }
1238
+ #endif
1129
1239
  cp = PRIV(ucd_caseless_sets) + code[2];
1130
1240
  for (;;)
1131
1241
  {
@@ -1140,6 +1250,15 @@ for (;;)
1140
1250
  c >= 0xe000;
1141
1251
  break;
1142
1252
 
1253
+ case PT_BIDICL:
1254
+ OK = UCD_BIDICLASS(c) == code[2];
1255
+ break;
1256
+
1257
+ case PT_BOOL:
1258
+ OK = MAPBIT(PRIV(ucd_boolprop_sets) +
1259
+ UCD_BPROPS_PROP(prop), code[2]) != 0;
1260
+ break;
1261
+
1143
1262
  /* Should never occur, but keep compilers from grumbling. */
1144
1263
 
1145
1264
  default:
@@ -1167,8 +1286,8 @@ for (;;)
1167
1286
  if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
1168
1287
  if (clen > 0)
1169
1288
  {
1170
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1171
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1289
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
1290
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
1172
1291
  NLBLOCK->nltype == NLTYPE_FIXED &&
1173
1292
  NLBLOCK->nllen == 2 &&
1174
1293
  c == NLBLOCK->nl[0])
@@ -1198,8 +1317,8 @@ for (;;)
1198
1317
  ADD_ACTIVE(state_offset + 2, 0);
1199
1318
  if (clen > 0)
1200
1319
  {
1201
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1202
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1320
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
1321
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
1203
1322
  NLBLOCK->nltype == NLTYPE_FIXED &&
1204
1323
  NLBLOCK->nllen == 2 &&
1205
1324
  c == NLBLOCK->nl[0])
@@ -1228,8 +1347,8 @@ for (;;)
1228
1347
  ADD_ACTIVE(state_offset + 2, 0);
1229
1348
  if (clen > 0)
1230
1349
  {
1231
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1232
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1350
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
1351
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
1233
1352
  NLBLOCK->nltype == NLTYPE_FIXED &&
1234
1353
  NLBLOCK->nllen == 2 &&
1235
1354
  c == NLBLOCK->nl[0])
@@ -1256,8 +1375,8 @@ for (;;)
1256
1375
  count = current_state->count; /* Number already matched */
1257
1376
  if (clen > 0)
1258
1377
  {
1259
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1260
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1378
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
1379
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
1261
1380
  NLBLOCK->nltype == NLTYPE_FIXED &&
1262
1381
  NLBLOCK->nllen == 2 &&
1263
1382
  c == NLBLOCK->nl[0])
@@ -1285,8 +1404,8 @@ for (;;)
1285
1404
  count = current_state->count; /* Number already matched */
1286
1405
  if (clen > 0)
1287
1406
  {
1288
- if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1289
- (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1407
+ if (d == OP_ANY && ptr + 1 >= mb->end_subject &&
1408
+ (mb->moptions & (PCRE2_PARTIAL_HARD)) != 0 &&
1290
1409
  NLBLOCK->nltype == NLTYPE_FIXED &&
1291
1410
  NLBLOCK->nllen == 2 &&
1292
1411
  c == NLBLOCK->nl[0])
@@ -1317,7 +1436,7 @@ for (;;)
1317
1436
  argument. It keeps the code above fast for the other cases. The argument
1318
1437
  is in the d variable. */
1319
1438
 
1320
- #ifdef SUPPORT_UCP
1439
+ #ifdef SUPPORT_UNICODE
1321
1440
  case OP_PROP_EXTRA + OP_TYPEPLUS:
1322
1441
  case OP_PROP_EXTRA + OP_TYPEMINPLUS:
1323
1442
  case OP_PROP_EXTRA + OP_TYPEPOSPLUS:
@@ -1326,17 +1445,14 @@ for (;;)
1326
1445
  if (clen > 0)
1327
1446
  {
1328
1447
  BOOL OK;
1329
- const pcre_uint32 *cp;
1448
+ int chartype;
1449
+ const uint32_t *cp;
1330
1450
  const ucd_record * prop = GET_UCD(c);
1331
1451
  switch(code[2])
1332
1452
  {
1333
- case PT_ANY:
1334
- OK = TRUE;
1335
- break;
1336
-
1337
1453
  case PT_LAMP:
1338
- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
1339
- prop->chartype == ucp_Lt;
1454
+ chartype = prop->chartype;
1455
+ OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
1340
1456
  break;
1341
1457
 
1342
1458
  case PT_GC:
@@ -1351,11 +1467,17 @@ for (;;)
1351
1467
  OK = prop->script == code[3];
1352
1468
  break;
1353
1469
 
1470
+ case PT_SCX:
1471
+ OK = (prop->script == code[3] ||
1472
+ MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), code[3]) != 0);
1473
+ break;
1474
+
1354
1475
  /* These are specials for combination cases. */
1355
1476
 
1356
1477
  case PT_ALNUM:
1357
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
1358
- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1478
+ chartype = prop->chartype;
1479
+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
1480
+ PRIV(ucp_gentype)[chartype] == ucp_N;
1359
1481
  break;
1360
1482
 
1361
1483
  /* Perl space used to exclude VT, but from Perl 5.18 it is included,
@@ -1378,12 +1500,20 @@ for (;;)
1378
1500
  break;
1379
1501
 
1380
1502
  case PT_WORD:
1381
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
1382
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
1383
- c == CHAR_UNDERSCORE;
1503
+ chartype = prop->chartype;
1504
+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
1505
+ PRIV(ucp_gentype)[chartype] == ucp_N ||
1506
+ chartype == ucp_Mn || chartype == ucp_Pc;
1384
1507
  break;
1385
1508
 
1386
1509
  case PT_CLIST:
1510
+ #if PCRE2_CODE_UNIT_WIDTH == 32
1511
+ if (c > MAX_UTF_CODE_POINT)
1512
+ {
1513
+ OK = FALSE;
1514
+ break;
1515
+ }
1516
+ #endif
1387
1517
  cp = PRIV(ucd_caseless_sets) + code[3];
1388
1518
  for (;;)
1389
1519
  {
@@ -1398,6 +1528,15 @@ for (;;)
1398
1528
  c >= 0xe000;
1399
1529
  break;
1400
1530
 
1531
+ case PT_BIDICL:
1532
+ OK = UCD_BIDICLASS(c) == code[3];
1533
+ break;
1534
+
1535
+ case PT_BOOL:
1536
+ OK = MAPBIT(PRIV(ucd_boolprop_sets) +
1537
+ UCD_BPROPS_PROP(prop), code[3]) != 0;
1538
+ break;
1539
+
1401
1540
  /* Should never occur, but keep compilers from grumbling. */
1402
1541
 
1403
1542
  default:
@@ -1426,25 +1565,14 @@ for (;;)
1426
1565
  if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
1427
1566
  if (clen > 0)
1428
1567
  {
1429
- int lgb, rgb;
1430
- const pcre_uchar *nptr = ptr + clen;
1431
1568
  int ncount = 0;
1432
1569
  if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
1433
1570
  {
1434
1571
  active_count--; /* Remove non-match possibility */
1435
1572
  next_active_state--;
1436
1573
  }
1437
- lgb = UCD_GRAPHBREAK(c);
1438
- while (nptr < end_subject)
1439
- {
1440
- dlen = 1;
1441
- if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1442
- rgb = UCD_GRAPHBREAK(d);
1443
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1444
- ncount++;
1445
- lgb = rgb;
1446
- nptr += dlen;
1447
- }
1574
+ (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,
1575
+ &ncount);
1448
1576
  count++;
1449
1577
  ADD_NEW_DATA(-state_offset, count, ncount);
1450
1578
  }
@@ -1469,7 +1597,7 @@ for (;;)
1469
1597
  case 0x2028:
1470
1598
  case 0x2029:
1471
1599
  #endif /* Not EBCDIC */
1472
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
1600
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
1473
1601
  goto ANYNL01;
1474
1602
 
1475
1603
  case CHAR_CR:
@@ -1560,7 +1688,7 @@ for (;;)
1560
1688
  break;
1561
1689
 
1562
1690
  /*-----------------------------------------------------------------*/
1563
- #ifdef SUPPORT_UCP
1691
+ #ifdef SUPPORT_UNICODE
1564
1692
  case OP_PROP_EXTRA + OP_TYPEQUERY:
1565
1693
  case OP_PROP_EXTRA + OP_TYPEMINQUERY:
1566
1694
  case OP_PROP_EXTRA + OP_TYPEPOSQUERY:
@@ -1578,17 +1706,14 @@ for (;;)
1578
1706
  if (clen > 0)
1579
1707
  {
1580
1708
  BOOL OK;
1581
- const pcre_uint32 *cp;
1709
+ int chartype;
1710
+ const uint32_t *cp;
1582
1711
  const ucd_record * prop = GET_UCD(c);
1583
1712
  switch(code[2])
1584
1713
  {
1585
- case PT_ANY:
1586
- OK = TRUE;
1587
- break;
1588
-
1589
1714
  case PT_LAMP:
1590
- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
1591
- prop->chartype == ucp_Lt;
1715
+ chartype = prop->chartype;
1716
+ OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
1592
1717
  break;
1593
1718
 
1594
1719
  case PT_GC:
@@ -1603,11 +1728,17 @@ for (;;)
1603
1728
  OK = prop->script == code[3];
1604
1729
  break;
1605
1730
 
1731
+ case PT_SCX:
1732
+ OK = (prop->script == code[3] ||
1733
+ MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), code[3]) != 0);
1734
+ break;
1735
+
1606
1736
  /* These are specials for combination cases. */
1607
1737
 
1608
1738
  case PT_ALNUM:
1609
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
1610
- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1739
+ chartype = prop->chartype;
1740
+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
1741
+ PRIV(ucp_gentype)[chartype] == ucp_N;
1611
1742
  break;
1612
1743
 
1613
1744
  /* Perl space used to exclude VT, but from Perl 5.18 it is included,
@@ -1630,12 +1761,20 @@ for (;;)
1630
1761
  break;
1631
1762
 
1632
1763
  case PT_WORD:
1633
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
1634
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
1635
- c == CHAR_UNDERSCORE;
1764
+ chartype = prop->chartype;
1765
+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
1766
+ PRIV(ucp_gentype)[chartype] == ucp_N ||
1767
+ chartype == ucp_Mn || chartype == ucp_Pc;
1636
1768
  break;
1637
1769
 
1638
1770
  case PT_CLIST:
1771
+ #if PCRE2_CODE_UNIT_WIDTH == 32
1772
+ if (c > MAX_UTF_CODE_POINT)
1773
+ {
1774
+ OK = FALSE;
1775
+ break;
1776
+ }
1777
+ #endif
1639
1778
  cp = PRIV(ucd_caseless_sets) + code[3];
1640
1779
  for (;;)
1641
1780
  {
@@ -1650,6 +1789,15 @@ for (;;)
1650
1789
  c >= 0xe000;
1651
1790
  break;
1652
1791
 
1792
+ case PT_BIDICL:
1793
+ OK = UCD_BIDICLASS(c) == code[3];
1794
+ break;
1795
+
1796
+ case PT_BOOL:
1797
+ OK = MAPBIT(PRIV(ucd_boolprop_sets) +
1798
+ UCD_BPROPS_PROP(prop), code[3]) != 0;
1799
+ break;
1800
+
1653
1801
  /* Should never occur, but keep compilers from grumbling. */
1654
1802
 
1655
1803
  default:
@@ -1687,8 +1835,6 @@ for (;;)
1687
1835
  ADD_ACTIVE(state_offset + 2, 0);
1688
1836
  if (clen > 0)
1689
1837
  {
1690
- int lgb, rgb;
1691
- const pcre_uchar *nptr = ptr + clen;
1692
1838
  int ncount = 0;
1693
1839
  if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
1694
1840
  codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
@@ -1696,17 +1842,8 @@ for (;;)
1696
1842
  active_count--; /* Remove non-match possibility */
1697
1843
  next_active_state--;
1698
1844
  }
1699
- lgb = UCD_GRAPHBREAK(c);
1700
- while (nptr < end_subject)
1701
- {
1702
- dlen = 1;
1703
- if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1704
- rgb = UCD_GRAPHBREAK(d);
1705
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1706
- ncount++;
1707
- lgb = rgb;
1708
- nptr += dlen;
1709
- }
1845
+ (void)PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,
1846
+ &ncount);
1710
1847
  ADD_NEW_DATA(-(state_offset + count), 0, ncount);
1711
1848
  }
1712
1849
  break;
@@ -1738,7 +1875,7 @@ for (;;)
1738
1875
  case 0x2028:
1739
1876
  case 0x2029:
1740
1877
  #endif /* Not EBCDIC */
1741
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
1878
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
1742
1879
  goto ANYNL02;
1743
1880
 
1744
1881
  case CHAR_CR:
@@ -1844,7 +1981,7 @@ for (;;)
1844
1981
  break;
1845
1982
 
1846
1983
  /*-----------------------------------------------------------------*/
1847
- #ifdef SUPPORT_UCP
1984
+ #ifdef SUPPORT_UNICODE
1848
1985
  case OP_PROP_EXTRA + OP_TYPEEXACT:
1849
1986
  case OP_PROP_EXTRA + OP_TYPEUPTO:
1850
1987
  case OP_PROP_EXTRA + OP_TYPEMINUPTO:
@@ -1855,17 +1992,14 @@ for (;;)
1855
1992
  if (clen > 0)
1856
1993
  {
1857
1994
  BOOL OK;
1858
- const pcre_uint32 *cp;
1995
+ int chartype;
1996
+ const uint32_t *cp;
1859
1997
  const ucd_record * prop = GET_UCD(c);
1860
1998
  switch(code[1 + IMM2_SIZE + 1])
1861
1999
  {
1862
- case PT_ANY:
1863
- OK = TRUE;
1864
- break;
1865
-
1866
2000
  case PT_LAMP:
1867
- OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
1868
- prop->chartype == ucp_Lt;
2001
+ chartype = prop->chartype;
2002
+ OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
1869
2003
  break;
1870
2004
 
1871
2005
  case PT_GC:
@@ -1880,11 +2014,18 @@ for (;;)
1880
2014
  OK = prop->script == code[1 + IMM2_SIZE + 2];
1881
2015
  break;
1882
2016
 
2017
+ case PT_SCX:
2018
+ OK = (prop->script == code[1 + IMM2_SIZE + 2] ||
2019
+ MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop),
2020
+ code[1 + IMM2_SIZE + 2]) != 0);
2021
+ break;
2022
+
1883
2023
  /* These are specials for combination cases. */
1884
2024
 
1885
2025
  case PT_ALNUM:
1886
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
1887
- PRIV(ucp_gentype)[prop->chartype] == ucp_N;
2026
+ chartype = prop->chartype;
2027
+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
2028
+ PRIV(ucp_gentype)[chartype] == ucp_N;
1888
2029
  break;
1889
2030
 
1890
2031
  /* Perl space used to exclude VT, but from Perl 5.18 it is included,
@@ -1907,12 +2048,20 @@ for (;;)
1907
2048
  break;
1908
2049
 
1909
2050
  case PT_WORD:
1910
- OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
1911
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
1912
- c == CHAR_UNDERSCORE;
2051
+ chartype = prop->chartype;
2052
+ OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
2053
+ PRIV(ucp_gentype)[chartype] == ucp_N ||
2054
+ chartype == ucp_Mn || chartype == ucp_Pc;
1913
2055
  break;
1914
2056
 
1915
2057
  case PT_CLIST:
2058
+ #if PCRE2_CODE_UNIT_WIDTH == 32
2059
+ if (c > MAX_UTF_CODE_POINT)
2060
+ {
2061
+ OK = FALSE;
2062
+ break;
2063
+ }
2064
+ #endif
1916
2065
  cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];
1917
2066
  for (;;)
1918
2067
  {
@@ -1927,6 +2076,15 @@ for (;;)
1927
2076
  c >= 0xe000;
1928
2077
  break;
1929
2078
 
2079
+ case PT_BIDICL:
2080
+ OK = UCD_BIDICLASS(c) == code[1 + IMM2_SIZE + 2];
2081
+ break;
2082
+
2083
+ case PT_BOOL:
2084
+ OK = MAPBIT(PRIV(ucd_boolprop_sets) +
2085
+ UCD_BPROPS_PROP(prop), code[1 + IMM2_SIZE + 2]) != 0;
2086
+ break;
2087
+
1930
2088
  /* Should never occur, but keep compilers from grumbling. */
1931
2089
 
1932
2090
  default:
@@ -1959,26 +2117,16 @@ for (;;)
1959
2117
  count = current_state->count; /* Number already matched */
1960
2118
  if (clen > 0)
1961
2119
  {
1962
- int lgb, rgb;
1963
- const pcre_uchar *nptr = ptr + clen;
2120
+ PCRE2_SPTR nptr;
1964
2121
  int ncount = 0;
1965
2122
  if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
1966
2123
  {
1967
2124
  active_count--; /* Remove non-match possibility */
1968
2125
  next_active_state--;
1969
2126
  }
1970
- lgb = UCD_GRAPHBREAK(c);
1971
- while (nptr < end_subject)
1972
- {
1973
- dlen = 1;
1974
- if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1975
- rgb = UCD_GRAPHBREAK(d);
1976
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1977
- ncount++;
1978
- lgb = rgb;
1979
- nptr += dlen;
1980
- }
1981
- if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
2127
+ nptr = PRIV(extuni)(c, ptr + clen, mb->start_subject, end_subject, utf,
2128
+ &ncount);
2129
+ if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
1982
2130
  reset_could_continue = TRUE;
1983
2131
  if (++count >= (int)GET2(code, 1))
1984
2132
  { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
@@ -2008,7 +2156,7 @@ for (;;)
2008
2156
  case 0x2028:
2009
2157
  case 0x2029:
2010
2158
  #endif /* Not EBCDIC */
2011
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
2159
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
2012
2160
  goto ANYNL03;
2013
2161
 
2014
2162
  case CHAR_CR:
@@ -2122,8 +2270,8 @@ for (;;)
2122
2270
  case OP_CHARI:
2123
2271
  if (clen == 0) break;
2124
2272
 
2125
- #ifdef SUPPORT_UTF
2126
- if (utf)
2273
+ #ifdef SUPPORT_UNICODE
2274
+ if (utf_or_ucp)
2127
2275
  {
2128
2276
  if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
2129
2277
  {
@@ -2131,20 +2279,13 @@ for (;;)
2131
2279
  if (c < 128)
2132
2280
  othercase = fcc[c];
2133
2281
  else
2134
- /* If we have Unicode property support, we can use it to test the
2135
- other case of the character. */
2136
- #ifdef SUPPORT_UCP
2137
2282
  othercase = UCD_OTHERCASE(c);
2138
- #else
2139
- othercase = NOTACHAR;
2140
- #endif
2141
-
2142
2283
  if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }
2143
2284
  }
2144
2285
  }
2145
2286
  else
2146
- #endif /* SUPPORT_UTF */
2147
- /* Not UTF mode */
2287
+ #endif /* SUPPORT_UNICODE */
2288
+ /* Not UTF or UCP mode */
2148
2289
  {
2149
2290
  if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))
2150
2291
  { ADD_NEW(state_offset + 2, 0); }
@@ -2152,7 +2293,7 @@ for (;;)
2152
2293
  break;
2153
2294
 
2154
2295
 
2155
- #ifdef SUPPORT_UCP
2296
+ #ifdef SUPPORT_UNICODE
2156
2297
  /*-----------------------------------------------------------------*/
2157
2298
  /* This is a tricky one because it can match more than one character.
2158
2299
  Find out how many characters to skip, and then set up a negative state
@@ -2161,21 +2302,10 @@ for (;;)
2161
2302
  case OP_EXTUNI:
2162
2303
  if (clen > 0)
2163
2304
  {
2164
- int lgb, rgb;
2165
- const pcre_uchar *nptr = ptr + clen;
2166
2305
  int ncount = 0;
2167
- lgb = UCD_GRAPHBREAK(c);
2168
- while (nptr < end_subject)
2169
- {
2170
- dlen = 1;
2171
- if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
2172
- rgb = UCD_GRAPHBREAK(d);
2173
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
2174
- ncount++;
2175
- lgb = rgb;
2176
- nptr += dlen;
2177
- }
2178
- if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
2306
+ PCRE2_SPTR nptr = PRIV(extuni)(c, ptr + clen, mb->start_subject,
2307
+ end_subject, utf, &ncount);
2308
+ if (nptr >= end_subject && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
2179
2309
  reset_could_continue = TRUE;
2180
2310
  ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
2181
2311
  }
@@ -2197,7 +2327,8 @@ for (;;)
2197
2327
  case 0x2028:
2198
2328
  case 0x2029:
2199
2329
  #endif /* Not EBCDIC */
2200
- if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
2330
+ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
2331
+ PCRE2_FALLTHROUGH /* Fall through */
2201
2332
 
2202
2333
  case CHAR_LF:
2203
2334
  ADD_NEW(state_offset + 1, 0);
@@ -2207,7 +2338,7 @@ for (;;)
2207
2338
  if (ptr + 1 >= end_subject)
2208
2339
  {
2209
2340
  ADD_NEW(state_offset + 1, 0);
2210
- if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
2341
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
2211
2342
  reset_could_continue = TRUE;
2212
2343
  }
2213
2344
  else if (UCHAR21TEST(ptr + 1) == CHAR_LF)
@@ -2287,18 +2418,12 @@ for (;;)
2287
2418
  case OP_NOTI:
2288
2419
  if (clen > 0)
2289
2420
  {
2290
- pcre_uint32 otherd;
2291
- #ifdef SUPPORT_UTF
2292
- if (utf && d >= 128)
2293
- {
2294
- #ifdef SUPPORT_UCP
2421
+ uint32_t otherd;
2422
+ #ifdef SUPPORT_UNICODE
2423
+ if (utf_or_ucp && d >= 128)
2295
2424
  otherd = UCD_OTHERCASE(d);
2296
- #else
2297
- otherd = d;
2298
- #endif /* SUPPORT_UCP */
2299
- }
2300
2425
  else
2301
- #endif /* SUPPORT_UTF */
2426
+ #endif /* SUPPORT_UNICODE */
2302
2427
  otherd = TABLE_GET(d, fcc, d);
2303
2428
  if (c != d && c != otherd)
2304
2429
  { ADD_NEW(state_offset + dlen + 1, 0); }
@@ -2315,7 +2440,7 @@ for (;;)
2315
2440
  caseless = TRUE;
2316
2441
  codevalue -= OP_STARI - OP_STAR;
2317
2442
 
2318
- /* Fall through */
2443
+ PCRE2_FALLTHROUGH /* Fall through */
2319
2444
  case OP_PLUS:
2320
2445
  case OP_MINPLUS:
2321
2446
  case OP_POSPLUS:
@@ -2326,18 +2451,14 @@ for (;;)
2326
2451
  if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
2327
2452
  if (clen > 0)
2328
2453
  {
2329
- pcre_uint32 otherd = NOTACHAR;
2454
+ uint32_t otherd = NOTACHAR;
2330
2455
  if (caseless)
2331
2456
  {
2332
- #ifdef SUPPORT_UTF
2333
- if (utf && d >= 128)
2334
- {
2335
- #ifdef SUPPORT_UCP
2457
+ #ifdef SUPPORT_UNICODE
2458
+ if (utf_or_ucp && d >= 128)
2336
2459
  otherd = UCD_OTHERCASE(d);
2337
- #endif /* SUPPORT_UCP */
2338
- }
2339
2460
  else
2340
- #endif /* SUPPORT_UTF */
2461
+ #endif /* SUPPORT_UNICODE */
2341
2462
  otherd = TABLE_GET(d, fcc, d);
2342
2463
  }
2343
2464
  if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
@@ -2363,7 +2484,7 @@ for (;;)
2363
2484
  case OP_NOTPOSQUERYI:
2364
2485
  caseless = TRUE;
2365
2486
  codevalue -= OP_STARI - OP_STAR;
2366
- /* Fall through */
2487
+ PCRE2_FALLTHROUGH /* Fall through */
2367
2488
  case OP_QUERY:
2368
2489
  case OP_MINQUERY:
2369
2490
  case OP_POSQUERY:
@@ -2373,18 +2494,14 @@ for (;;)
2373
2494
  ADD_ACTIVE(state_offset + dlen + 1, 0);
2374
2495
  if (clen > 0)
2375
2496
  {
2376
- pcre_uint32 otherd = NOTACHAR;
2497
+ uint32_t otherd = NOTACHAR;
2377
2498
  if (caseless)
2378
2499
  {
2379
- #ifdef SUPPORT_UTF
2380
- if (utf && d >= 128)
2381
- {
2382
- #ifdef SUPPORT_UCP
2500
+ #ifdef SUPPORT_UNICODE
2501
+ if (utf_or_ucp && d >= 128)
2383
2502
  otherd = UCD_OTHERCASE(d);
2384
- #endif /* SUPPORT_UCP */
2385
- }
2386
2503
  else
2387
- #endif /* SUPPORT_UTF */
2504
+ #endif /* SUPPORT_UNICODE */
2388
2505
  otherd = TABLE_GET(d, fcc, d);
2389
2506
  }
2390
2507
  if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
@@ -2408,7 +2525,7 @@ for (;;)
2408
2525
  case OP_NOTPOSSTARI:
2409
2526
  caseless = TRUE;
2410
2527
  codevalue -= OP_STARI - OP_STAR;
2411
- /* Fall through */
2528
+ PCRE2_FALLTHROUGH /* Fall through */
2412
2529
  case OP_STAR:
2413
2530
  case OP_MINSTAR:
2414
2531
  case OP_POSSTAR:
@@ -2418,18 +2535,14 @@ for (;;)
2418
2535
  ADD_ACTIVE(state_offset + dlen + 1, 0);
2419
2536
  if (clen > 0)
2420
2537
  {
2421
- pcre_uint32 otherd = NOTACHAR;
2538
+ uint32_t otherd = NOTACHAR;
2422
2539
  if (caseless)
2423
2540
  {
2424
- #ifdef SUPPORT_UTF
2425
- if (utf && d >= 128)
2426
- {
2427
- #ifdef SUPPORT_UCP
2541
+ #ifdef SUPPORT_UNICODE
2542
+ if (utf_or_ucp && d >= 128)
2428
2543
  otherd = UCD_OTHERCASE(d);
2429
- #endif /* SUPPORT_UCP */
2430
- }
2431
2544
  else
2432
- #endif /* SUPPORT_UTF */
2545
+ #endif /* SUPPORT_UNICODE */
2433
2546
  otherd = TABLE_GET(d, fcc, d);
2434
2547
  }
2435
2548
  if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
@@ -2449,24 +2562,20 @@ for (;;)
2449
2562
  case OP_NOTEXACTI:
2450
2563
  caseless = TRUE;
2451
2564
  codevalue -= OP_STARI - OP_STAR;
2452
- /* Fall through */
2565
+ PCRE2_FALLTHROUGH /* Fall through */
2453
2566
  case OP_EXACT:
2454
2567
  case OP_NOTEXACT:
2455
2568
  count = current_state->count; /* Number already matched */
2456
2569
  if (clen > 0)
2457
2570
  {
2458
- pcre_uint32 otherd = NOTACHAR;
2571
+ uint32_t otherd = NOTACHAR;
2459
2572
  if (caseless)
2460
2573
  {
2461
- #ifdef SUPPORT_UTF
2462
- if (utf && d >= 128)
2463
- {
2464
- #ifdef SUPPORT_UCP
2574
+ #ifdef SUPPORT_UNICODE
2575
+ if (utf_or_ucp && d >= 128)
2465
2576
  otherd = UCD_OTHERCASE(d);
2466
- #endif /* SUPPORT_UCP */
2467
- }
2468
2577
  else
2469
- #endif /* SUPPORT_UTF */
2578
+ #endif /* SUPPORT_UNICODE */
2470
2579
  otherd = TABLE_GET(d, fcc, d);
2471
2580
  }
2472
2581
  if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
@@ -2488,7 +2597,7 @@ for (;;)
2488
2597
  case OP_NOTPOSUPTOI:
2489
2598
  caseless = TRUE;
2490
2599
  codevalue -= OP_STARI - OP_STAR;
2491
- /* Fall through */
2600
+ PCRE2_FALLTHROUGH /* Fall through */
2492
2601
  case OP_UPTO:
2493
2602
  case OP_MINUPTO:
2494
2603
  case OP_POSUPTO:
@@ -2499,18 +2608,14 @@ for (;;)
2499
2608
  count = current_state->count; /* Number already matched */
2500
2609
  if (clen > 0)
2501
2610
  {
2502
- pcre_uint32 otherd = NOTACHAR;
2611
+ uint32_t otherd = NOTACHAR;
2503
2612
  if (caseless)
2504
2613
  {
2505
- #ifdef SUPPORT_UTF
2506
- if (utf && d >= 128)
2507
- {
2508
- #ifdef SUPPORT_UCP
2614
+ #ifdef SUPPORT_UNICODE
2615
+ if (utf_or_ucp && d >= 128)
2509
2616
  otherd = UCD_OTHERCASE(d);
2510
- #endif /* SUPPORT_UCP */
2511
- }
2512
2617
  else
2513
- #endif /* SUPPORT_UTF */
2618
+ #endif /* SUPPORT_UNICODE */
2514
2619
  otherd = TABLE_GET(d, fcc, d);
2515
2620
  }
2516
2621
  if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
@@ -2534,35 +2639,54 @@ for (;;)
2534
2639
 
2535
2640
  case OP_CLASS:
2536
2641
  case OP_NCLASS:
2642
+ #ifdef SUPPORT_WIDE_CHARS
2537
2643
  case OP_XCLASS:
2644
+ case OP_ECLASS:
2645
+ #endif
2538
2646
  {
2539
2647
  BOOL isinclass = FALSE;
2540
2648
  int next_state_offset;
2541
- const pcre_uchar *ecode;
2649
+ PCRE2_SPTR ecode;
2650
+
2651
+ #ifdef SUPPORT_WIDE_CHARS
2652
+ /* An extended class may have a table or a list of single characters,
2653
+ ranges, or both, and it may be positive or negative. There's a
2654
+ function that sorts all this out. */
2655
+
2656
+ if (codevalue == OP_XCLASS)
2657
+ {
2658
+ ecode = code + GET(code, 1);
2659
+ if (clen > 0)
2660
+ isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE,
2661
+ (const uint8_t*)mb->start_code, utf);
2662
+ }
2663
+
2664
+ /* A nested set-based class has internal opcodes for performing
2665
+ set operations. */
2666
+
2667
+ else if (codevalue == OP_ECLASS)
2668
+ {
2669
+ ecode = code + GET(code, 1);
2670
+ if (clen > 0)
2671
+ isinclass = PRIV(eclass)(c, code + 1 + LINK_SIZE, ecode,
2672
+ (const uint8_t*)mb->start_code, utf);
2673
+ }
2674
+
2675
+ else
2676
+ #endif /* SUPPORT_WIDE_CHARS */
2542
2677
 
2543
2678
  /* For a simple class, there is always just a 32-byte table, and we
2544
2679
  can set isinclass from it. */
2545
2680
 
2546
- if (codevalue != OP_XCLASS)
2547
2681
  {
2548
- ecode = code + 1 + (32 / sizeof(pcre_uchar));
2682
+ ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR));
2549
2683
  if (clen > 0)
2550
2684
  {
2551
2685
  isinclass = (c > 255)? (codevalue == OP_NCLASS) :
2552
- ((((pcre_uint8 *)(code + 1))[c/8] & (1 << (c&7))) != 0);
2686
+ ((((const uint8_t *)(code + 1))[c/8] & (1u << (c&7))) != 0);
2553
2687
  }
2554
2688
  }
2555
2689
 
2556
- /* An extended class may have a table or a list of single characters,
2557
- ranges, or both, and it may be positive or negative. There's a
2558
- function that sorts all this out. */
2559
-
2560
- else
2561
- {
2562
- ecode = code + GET(code, 1);
2563
- if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf);
2564
- }
2565
-
2566
2690
  /* At this point, isinclass is set for all kinds of class, and ecode
2567
2691
  points to the byte after the end of the class. If there is a
2568
2692
  quantifier, this is where it will be. */
@@ -2627,11 +2751,13 @@ for (;;)
2627
2751
  if (isinclass)
2628
2752
  {
2629
2753
  int max = (int)GET2(ecode, 1 + IMM2_SIZE);
2754
+
2630
2755
  if (*ecode == OP_CRPOSRANGE && count >= (int)GET2(ecode, 1))
2631
2756
  {
2632
2757
  active_count--; /* Remove non-match possibility */
2633
2758
  next_active_state--;
2634
2759
  }
2760
+
2635
2761
  if (++count >= max && max != 0) /* Max 0 => no limit */
2636
2762
  { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
2637
2763
  else
@@ -2653,7 +2779,6 @@ for (;;)
2653
2779
  though the other "backtracking verbs" are not supported. */
2654
2780
 
2655
2781
  case OP_FAIL:
2656
- forced_fail++; /* Count FAILs for multiple states */
2657
2782
  break;
2658
2783
 
2659
2784
  case OP_ASSERT:
@@ -2662,24 +2787,39 @@ for (;;)
2662
2787
  case OP_ASSERTBACK_NOT:
2663
2788
  {
2664
2789
  int rc;
2665
- int local_offsets[2];
2666
- int local_workspace[1000];
2667
- const pcre_uchar *endasscode = code + GET(code, 1);
2790
+ int *local_workspace;
2791
+ PCRE2_SIZE *local_offsets;
2792
+ PCRE2_SPTR endasscode = code + GET(code, 1);
2793
+ RWS_anchor *rws = (RWS_anchor *)RWS;
2794
+
2795
+ if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)
2796
+ {
2797
+ rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);
2798
+ if (rc != 0) return rc;
2799
+ RWS = (int *)rws;
2800
+ }
2801
+
2802
+ local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
2803
+ local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
2804
+ rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
2668
2805
 
2669
2806
  while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
2670
2807
 
2671
- rc = internal_dfa_exec(
2672
- md, /* static match data */
2808
+ rc = internal_dfa_match(
2809
+ mb, /* static match data */
2673
2810
  code, /* this subexpression's code */
2674
2811
  ptr, /* where we currently are */
2675
- (int)(ptr - start_subject), /* start offset */
2812
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
2676
2813
  local_offsets, /* offset vector */
2677
- sizeof(local_offsets)/sizeof(int), /* size of same */
2814
+ RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
2678
2815
  local_workspace, /* workspace vector */
2679
- sizeof(local_workspace)/sizeof(int), /* size of same */
2680
- rlevel); /* function recursion level */
2816
+ RWS_RSIZE, /* size of same */
2817
+ rlevel, /* function recursion level */
2818
+ RWS); /* recursion workspace */
2819
+
2820
+ rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;
2681
2821
 
2682
- if (rc == PCRE_ERROR_DFA_UITEM) return rc;
2822
+ if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;
2683
2823
  if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
2684
2824
  { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
2685
2825
  }
@@ -2689,44 +2829,22 @@ for (;;)
2689
2829
  case OP_COND:
2690
2830
  case OP_SCOND:
2691
2831
  {
2692
- int local_offsets[1000];
2693
- int local_workspace[1000];
2694
- int codelink = GET(code, 1);
2695
- int condcode;
2832
+ int codelink = (int)GET(code, 1);
2833
+ PCRE2_UCHAR condcode;
2696
2834
 
2697
2835
  /* Because of the way auto-callout works during compile, a callout item
2698
2836
  is inserted between OP_COND and an assertion condition. This does not
2699
2837
  happen for the other conditions. */
2700
2838
 
2701
- if (code[LINK_SIZE+1] == OP_CALLOUT)
2839
+ if (code[LINK_SIZE + 1] == OP_CALLOUT
2840
+ || code[LINK_SIZE + 1] == OP_CALLOUT_STR)
2702
2841
  {
2703
- rrc = 0;
2704
- if (PUBL(callout) != NULL)
2705
- {
2706
- PUBL(callout_block) cb;
2707
- cb.version = 1; /* Version 1 of the callout block */
2708
- cb.callout_number = code[LINK_SIZE+2];
2709
- cb.offset_vector = offsets;
2710
- #if defined COMPILE_PCRE8
2711
- cb.subject = (PCRE_SPTR)start_subject;
2712
- #elif defined COMPILE_PCRE16
2713
- cb.subject = (PCRE_SPTR16)start_subject;
2714
- #elif defined COMPILE_PCRE32
2715
- cb.subject = (PCRE_SPTR32)start_subject;
2716
- #endif
2717
- cb.subject_length = (int)(end_subject - start_subject);
2718
- cb.start_match = (int)(current_subject - start_subject);
2719
- cb.current_position = (int)(ptr - start_subject);
2720
- cb.pattern_position = GET(code, LINK_SIZE + 3);
2721
- cb.next_item_length = GET(code, 3 + 2*LINK_SIZE);
2722
- cb.capture_top = 1;
2723
- cb.capture_last = -1;
2724
- cb.callout_data = md->callout_data;
2725
- cb.mark = NULL; /* No (*MARK) support */
2726
- if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
2727
- }
2842
+ PCRE2_SIZE callout_length;
2843
+ rrc = do_callout_dfa(code, offsets, current_subject, ptr, mb,
2844
+ 1 + LINK_SIZE, &callout_length);
2845
+ if (rrc < 0) return rrc; /* Abandon */
2728
2846
  if (rrc > 0) break; /* Fail this thread */
2729
- code += PRIV(OP_lengths)[OP_CALLOUT]; /* Skip callout data */
2847
+ code += callout_length; /* Skip callout data */
2730
2848
  }
2731
2849
 
2732
2850
  condcode = code[LINK_SIZE+1];
@@ -2736,23 +2854,28 @@ for (;;)
2736
2854
 
2737
2855
  if (condcode == OP_CREF || condcode == OP_DNCREF ||
2738
2856
  condcode == OP_DNRREF)
2739
- return PCRE_ERROR_DFA_UCOND;
2857
+ return PCRE2_ERROR_DFA_UCOND;
2740
2858
 
2741
2859
  /* The DEFINE condition is always false, and the assertion (?!) is
2742
2860
  converted to OP_FAIL. */
2743
2861
 
2744
- if (condcode == OP_DEF || condcode == OP_FAIL)
2862
+ if (condcode == OP_FALSE || condcode == OP_FAIL)
2745
2863
  { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
2746
2864
 
2865
+ /* There is also an always-true condition */
2866
+
2867
+ else if (condcode == OP_TRUE)
2868
+ { ADD_ACTIVE(state_offset + LINK_SIZE + 2, 0); }
2869
+
2747
2870
  /* The only supported version of OP_RREF is for the value RREF_ANY,
2748
2871
  which means "test if in any recursion". We can't test for specifically
2749
2872
  recursed groups. */
2750
2873
 
2751
2874
  else if (condcode == OP_RREF)
2752
2875
  {
2753
- int value = GET2(code, LINK_SIZE + 2);
2754
- if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
2755
- if (md->recursive != NULL)
2876
+ unsigned int value = GET2(code, LINK_SIZE + 2);
2877
+ if (value != RREF_ANY) return PCRE2_ERROR_DFA_UCOND;
2878
+ if (mb->recursive != NULL)
2756
2879
  { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }
2757
2880
  else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
2758
2881
  }
@@ -2762,23 +2885,40 @@ for (;;)
2762
2885
  else
2763
2886
  {
2764
2887
  int rc;
2765
- const pcre_uchar *asscode = code + LINK_SIZE + 1;
2766
- const pcre_uchar *endasscode = asscode + GET(asscode, 1);
2888
+ int *local_workspace;
2889
+ PCRE2_SIZE *local_offsets;
2890
+ PCRE2_SPTR asscode = code + LINK_SIZE + 1;
2891
+ PCRE2_SPTR endasscode = asscode + GET(asscode, 1);
2892
+ RWS_anchor *rws = (RWS_anchor *)RWS;
2893
+
2894
+ if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)
2895
+ {
2896
+ rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);
2897
+ if (rc != 0) return rc;
2898
+ RWS = (int *)rws;
2899
+ }
2900
+
2901
+ local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
2902
+ local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
2903
+ rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
2767
2904
 
2768
2905
  while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
2769
2906
 
2770
- rc = internal_dfa_exec(
2771
- md, /* fixed match data */
2907
+ rc = internal_dfa_match(
2908
+ mb, /* fixed match data */
2772
2909
  asscode, /* this subexpression's code */
2773
2910
  ptr, /* where we currently are */
2774
- (int)(ptr - start_subject), /* start offset */
2911
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
2775
2912
  local_offsets, /* offset vector */
2776
- sizeof(local_offsets)/sizeof(int), /* size of same */
2913
+ RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
2777
2914
  local_workspace, /* workspace vector */
2778
- sizeof(local_workspace)/sizeof(int), /* size of same */
2779
- rlevel); /* function recursion level */
2915
+ RWS_RSIZE, /* size of same */
2916
+ rlevel, /* function recursion level */
2917
+ RWS); /* recursion workspace */
2918
+
2919
+ rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;
2780
2920
 
2781
- if (rc == PCRE_ERROR_DFA_UITEM) return rc;
2921
+ if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc;
2782
2922
  if ((rc >= 0) ==
2783
2923
  (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
2784
2924
  { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
@@ -2791,51 +2931,69 @@ for (;;)
2791
2931
  /*-----------------------------------------------------------------*/
2792
2932
  case OP_RECURSE:
2793
2933
  {
2794
- dfa_recursion_info *ri;
2795
- int local_offsets[1000];
2796
- int local_workspace[1000];
2797
- const pcre_uchar *callpat = start_code + GET(code, 1);
2798
- int recno = (callpat == md->start_code)? 0 :
2799
- GET2(callpat, 1 + LINK_SIZE);
2800
2934
  int rc;
2935
+ int *local_workspace;
2936
+ dfa_recursion_info *ri;
2937
+ PCRE2_SIZE *local_offsets;
2938
+ RWS_anchor *rws = (RWS_anchor *)RWS;
2939
+ PCRE2_SPTR callpat = start_code + GET(code, 1);
2940
+ uint32_t recno = (callpat == mb->start_code)? 0 :
2941
+ GET2(callpat, 1 + LINK_SIZE);
2942
+
2943
+ /* Argument list has not been supported yet. */
2944
+ if (code[1 + LINK_SIZE] == OP_CREF) return PCRE2_ERROR_DFA_UITEM;
2945
+
2946
+ if (rws->free < RWS_RSIZE + RWS_OVEC_RSIZE)
2947
+ {
2948
+ rc = more_workspace(&rws, RWS_OVEC_RSIZE, mb);
2949
+ if (rc != 0) return rc;
2950
+ RWS = (int *)rws;
2951
+ }
2801
2952
 
2802
- DPRINTF(("%.*sStarting regex recursion\n", rlevel*2-2, SP));
2953
+ local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
2954
+ local_workspace = ((int *)local_offsets) + RWS_OVEC_RSIZE;
2955
+ rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE;
2803
2956
 
2804
2957
  /* Check for repeating a recursion without advancing the subject
2805
- pointer. This should catch convoluted mutual recursions. (Some simple
2806
- cases are caught at compile time.) */
2958
+ pointer or last used character. This should catch convoluted mutual
2959
+ recursions. (Some simple cases are caught at compile time.) */
2807
2960
 
2808
- for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
2809
- if (recno == ri->group_num && ptr == ri->subject_position)
2810
- return PCRE_ERROR_RECURSELOOP;
2961
+ for (ri = mb->recursive;
2962
+ ri != NULL;
2963
+ ri = ri->prevrec)
2964
+ {
2965
+ if (recno == ri->group_num && ptr == ri->subject_position &&
2966
+ mb->last_used_ptr == ri->last_used_ptr)
2967
+ return PCRE2_ERROR_RECURSELOOP;
2968
+ }
2811
2969
 
2812
2970
  /* Remember this recursion and where we started it so as to
2813
2971
  catch infinite loops. */
2814
2972
 
2815
2973
  new_recursive.group_num = recno;
2816
2974
  new_recursive.subject_position = ptr;
2817
- new_recursive.prevrec = md->recursive;
2818
- md->recursive = &new_recursive;
2975
+ new_recursive.last_used_ptr = mb->last_used_ptr;
2976
+ new_recursive.prevrec = mb->recursive;
2977
+ mb->recursive = &new_recursive;
2819
2978
 
2820
- rc = internal_dfa_exec(
2821
- md, /* fixed match data */
2979
+ rc = internal_dfa_match(
2980
+ mb, /* fixed match data */
2822
2981
  callpat, /* this subexpression's code */
2823
2982
  ptr, /* where we currently are */
2824
- (int)(ptr - start_subject), /* start offset */
2983
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
2825
2984
  local_offsets, /* offset vector */
2826
- sizeof(local_offsets)/sizeof(int), /* size of same */
2985
+ RWS_OVEC_RSIZE/OVEC_UNIT, /* size of same */
2827
2986
  local_workspace, /* workspace vector */
2828
- sizeof(local_workspace)/sizeof(int), /* size of same */
2829
- rlevel); /* function recursion level */
2830
-
2831
- md->recursive = new_recursive.prevrec; /* Done this recursion */
2987
+ RWS_RSIZE, /* size of same */
2988
+ rlevel, /* function recursion level */
2989
+ RWS); /* recursion workspace */
2832
2990
 
2833
- DPRINTF(("%.*sReturn from regex recursion: rc=%d\n", rlevel*2-2, SP,
2834
- rc));
2991
+ rws->free += RWS_RSIZE + RWS_OVEC_RSIZE;
2992
+ mb->recursive = new_recursive.prevrec; /* Done this recursion */
2835
2993
 
2836
2994
  /* Ran out of internal offsets */
2837
2995
 
2838
- if (rc == 0) return PCRE_ERROR_DFA_RECURSE;
2996
+ if (rc == 0) return PCRE2_ERROR_DFA_RECURSE;
2839
2997
 
2840
2998
  /* For each successful matched substring, set up the next state with a
2841
2999
  count of characters to skip before trying it. Note that the count is in
@@ -2845,18 +3003,19 @@ for (;;)
2845
3003
  {
2846
3004
  for (rc = rc*2 - 2; rc >= 0; rc -= 2)
2847
3005
  {
2848
- int charcount = local_offsets[rc+1] - local_offsets[rc];
2849
- #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3006
+ PCRE2_SIZE charcount = local_offsets[rc+1] - local_offsets[rc];
3007
+ #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
2850
3008
  if (utf)
2851
3009
  {
2852
- const pcre_uchar *p = start_subject + local_offsets[rc];
2853
- const pcre_uchar *pp = start_subject + local_offsets[rc+1];
2854
- while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
3010
+ PCRE2_SPTR p = start_subject + local_offsets[rc];
3011
+ PCRE2_SPTR pp = start_subject + local_offsets[rc+1];
3012
+ while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;
2855
3013
  }
2856
3014
  #endif
2857
3015
  if (charcount > 0)
2858
3016
  {
2859
- ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1));
3017
+ ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0,
3018
+ (int)(charcount - 1));
2860
3019
  }
2861
3020
  else
2862
3021
  {
@@ -2864,7 +3023,7 @@ for (;;)
2864
3023
  }
2865
3024
  }
2866
3025
  }
2867
- else if (rc != PCRE_ERROR_NOMATCH) return rc;
3026
+ else if (rc != PCRE2_ERROR_NOMATCH) return rc;
2868
3027
  }
2869
3028
  break;
2870
3029
 
@@ -2875,14 +3034,29 @@ for (;;)
2875
3034
  case OP_SCBRAPOS:
2876
3035
  case OP_BRAPOSZERO:
2877
3036
  {
2878
- int charcount, matched_count;
2879
- const pcre_uchar *local_ptr = ptr;
3037
+ int rc;
3038
+ int *local_workspace;
3039
+ PCRE2_SIZE *local_offsets;
3040
+ PCRE2_SIZE charcount, matched_count;
3041
+ PCRE2_SPTR local_ptr = ptr;
3042
+ RWS_anchor *rws = (RWS_anchor *)RWS;
2880
3043
  BOOL allow_zero;
2881
3044
 
3045
+ if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)
3046
+ {
3047
+ rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);
3048
+ if (rc != 0) return rc;
3049
+ RWS = (int *)rws;
3050
+ }
3051
+
3052
+ local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
3053
+ local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
3054
+ rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
3055
+
2882
3056
  if (codevalue == OP_BRAPOSZERO)
2883
3057
  {
2884
3058
  allow_zero = TRUE;
2885
- codevalue = *(++code); /* Codevalue will be one of above BRAs */
3059
+ ++code; /* The following opcode will be one of the above BRAs */
2886
3060
  }
2887
3061
  else allow_zero = FALSE;
2888
3062
 
@@ -2891,25 +3065,23 @@ for (;;)
2891
3065
 
2892
3066
  for (matched_count = 0;; matched_count++)
2893
3067
  {
2894
- int local_offsets[2];
2895
- int local_workspace[1000];
2896
-
2897
- int rc = internal_dfa_exec(
2898
- md, /* fixed match data */
3068
+ rc = internal_dfa_match(
3069
+ mb, /* fixed match data */
2899
3070
  code, /* this subexpression's code */
2900
3071
  local_ptr, /* where we currently are */
2901
- (int)(ptr - start_subject), /* start offset */
3072
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
2902
3073
  local_offsets, /* offset vector */
2903
- sizeof(local_offsets)/sizeof(int), /* size of same */
3074
+ RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
2904
3075
  local_workspace, /* workspace vector */
2905
- sizeof(local_workspace)/sizeof(int), /* size of same */
2906
- rlevel); /* function recursion level */
3076
+ RWS_RSIZE, /* size of same */
3077
+ rlevel, /* function recursion level */
3078
+ RWS); /* recursion workspace */
2907
3079
 
2908
3080
  /* Failed to match */
2909
3081
 
2910
3082
  if (rc < 0)
2911
3083
  {
2912
- if (rc != PCRE_ERROR_NOMATCH) return rc;
3084
+ if (rc != PCRE2_ERROR_NOMATCH) return rc;
2913
3085
  break;
2914
3086
  }
2915
3087
 
@@ -2920,13 +3092,15 @@ for (;;)
2920
3092
  local_ptr += charcount; /* Advance temporary position ptr */
2921
3093
  }
2922
3094
 
3095
+ rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;
3096
+
2923
3097
  /* At this point we have matched the subpattern matched_count
2924
3098
  times, and local_ptr is pointing to the character after the end of the
2925
3099
  last match. */
2926
3100
 
2927
3101
  if (matched_count > 0 || allow_zero)
2928
3102
  {
2929
- const pcre_uchar *end_subpattern = code;
3103
+ PCRE2_SPTR end_subpattern = code;
2930
3104
  int next_state_offset;
2931
3105
 
2932
3106
  do { end_subpattern += GET(end_subpattern, 1); }
@@ -2947,13 +3121,13 @@ for (;;)
2947
3121
  }
2948
3122
  else
2949
3123
  {
2950
- const pcre_uchar *p = ptr;
2951
- const pcre_uchar *pp = local_ptr;
2952
- charcount = (int)(pp - p);
2953
- #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2954
- if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
3124
+ PCRE2_SPTR p = ptr;
3125
+ PCRE2_SPTR pp = local_ptr;
3126
+ charcount = (PCRE2_SIZE)(pp - p);
3127
+ #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
3128
+ if (utf) while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;
2955
3129
  #endif
2956
- ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
3130
+ ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));
2957
3131
  }
2958
3132
  }
2959
3133
  }
@@ -2961,26 +3135,41 @@ for (;;)
2961
3135
 
2962
3136
  /*-----------------------------------------------------------------*/
2963
3137
  case OP_ONCE:
2964
- case OP_ONCE_NC:
2965
3138
  {
2966
- int local_offsets[2];
2967
- int local_workspace[1000];
3139
+ int rc;
3140
+ int *local_workspace;
3141
+ PCRE2_SIZE *local_offsets;
3142
+ RWS_anchor *rws = (RWS_anchor *)RWS;
3143
+
3144
+ if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE)
3145
+ {
3146
+ rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb);
3147
+ if (rc != 0) return rc;
3148
+ RWS = (int *)rws;
3149
+ }
3150
+
3151
+ local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free);
3152
+ local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE;
3153
+ rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE;
2968
3154
 
2969
- int rc = internal_dfa_exec(
2970
- md, /* fixed match data */
3155
+ rc = internal_dfa_match(
3156
+ mb, /* fixed match data */
2971
3157
  code, /* this subexpression's code */
2972
3158
  ptr, /* where we currently are */
2973
- (int)(ptr - start_subject), /* start offset */
3159
+ (PCRE2_SIZE)(ptr - start_subject), /* start offset */
2974
3160
  local_offsets, /* offset vector */
2975
- sizeof(local_offsets)/sizeof(int), /* size of same */
3161
+ RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
2976
3162
  local_workspace, /* workspace vector */
2977
- sizeof(local_workspace)/sizeof(int), /* size of same */
2978
- rlevel); /* function recursion level */
3163
+ RWS_RSIZE, /* size of same */
3164
+ rlevel, /* function recursion level */
3165
+ RWS); /* recursion workspace */
3166
+
3167
+ rws->free += RWS_RSIZE + RWS_OVEC_OSIZE;
2979
3168
 
2980
3169
  if (rc >= 0)
2981
3170
  {
2982
- const pcre_uchar *end_subpattern = code;
2983
- int charcount = local_offsets[1] - local_offsets[0];
3171
+ PCRE2_SPTR end_subpattern = code;
3172
+ PCRE2_SIZE charcount = local_offsets[1] - local_offsets[0];
2984
3173
  int next_state_offset, repeat_state_offset;
2985
3174
 
2986
3175
  do { end_subpattern += GET(end_subpattern, 1); }
@@ -3032,20 +3221,20 @@ for (;;)
3032
3221
  }
3033
3222
  else
3034
3223
  {
3035
- #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3224
+ #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
3036
3225
  if (utf)
3037
3226
  {
3038
- const pcre_uchar *p = start_subject + local_offsets[0];
3039
- const pcre_uchar *pp = start_subject + local_offsets[1];
3040
- while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
3227
+ PCRE2_SPTR p = start_subject + local_offsets[0];
3228
+ PCRE2_SPTR pp = start_subject + local_offsets[1];
3229
+ while (p < pp) if (NOT_FIRSTCU(*p++)) charcount--;
3041
3230
  }
3042
3231
  #endif
3043
- ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
3232
+ ADD_NEW_DATA(-next_state_offset, 0, (int)(charcount - 1));
3044
3233
  if (repeat_state_offset >= 0)
3045
- { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); }
3234
+ { ADD_NEW_DATA(-repeat_state_offset, 0, (int)(charcount - 1)); }
3046
3235
  }
3047
3236
  }
3048
- else if (rc != PCRE_ERROR_NOMATCH) return rc;
3237
+ else if (rc != PCRE2_ERROR_NOMATCH) return rc;
3049
3238
  }
3050
3239
  break;
3051
3240
 
@@ -3054,39 +3243,21 @@ for (;;)
3054
3243
  /* Handle callouts */
3055
3244
 
3056
3245
  case OP_CALLOUT:
3057
- rrc = 0;
3058
- if (PUBL(callout) != NULL)
3246
+ case OP_CALLOUT_STR:
3059
3247
  {
3060
- PUBL(callout_block) cb;
3061
- cb.version = 1; /* Version 1 of the callout block */
3062
- cb.callout_number = code[1];
3063
- cb.offset_vector = offsets;
3064
- #if defined COMPILE_PCRE8
3065
- cb.subject = (PCRE_SPTR)start_subject;
3066
- #elif defined COMPILE_PCRE16
3067
- cb.subject = (PCRE_SPTR16)start_subject;
3068
- #elif defined COMPILE_PCRE32
3069
- cb.subject = (PCRE_SPTR32)start_subject;
3070
- #endif
3071
- cb.subject_length = (int)(end_subject - start_subject);
3072
- cb.start_match = (int)(current_subject - start_subject);
3073
- cb.current_position = (int)(ptr - start_subject);
3074
- cb.pattern_position = GET(code, 2);
3075
- cb.next_item_length = GET(code, 2 + LINK_SIZE);
3076
- cb.capture_top = 1;
3077
- cb.capture_last = -1;
3078
- cb.callout_data = md->callout_data;
3079
- cb.mark = NULL; /* No (*MARK) support */
3080
- if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
3248
+ PCRE2_SIZE callout_length;
3249
+ rrc = do_callout_dfa(code, offsets, current_subject, ptr, mb, 0,
3250
+ &callout_length);
3251
+ if (rrc < 0) return rrc; /* Abandon */
3252
+ if (rrc == 0)
3253
+ { ADD_ACTIVE(state_offset + (int)callout_length, 0); }
3081
3254
  }
3082
- if (rrc == 0)
3083
- { ADD_ACTIVE(state_offset + PRIV(OP_lengths)[OP_CALLOUT], 0); }
3084
3255
  break;
3085
3256
 
3086
3257
 
3087
3258
  /* ========================================================================== */
3088
3259
  default: /* Unsupported opcode */
3089
- return PCRE_ERROR_DFA_UITEM;
3260
+ return PCRE2_ERROR_DFA_UITEM;
3090
3261
  }
3091
3262
 
3092
3263
  NEXT_ACTIVE_STATE: continue;
@@ -3095,40 +3266,33 @@ for (;;)
3095
3266
 
3096
3267
  /* We have finished the processing at the current subject character. If no
3097
3268
  new states have been set for the next character, we have found all the
3098
- matches that we are going to find. If we are at the top level and partial
3099
- matching has been requested, check for appropriate conditions.
3100
-
3101
- The "forced_ fail" variable counts the number of (*F) encountered for the
3102
- character. If it is equal to the original active_count (saved in
3103
- workspace[1]) it means that (*F) was found on every active state. In this
3104
- case we don't want to give a partial match.
3269
+ matches that we are going to find. If partial matching has been requested,
3270
+ check for appropriate conditions.
3105
3271
 
3106
3272
  The "could_continue" variable is true if a state could have continued but
3107
3273
  for the fact that the end of the subject was reached. */
3108
3274
 
3109
3275
  if (new_count <= 0)
3110
3276
  {
3111
- if (rlevel == 1 && /* Top level, and */
3112
- could_continue && /* Some could go on, and */
3113
- forced_fail != workspace[1] && /* Not all forced fail & */
3277
+ if (could_continue && /* Some could go on, and */
3114
3278
  ( /* either... */
3115
- (md->moptions & PCRE_PARTIAL_HARD) != 0 /* Hard partial */
3279
+ (mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */
3116
3280
  || /* or... */
3117
- ((md->moptions & PCRE_PARTIAL_SOFT) != 0 && /* Soft partial and */
3118
- match_count < 0) /* no matches */
3281
+ ((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 && /* Soft partial and */
3282
+ match_count < 0) /* no matches */
3119
3283
  ) && /* And... */
3120
3284
  (
3121
- partial_newline || /* Either partial NL */
3122
- ( /* or ... */
3123
- ptr >= end_subject && /* End of subject and */
3124
- ptr > md->start_used_ptr) /* Inspected non-empty string */
3285
+ partial_newline || /* Either partial NL */
3286
+ ( /* or ... */
3287
+ ptr >= end_subject && /* End of subject and */
3288
+ ( /* either */
3289
+ ptr > mb->start_used_ptr || /* Inspected non-empty string */
3290
+ mb->allowemptypartial /* or pattern has lookbehind */
3291
+ ) /* or could match empty */
3125
3292
  )
3126
- )
3127
- match_count = PCRE_ERROR_PARTIAL;
3128
- DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
3129
- "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,
3130
- rlevel*2-2, SP));
3131
- break; /* In effect, "return", but see the comment below */
3293
+ ))
3294
+ match_count = PCRE2_ERROR_PARTIAL;
3295
+ break; /* Exit from loop along the subject string */
3132
3296
  }
3133
3297
 
3134
3298
  /* One or more states are active for the next character. */
@@ -3136,295 +3300,397 @@ for (;;)
3136
3300
  ptr += clen; /* Advance to next subject character */
3137
3301
  } /* Loop to move along the subject string */
3138
3302
 
3139
- /* Control gets here from "break" a few lines above. We do it this way because
3140
- if we use "return" above, we have compiler trouble. Some compilers warn if
3141
- there's nothing here because they think the function doesn't return a value. On
3142
- the other hand, if we put a dummy statement here, some more clever compilers
3143
- complain that it can't be reached. Sigh. */
3303
+ /* Control gets here from "break" a few lines above. If we have a match and
3304
+ PCRE2_ENDANCHORED is set, the match fails. */
3305
+
3306
+ if (match_count >= 0 &&
3307
+ ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0 &&
3308
+ ptr < end_subject)
3309
+ match_count = PCRE2_ERROR_NOMATCH;
3144
3310
 
3145
3311
  return match_count;
3146
3312
  }
3147
3313
 
3148
3314
 
3149
3315
 
3150
-
3151
3316
  /*************************************************
3152
- * Execute a Regular Expression - DFA engine *
3317
+ * Match a pattern using the DFA algorithm *
3153
3318
  *************************************************/
3154
3319
 
3155
- /* This external function applies a compiled re to a subject string using a DFA
3156
- engine. This function calls the internal function multiple times if the pattern
3157
- is not anchored.
3320
+ /* This function matches a compiled pattern to a subject string, using the
3321
+ alternate matching algorithm that finds all matches at once.
3158
3322
 
3159
3323
  Arguments:
3160
- argument_re points to the compiled expression
3161
- extra_data points to extra data or is NULL
3162
- subject points to the subject string
3163
- length length of subject string (may contain binary zeros)
3164
- start_offset where to start in the subject string
3165
- options option bits
3166
- offsets vector of match offsets
3167
- offsetcount size of same
3168
- workspace workspace vector
3169
- wscount size of same
3170
-
3171
- Returns: > 0 => number of match offset pairs placed in offsets
3172
- = 0 => offsets overflowed; longest matches are present
3173
- -1 => failed to match
3174
- < -1 => some kind of unexpected problem
3324
+ code points to the compiled pattern
3325
+ subject subject string
3326
+ length length of subject string
3327
+ startoffset where to start matching in the subject
3328
+ options option bits
3329
+ match_data points to a match data structure
3330
+ gcontext points to a match context
3331
+ workspace pointer to workspace
3332
+ wscount size of workspace
3333
+
3334
+ Returns: > 0 => number of match offset pairs placed in offsets
3335
+ = 0 => offsets overflowed; longest matches are present
3336
+ -1 => failed to match
3337
+ < -1 => some kind of unexpected problem
3175
3338
  */
3176
3339
 
3177
- #if defined COMPILE_PCRE8
3178
- PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3179
- pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
3180
- const char *subject, int length, int start_offset, int options, int *offsets,
3181
- int offsetcount, int *workspace, int wscount)
3182
- #elif defined COMPILE_PCRE16
3183
- PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3184
- pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
3185
- PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
3186
- int offsetcount, int *workspace, int wscount)
3187
- #elif defined COMPILE_PCRE32
3188
- PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3189
- pcre32_dfa_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
3190
- PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets,
3191
- int offsetcount, int *workspace, int wscount)
3192
- #endif
3340
+ PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
3341
+ pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
3342
+ PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
3343
+ pcre2_match_context *mcontext, int *workspace, PCRE2_SIZE wscount)
3193
3344
  {
3194
- REAL_PCRE *re = (REAL_PCRE *)argument_re;
3195
- dfa_match_data match_block;
3196
- dfa_match_data *md = &match_block;
3345
+ int rc;
3346
+
3347
+ const pcre2_real_code *re = (const pcre2_real_code *)code;
3348
+ uint32_t original_options = options;
3349
+
3350
+ PCRE2_UCHAR null_str[1] = { 0xcd };
3351
+ PCRE2_SPTR original_subject = subject;
3352
+ PCRE2_SPTR start_match;
3353
+ PCRE2_SPTR end_subject;
3354
+ PCRE2_SPTR bumpalong_limit;
3355
+ PCRE2_SPTR req_cu_ptr;
3356
+
3197
3357
  BOOL utf, anchored, startline, firstline;
3198
- const pcre_uchar *current_subject, *end_subject;
3199
- const pcre_study_data *study = NULL;
3200
-
3201
- const pcre_uchar *req_char_ptr;
3202
- const pcre_uint8 *start_bits = NULL;
3203
- BOOL has_first_char = FALSE;
3204
- BOOL has_req_char = FALSE;
3205
- pcre_uchar first_char = 0;
3206
- pcre_uchar first_char2 = 0;
3207
- pcre_uchar req_char = 0;
3208
- pcre_uchar req_char2 = 0;
3209
- int newline;
3358
+ BOOL has_first_cu = FALSE;
3359
+ BOOL has_req_cu = FALSE;
3210
3360
 
3211
- /* Plausibility checks */
3361
+ #if PCRE2_CODE_UNIT_WIDTH == 8
3362
+ PCRE2_SPTR memchr_found_first_cu = NULL;
3363
+ PCRE2_SPTR memchr_found_first_cu2 = NULL;
3364
+ #endif
3212
3365
 
3213
- if ((options & ~PUBLIC_DFA_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
3214
- if (re == NULL || subject == NULL || workspace == NULL ||
3215
- (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
3216
- if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
3217
- if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
3218
- if (length < 0) return PCRE_ERROR_BADLENGTH;
3219
- if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
3366
+ PCRE2_UCHAR first_cu = 0;
3367
+ PCRE2_UCHAR first_cu2 = 0;
3368
+ PCRE2_UCHAR req_cu = 0;
3369
+ PCRE2_UCHAR req_cu2 = 0;
3220
3370
 
3221
- /* Check that the first field in the block is the magic number. If it is not,
3222
- return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
3223
- REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
3224
- means that the pattern is likely compiled with different endianness. */
3371
+ const uint8_t *start_bits = NULL;
3225
3372
 
3226
- if (re->magic_number != MAGIC_NUMBER)
3227
- return re->magic_number == REVERSED_MAGIC_NUMBER?
3228
- PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
3229
- if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
3373
+ /* We need to have mb pointing to a match block, because the IS_NEWLINE macro
3374
+ is used below, and it expects NLBLOCK to be defined as a pointer. */
3230
3375
 
3231
- /* If restarting after a partial match, do some sanity checks on the contents
3232
- of the workspace. */
3376
+ pcre2_callout_block cb;
3377
+ dfa_match_block actual_match_block;
3378
+ dfa_match_block *mb = &actual_match_block;
3233
3379
 
3234
- if ((options & PCRE_DFA_RESTART) != 0)
3235
- {
3236
- if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
3237
- workspace[1] > (wscount - 2)/INTS_PER_STATEBLOCK)
3238
- return PCRE_ERROR_DFA_BADRESTART;
3239
- }
3380
+ /* Set up a starting block of memory for use during recursive calls to
3381
+ internal_dfa_match(). By putting this on the stack, it minimizes resource use
3382
+ in the case when it is not needed. If this is too small, more memory is
3383
+ obtained from the heap. At the start of each block is an anchor structure.*/
3384
+
3385
+ int base_recursion_workspace[RWS_BASE_SIZE];
3386
+ RWS_anchor *rws = (RWS_anchor *)base_recursion_workspace;
3387
+ rws->next = NULL;
3388
+ rws->size = RWS_BASE_SIZE;
3389
+ rws->free = RWS_BASE_SIZE - RWS_ANCHOR_SIZE;
3390
+
3391
+ /* Recognize NULL, length 0 as an empty string. */
3240
3392
 
3241
- /* Set up study, callout, and table data */
3393
+ if (subject == NULL && length == 0) subject = null_str;
3242
3394
 
3243
- md->tables = re->tables;
3244
- md->callout_data = NULL;
3395
+ /* Plausibility checks */
3396
+
3397
+ if (match_data == NULL) return PCRE2_ERROR_NULL;
3398
+ if (re == NULL || subject == NULL || workspace == NULL)
3399
+ { rc = PCRE2_ERROR_NULL; goto EXIT; }
3400
+ if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0)
3401
+ { rc = PCRE2_ERROR_BADOPTION; goto EXIT; }
3245
3402
 
3246
- if (extra_data != NULL)
3403
+ if (length == PCRE2_ZERO_TERMINATED)
3247
3404
  {
3248
- unsigned long int flags = extra_data->flags;
3249
- if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
3250
- study = (const pcre_study_data *)extra_data->study_data;
3251
- if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT;
3252
- if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
3253
- return PCRE_ERROR_DFA_UMLIMIT;
3254
- if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
3255
- md->callout_data = extra_data->callout_data;
3256
- if ((flags & PCRE_EXTRA_TABLES) != 0)
3257
- md->tables = extra_data->tables;
3405
+ length = PRIV(strlen)(subject);
3258
3406
  }
3259
3407
 
3260
- /* Set some local values */
3408
+ if (wscount < 20) { rc = PCRE2_ERROR_DFA_WSSIZE; goto EXIT; }
3409
+ if (start_offset > length) { rc = PCRE2_ERROR_BADOFFSET; goto EXIT; }
3261
3410
 
3262
- current_subject = (const pcre_uchar *)subject + start_offset;
3263
- end_subject = (const pcre_uchar *)subject + length;
3264
- req_char_ptr = current_subject - 1;
3411
+ /* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same
3412
+ time. */
3265
3413
 
3266
- #ifdef SUPPORT_UTF
3267
- /* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
3268
- utf = (re->options & PCRE_UTF8) != 0;
3269
- #else
3270
- utf = FALSE;
3271
- #endif
3414
+ if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
3415
+ ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
3416
+ { rc = PCRE2_ERROR_BADOPTION; goto EXIT; }
3272
3417
 
3273
- anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 ||
3274
- (re->options & PCRE_ANCHORED) != 0;
3418
+ /* Invalid UTF support is not available for DFA matching. */
3275
3419
 
3276
- /* The remaining fixed data for passing around. */
3420
+ if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)
3421
+ { rc = PCRE2_ERROR_DFA_UINVALID_UTF; goto EXIT; }
3277
3422
 
3278
- md->start_code = (const pcre_uchar *)argument_re +
3279
- re->name_table_offset + re->name_count * re->name_entry_size;
3280
- md->start_subject = (const pcre_uchar *)subject;
3281
- md->end_subject = end_subject;
3282
- md->start_offset = start_offset;
3283
- md->moptions = options;
3284
- md->poptions = re->options;
3423
+ /* Check that the first field in the block is the magic number. If it is not,
3424
+ return with PCRE2_ERROR_BADMAGIC. */
3285
3425
 
3286
- /* If the BSR option is not set at match time, copy what was set
3287
- at compile time. */
3426
+ if (re->magic_number != MAGIC_NUMBER)
3427
+ { rc = PCRE2_ERROR_BADMAGIC; goto EXIT; }
3428
+
3429
+ /* Check the code unit width. */
3430
+
3431
+ if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
3432
+ { rc = PCRE2_ERROR_BADMODE; goto EXIT; }
3433
+
3434
+ /* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
3435
+ options variable for this function. Users of PCRE2 who are not calling the
3436
+ function directly would like to have a way of setting these flags, in the same
3437
+ way that they can set pcre2_compile() flags like PCRE2_NO_AUTO_POSSESS with
3438
+ constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and
3439
+ (*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be
3440
+ transferred to the options for this function. The bits are guaranteed to be
3441
+ adjacent, but do not have the same values. This bit of Boolean trickery assumes
3442
+ that the match-time bits are not more significant than the flag bits. If by
3443
+ accident this is not the case, a compile-time division by zero error will
3444
+ occur. */
3445
+
3446
+ #define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)
3447
+ #define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)
3448
+ options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));
3449
+ #undef FF
3450
+ #undef OO
3451
+
3452
+ /* If restarting after a partial match, do some sanity checks on the contents
3453
+ of the workspace. */
3288
3454
 
3289
- if ((md->moptions & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == 0)
3455
+ if ((options & PCRE2_DFA_RESTART) != 0)
3290
3456
  {
3291
- if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
3292
- md->moptions |= re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE);
3293
- #ifdef BSR_ANYCRLF
3294
- else md->moptions |= PCRE_BSR_ANYCRLF;
3295
- #endif
3457
+ if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
3458
+ workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK))
3459
+ { rc = PCRE2_ERROR_DFA_BADRESTART; goto EXIT; }
3296
3460
  }
3297
3461
 
3298
- /* Handle different types of newline. The three bits give eight cases. If
3299
- nothing is set at run time, whatever was used at compile time applies. */
3462
+ /* Set some local values */
3300
3463
 
3301
- switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) &
3302
- PCRE_NEWLINE_BITS)
3303
- {
3304
- case 0: newline = NEWLINE; break; /* Compile-time default */
3305
- case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
3306
- case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
3307
- case PCRE_NEWLINE_CR+
3308
- PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
3309
- case PCRE_NEWLINE_ANY: newline = -1; break;
3310
- case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
3311
- default: return PCRE_ERROR_BADNEWLINE;
3312
- }
3464
+ utf = (re->overall_options & PCRE2_UTF) != 0;
3465
+ start_match = subject + start_offset;
3466
+ end_subject = subject + length;
3467
+ req_cu_ptr = start_match - 1;
3468
+ anchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 ||
3469
+ (re->overall_options & PCRE2_ANCHORED) != 0;
3313
3470
 
3314
- if (newline == -2)
3315
- {
3316
- md->nltype = NLTYPE_ANYCRLF;
3317
- }
3318
- else if (newline < 0)
3471
+ /* The "must be at the start of a line" flags are used in a loop when finding
3472
+ where to start. */
3473
+
3474
+ startline = (re->flags & PCRE2_STARTLINE) != 0;
3475
+ firstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0;
3476
+ bumpalong_limit = end_subject;
3477
+
3478
+ /* Initialize and set up the fixed fields in the callout block, with a pointer
3479
+ in the match block. */
3480
+
3481
+ mb->cb = &cb;
3482
+ cb.version = 2;
3483
+ cb.subject = subject;
3484
+ cb.subject_length = (PCRE2_SIZE)(end_subject - subject);
3485
+ cb.callout_flags = 0;
3486
+ cb.capture_top = 1; /* No capture support */
3487
+ cb.capture_last = 0;
3488
+ cb.mark = NULL; /* No (*MARK) support */
3489
+
3490
+ /* Get data from the match context, if present, and fill in the remaining
3491
+ fields in the match block. It is an error to set an offset limit without
3492
+ setting the flag at compile time. */
3493
+
3494
+ if (mcontext == NULL)
3319
3495
  {
3320
- md->nltype = NLTYPE_ANY;
3496
+ mb->callout = NULL;
3497
+ mb->memctl = re->memctl;
3498
+ mb->match_limit = PRIV(default_match_context).match_limit;
3499
+ mb->match_limit_depth = PRIV(default_match_context).depth_limit;
3500
+ mb->heap_limit = PRIV(default_match_context).heap_limit;
3321
3501
  }
3322
3502
  else
3323
3503
  {
3324
- md->nltype = NLTYPE_FIXED;
3325
- if (newline > 255)
3326
- {
3327
- md->nllen = 2;
3328
- md->nl[0] = (newline >> 8) & 255;
3329
- md->nl[1] = newline & 255;
3330
- }
3331
- else
3504
+ if (mcontext->offset_limit != PCRE2_UNSET)
3332
3505
  {
3333
- md->nllen = 1;
3334
- md->nl[0] = newline;
3506
+ if ((re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
3507
+ { rc = PCRE2_ERROR_BADOFFSETLIMIT; goto EXIT; }
3508
+ bumpalong_limit = subject + mcontext->offset_limit;
3335
3509
  }
3510
+ mb->callout = mcontext->callout;
3511
+ mb->callout_data = mcontext->callout_data;
3512
+ mb->memctl = mcontext->memctl;
3513
+ mb->match_limit = mcontext->match_limit;
3514
+ mb->match_limit_depth = mcontext->depth_limit;
3515
+ mb->heap_limit = mcontext->heap_limit;
3336
3516
  }
3337
3517
 
3338
- /* Check a UTF-8 string if required. Unfortunately there's no way of passing
3339
- back the character offset. */
3518
+ if (mb->match_limit > re->limit_match)
3519
+ mb->match_limit = re->limit_match;
3340
3520
 
3341
- #ifdef SUPPORT_UTF
3342
- if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
3343
- {
3344
- int erroroffset;
3345
- int errorcode = PRIV(valid_utf)((pcre_uchar *)subject, length, &erroroffset);
3346
- if (errorcode != 0)
3347
- {
3348
- if (offsetcount >= 2)
3349
- {
3350
- offsets[0] = erroroffset;
3351
- offsets[1] = errorcode;
3352
- }
3353
- #if defined COMPILE_PCRE8
3354
- return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0) ?
3355
- PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
3356
- #elif defined COMPILE_PCRE16
3357
- return (errorcode <= PCRE_UTF16_ERR1 && (options & PCRE_PARTIAL_HARD) != 0) ?
3358
- PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
3359
- #elif defined COMPILE_PCRE32
3360
- return PCRE_ERROR_BADUTF32;
3361
- #endif
3362
- }
3363
- #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3364
- if (start_offset > 0 && start_offset < length &&
3365
- NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
3366
- return PCRE_ERROR_BADUTF8_OFFSET;
3367
- #endif
3368
- }
3369
- #endif
3521
+ if (mb->match_limit_depth > re->limit_depth)
3522
+ mb->match_limit_depth = re->limit_depth;
3370
3523
 
3371
- /* If the exec call supplied NULL for tables, use the inbuilt ones. This
3372
- is a feature that makes it possible to save compiled regex and re-use them
3373
- in other programs later. */
3524
+ if (mb->heap_limit > re->limit_heap)
3525
+ mb->heap_limit = re->limit_heap;
3374
3526
 
3375
- if (md->tables == NULL) md->tables = PRIV(default_tables);
3527
+ mb->start_code = (PCRE2_SPTR)((const uint8_t *)re + re->code_start);
3528
+ mb->tables = re->tables;
3529
+ mb->start_subject = subject;
3530
+ mb->end_subject = end_subject;
3531
+ mb->start_offset = start_offset;
3532
+ mb->allowemptypartial = (re->max_lookbehind > 0) ||
3533
+ (re->flags & PCRE2_MATCH_EMPTY) != 0;
3534
+ mb->moptions = options;
3535
+ mb->poptions = re->overall_options;
3536
+ mb->match_call_count = 0;
3537
+ mb->heap_used = 0;
3376
3538
 
3377
- /* The "must be at the start of a line" flags are used in a loop when finding
3378
- where to start. */
3539
+ /* Process the \R and newline settings. */
3379
3540
 
3380
- startline = (re->flags & PCRE_STARTLINE) != 0;
3381
- firstline = (re->options & PCRE_FIRSTLINE) != 0;
3541
+ mb->bsr_convention = re->bsr_convention;
3542
+ mb->nltype = NLTYPE_FIXED;
3543
+ switch(re->newline_convention)
3544
+ {
3545
+ case PCRE2_NEWLINE_CR:
3546
+ mb->nllen = 1;
3547
+ mb->nl[0] = CHAR_CR;
3548
+ break;
3549
+
3550
+ case PCRE2_NEWLINE_LF:
3551
+ mb->nllen = 1;
3552
+ mb->nl[0] = CHAR_NL;
3553
+ break;
3554
+
3555
+ case PCRE2_NEWLINE_NUL:
3556
+ mb->nllen = 1;
3557
+ mb->nl[0] = CHAR_NUL;
3558
+ break;
3559
+
3560
+ case PCRE2_NEWLINE_CRLF:
3561
+ mb->nllen = 2;
3562
+ mb->nl[0] = CHAR_CR;
3563
+ mb->nl[1] = CHAR_NL;
3564
+ break;
3565
+
3566
+ case PCRE2_NEWLINE_ANY:
3567
+ mb->nltype = NLTYPE_ANY;
3568
+ break;
3569
+
3570
+ case PCRE2_NEWLINE_ANYCRLF:
3571
+ mb->nltype = NLTYPE_ANYCRLF;
3572
+ break;
3573
+
3574
+ /* LCOV_EXCL_START */
3575
+ default:
3576
+ PCRE2_DEBUG_UNREACHABLE();
3577
+ rc = PCRE2_ERROR_INTERNAL;
3578
+ goto EXIT;
3579
+ /* LCOV_EXCL_STOP */
3580
+ }
3382
3581
 
3383
- /* Set up the first character to match, if available. The first_byte value is
3384
- never set for an anchored regular expression, but the anchoring may be forced
3385
- at run time, so we have to test for anchoring. The first char may be unset for
3386
- an unanchored pattern, of course. If there's no first char and the pattern was
3387
- studied, there may be a bitmap of possible first characters. */
3582
+ /* Check a UTF string for validity if required. For 8-bit and 16-bit strings,
3583
+ we must also check that a starting offset does not point into the middle of a
3584
+ multiunit character. We check only the portion of the subject that is going to
3585
+ be inspected during matching - from the offset minus the maximum back reference
3586
+ to the given length. This saves time when a small part of a large subject is
3587
+ being matched by the use of a starting offset. Note that the maximum lookbehind
3588
+ is a number of characters, not code units. */
3388
3589
 
3389
- if (!anchored)
3590
+ #ifdef SUPPORT_UNICODE
3591
+ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
3390
3592
  {
3391
- if ((re->flags & PCRE_FIRSTSET) != 0)
3593
+ PCRE2_SPTR check_subject = start_match; /* start_match includes offset */
3594
+
3595
+ if (start_offset > 0)
3392
3596
  {
3393
- has_first_char = TRUE;
3394
- first_char = first_char2 = (pcre_uchar)(re->first_char);
3395
- if ((re->flags & PCRE_FCH_CASELESS) != 0)
3597
+ #if PCRE2_CODE_UNIT_WIDTH != 32
3598
+ unsigned int i;
3599
+ if (start_match < end_subject && NOT_FIRSTCU(*start_match))
3600
+ { rc = PCRE2_ERROR_BADUTFOFFSET; goto EXIT; }
3601
+ for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--)
3396
3602
  {
3397
- first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char);
3398
- #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
3399
- if (utf && first_char > 127)
3400
- first_char2 = UCD_OTHERCASE(first_char);
3401
- #endif
3603
+ check_subject--;
3604
+ while (check_subject > subject &&
3605
+ #if PCRE2_CODE_UNIT_WIDTH == 8
3606
+ (*check_subject & 0xc0) == 0x80)
3607
+ #else /* 16-bit */
3608
+ (*check_subject & 0xfc00) == 0xdc00)
3609
+ #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
3610
+ check_subject--;
3402
3611
  }
3612
+ #else /* In the 32-bit library, one code unit equals one character. */
3613
+ check_subject -= re->max_lookbehind;
3614
+ if (check_subject < subject) check_subject = subject;
3615
+ #endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
3403
3616
  }
3404
- else
3617
+
3618
+ /* Validate the relevant portion of the subject. After an error, adjust the
3619
+ offset to be an absolute offset in the whole string. */
3620
+
3621
+ rc = PRIV(valid_utf)(check_subject,
3622
+ length - (PCRE2_SIZE)(check_subject - subject), &(match_data->startchar));
3623
+ if (rc != 0)
3405
3624
  {
3406
- if (!startline && study != NULL &&
3407
- (study->flags & PCRE_STUDY_MAPPED) != 0)
3408
- start_bits = study->start_bits;
3625
+ match_data->startchar += (PCRE2_SIZE)(check_subject - subject);
3626
+ goto EXIT;
3409
3627
  }
3410
3628
  }
3629
+ #endif /* SUPPORT_UNICODE */
3411
3630
 
3412
- /* For anchored or unanchored matches, there may be a "last known required
3413
- character" set. */
3631
+ /* Set up the first code unit to match, if available. If there's no first code
3632
+ unit there may be a bitmap of possible first characters. */
3414
3633
 
3415
- if ((re->flags & PCRE_REQCHSET) != 0)
3634
+ if ((re->flags & PCRE2_FIRSTSET) != 0)
3416
3635
  {
3417
- has_req_char = TRUE;
3418
- req_char = req_char2 = (pcre_uchar)(re->req_char);
3419
- if ((re->flags & PCRE_RCH_CASELESS) != 0)
3636
+ has_first_cu = TRUE;
3637
+ first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
3638
+ if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
3420
3639
  {
3421
- req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char);
3422
- #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
3423
- if (utf && req_char > 127)
3424
- req_char2 = UCD_OTHERCASE(req_char);
3640
+ first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu);
3641
+ #ifdef SUPPORT_UNICODE
3642
+ #if PCRE2_CODE_UNIT_WIDTH == 8
3643
+ if (first_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)
3644
+ first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
3645
+ #else
3646
+ if (first_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))
3647
+ first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
3425
3648
  #endif
3649
+ #endif /* SUPPORT_UNICODE */
3426
3650
  }
3427
3651
  }
3652
+ else
3653
+ if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
3654
+ start_bits = re->start_bitmap;
3655
+
3656
+ /* There may be a "last known required code unit" set. */
3657
+
3658
+ if ((re->flags & PCRE2_LASTSET) != 0)
3659
+ {
3660
+ has_req_cu = TRUE;
3661
+ req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);
3662
+ if ((re->flags & PCRE2_LASTCASELESS) != 0)
3663
+ {
3664
+ req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu);
3665
+ #ifdef SUPPORT_UNICODE
3666
+ #if PCRE2_CODE_UNIT_WIDTH == 8
3667
+ if (req_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)
3668
+ req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
3669
+ #else
3670
+ if (req_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))
3671
+ req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
3672
+ #endif
3673
+ #endif /* SUPPORT_UNICODE */
3674
+ }
3675
+ }
3676
+
3677
+ /* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,
3678
+ free the memory that was obtained. */
3679
+
3680
+ if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
3681
+ {
3682
+ match_data->memctl.free((void *)match_data->subject,
3683
+ match_data->memctl.memory_data);
3684
+ match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;
3685
+ }
3686
+
3687
+ /* Fill in fields that are always returned in the match data. */
3688
+
3689
+ match_data->code = re;
3690
+ match_data->subject = NULL; /* Default for match error */
3691
+ match_data->mark = NULL;
3692
+ match_data->matchedby = PCRE2_MATCHEDBY_DFA_INTERPRETER;
3693
+ match_data->options = original_options;
3428
3694
 
3429
3695
  /* Call the main matching function, looping for a non-anchored regex after a
3430
3696
  failed match. If not restarting, perform certain optimizations at the start of
@@ -3432,245 +3698,438 @@ a match. */
3432
3698
 
3433
3699
  for (;;)
3434
3700
  {
3435
- int rc;
3701
+ /* ----------------- Start of match optimizations ---------------- */
3436
3702
 
3437
- if ((options & PCRE_DFA_RESTART) == 0)
3438
- {
3439
- const pcre_uchar *save_end_subject = end_subject;
3703
+ /* There are some optimizations that avoid running the match if a known
3704
+ starting point is not found, or if a known later code unit is not present.
3705
+ However, there is an option (settable at compile time) that disables
3706
+ these, for testing and for ensuring that all callouts do actually occur.
3707
+ The optimizations must also be avoided when restarting a DFA match. */
3440
3708
 
3709
+ if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0 &&
3710
+ (options & PCRE2_DFA_RESTART) == 0)
3711
+ {
3441
3712
  /* If firstline is TRUE, the start of the match is constrained to the first
3442
- line of a multiline string. Implement this by temporarily adjusting
3443
- end_subject so that we stop scanning at a newline. If the match fails at
3444
- the newline, later code breaks this loop. */
3713
+ line of a multiline string. That is, the match must be before or at the
3714
+ first newline following the start of matching. Temporarily adjust
3715
+ end_subject so that we stop the optimization scans for a first code unit
3716
+ immediately after the first character of a newline (the first code unit can
3717
+ legitimately be a newline). If the match fails at the newline, later code
3718
+ breaks this loop. */
3445
3719
 
3446
3720
  if (firstline)
3447
3721
  {
3448
- PCRE_PUCHAR t = current_subject;
3449
- #ifdef SUPPORT_UTF
3722
+ PCRE2_SPTR t = start_match;
3723
+ #ifdef SUPPORT_UNICODE
3450
3724
  if (utf)
3451
3725
  {
3452
- while (t < md->end_subject && !IS_NEWLINE(t))
3726
+ while (t < end_subject && !IS_NEWLINE(t))
3453
3727
  {
3454
3728
  t++;
3455
- ACROSSCHAR(t < end_subject, *t, t++);
3729
+ ACROSSCHAR(t < end_subject, t, t++);
3456
3730
  }
3457
3731
  }
3458
3732
  else
3459
3733
  #endif
3460
- while (t < md->end_subject && !IS_NEWLINE(t)) t++;
3734
+ while (t < end_subject && !IS_NEWLINE(t)) t++;
3461
3735
  end_subject = t;
3462
3736
  }
3463
3737
 
3464
- /* There are some optimizations that avoid running the match if a known
3465
- starting point is not found. However, there is an option that disables
3466
- these, for testing and for ensuring that all callouts do actually occur.
3467
- The option can be set in the regex by (*NO_START_OPT) or passed in
3468
- match-time options. */
3738
+ /* Anchored: check the first code unit if one is recorded. This may seem
3739
+ pointless but it can help in detecting a no match case without scanning for
3740
+ the required code unit. */
3469
3741
 
3470
- if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
3742
+ if (anchored)
3471
3743
  {
3472
- /* Advance to a known first pcre_uchar (i.e. data item) */
3744
+ if (has_first_cu || start_bits != NULL)
3745
+ {
3746
+ BOOL ok = start_match < end_subject;
3747
+ if (ok)
3748
+ {
3749
+ PCRE2_UCHAR c = UCHAR21TEST(start_match);
3750
+ ok = has_first_cu && (c == first_cu || c == first_cu2);
3751
+ if (!ok && start_bits != NULL)
3752
+ {
3753
+ #if PCRE2_CODE_UNIT_WIDTH != 8
3754
+ if (c > 255) c = 255;
3755
+ #endif
3756
+ ok = (start_bits[c/8] & (1u << (c&7))) != 0;
3757
+ }
3758
+ }
3759
+ if (!ok) break;
3760
+ }
3761
+ }
3762
+
3763
+ /* Not anchored. Advance to a unique first code unit if there is one. */
3473
3764
 
3474
- if (has_first_char)
3765
+ else
3766
+ {
3767
+ if (has_first_cu)
3475
3768
  {
3476
- if (first_char != first_char2)
3769
+ if (first_cu != first_cu2) /* Caseless */
3477
3770
  {
3478
- pcre_uchar csc;
3479
- while (current_subject < end_subject &&
3480
- (csc = UCHAR21TEST(current_subject)) != first_char && csc != first_char2)
3481
- current_subject++;
3771
+ /* In 16-bit and 32_bit modes we have to do our own search, so can
3772
+ look for both cases at once. */
3773
+
3774
+ #if PCRE2_CODE_UNIT_WIDTH != 8
3775
+ PCRE2_UCHAR smc;
3776
+ while (start_match < end_subject &&
3777
+ (smc = UCHAR21TEST(start_match)) != first_cu &&
3778
+ smc != first_cu2)
3779
+ start_match++;
3780
+ #else
3781
+ /* In 8-bit mode, the use of memchr() gives a big speed up, even
3782
+ though we have to call it twice in order to find the earliest
3783
+ occurrence of the code unit in either of its cases. Caching is used
3784
+ to remember the positions of previously found code units. This can
3785
+ make a huge difference when the strings are very long and only one
3786
+ case is actually present. */
3787
+
3788
+ PCRE2_SPTR pp1 = NULL;
3789
+ PCRE2_SPTR pp2 = NULL;
3790
+ PCRE2_SIZE searchlength = end_subject - start_match;
3791
+
3792
+ /* If we haven't got a previously found position for first_cu, or if
3793
+ the current starting position is later, we need to do a search. If
3794
+ the code unit is not found, set it to the end. */
3795
+
3796
+ if (memchr_found_first_cu == NULL ||
3797
+ start_match > memchr_found_first_cu)
3798
+ {
3799
+ pp1 = memchr(start_match, first_cu, searchlength);
3800
+ memchr_found_first_cu = (pp1 == NULL)? end_subject : pp1;
3801
+ }
3802
+
3803
+ /* If the start is before a previously found position, use the
3804
+ previous position, or NULL if a previous search failed. */
3805
+
3806
+ else pp1 = (memchr_found_first_cu == end_subject)? NULL :
3807
+ memchr_found_first_cu;
3808
+
3809
+ /* Do the same thing for the other case. */
3810
+
3811
+ if (memchr_found_first_cu2 == NULL ||
3812
+ start_match > memchr_found_first_cu2)
3813
+ {
3814
+ pp2 = memchr(start_match, first_cu2, searchlength);
3815
+ memchr_found_first_cu2 = (pp2 == NULL)? end_subject : pp2;
3816
+ }
3817
+
3818
+ else pp2 = (memchr_found_first_cu2 == end_subject)? NULL :
3819
+ memchr_found_first_cu2;
3820
+
3821
+ /* Set the start to the end of the subject if neither case was found.
3822
+ Otherwise, use the earlier found point. */
3823
+
3824
+ if (pp1 == NULL)
3825
+ start_match = (pp2 == NULL)? end_subject : pp2;
3826
+ else
3827
+ start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;
3828
+
3829
+ #endif /* 8-bit handling */
3482
3830
  }
3831
+
3832
+ /* The caseful case is much simpler. */
3833
+
3483
3834
  else
3484
- while (current_subject < end_subject &&
3485
- UCHAR21TEST(current_subject) != first_char)
3486
- current_subject++;
3835
+ {
3836
+ #if PCRE2_CODE_UNIT_WIDTH != 8
3837
+ while (start_match < end_subject && UCHAR21TEST(start_match) !=
3838
+ first_cu)
3839
+ start_match++;
3840
+ #else /* 8-bit code units */
3841
+ start_match = memchr(start_match, first_cu, end_subject - start_match);
3842
+ if (start_match == NULL) start_match = end_subject;
3843
+ #endif
3844
+ }
3845
+
3846
+ /* If we can't find the required code unit, having reached the true end
3847
+ of the subject, break the bumpalong loop, to force a match failure,
3848
+ except when doing partial matching, when we let the next cycle run at
3849
+ the end of the subject. To see why, consider the pattern /(?<=abc)def/,
3850
+ which partially matches "abc", even though the string does not contain
3851
+ the starting character "d". If we have not reached the true end of the
3852
+ subject (PCRE2_FIRSTLINE caused end_subject to be temporarily modified)
3853
+ we also let the cycle run, because the matching string is legitimately
3854
+ allowed to start with the first code unit of a newline. */
3855
+
3856
+ if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0 &&
3857
+ start_match >= mb->end_subject)
3858
+ break;
3487
3859
  }
3488
3860
 
3489
- /* Or to just after a linebreak for a multiline match if possible */
3861
+ /* If there's no first code unit, advance to just after a linebreak for a
3862
+ multiline match if required. */
3490
3863
 
3491
3864
  else if (startline)
3492
3865
  {
3493
- if (current_subject > md->start_subject + start_offset)
3866
+ if (start_match > mb->start_subject + start_offset)
3494
3867
  {
3495
- #ifdef SUPPORT_UTF
3868
+ #ifdef SUPPORT_UNICODE
3496
3869
  if (utf)
3497
3870
  {
3498
- while (current_subject < end_subject &&
3499
- !WAS_NEWLINE(current_subject))
3871
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
3500
3872
  {
3501
- current_subject++;
3502
- ACROSSCHAR(current_subject < end_subject, *current_subject,
3503
- current_subject++);
3873
+ start_match++;
3874
+ ACROSSCHAR(start_match < end_subject, start_match, start_match++);
3504
3875
  }
3505
3876
  }
3506
3877
  else
3507
3878
  #endif
3508
- while (current_subject < end_subject && !WAS_NEWLINE(current_subject))
3509
- current_subject++;
3879
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
3880
+ start_match++;
3510
3881
 
3511
3882
  /* If we have just passed a CR and the newline option is ANY or
3512
3883
  ANYCRLF, and we are now at a LF, advance the match position by one
3513
- more character. */
3884
+ more code unit. */
3514
3885
 
3515
- if (UCHAR21TEST(current_subject - 1) == CHAR_CR &&
3516
- (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
3517
- current_subject < end_subject &&
3518
- UCHAR21TEST(current_subject) == CHAR_NL)
3519
- current_subject++;
3886
+ if (start_match[-1] == CHAR_CR &&
3887
+ (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
3888
+ start_match < end_subject &&
3889
+ UCHAR21TEST(start_match) == CHAR_NL)
3890
+ start_match++;
3520
3891
  }
3521
3892
  }
3522
3893
 
3523
- /* Advance to a non-unique first pcre_uchar after study */
3894
+ /* If there's no first code unit or a requirement for a multiline line
3895
+ start, advance to a non-unique first code unit if any have been
3896
+ identified. The bitmap contains only 256 bits. When code units are 16 or
3897
+ 32 bits wide, all code units greater than 254 set the 255 bit. */
3524
3898
 
3525
3899
  else if (start_bits != NULL)
3526
3900
  {
3527
- while (current_subject < end_subject)
3901
+ while (start_match < end_subject)
3528
3902
  {
3529
- register pcre_uint32 c = UCHAR21TEST(current_subject);
3530
- #ifndef COMPILE_PCRE8
3903
+ uint32_t c = UCHAR21TEST(start_match);
3904
+ #if PCRE2_CODE_UNIT_WIDTH != 8
3531
3905
  if (c > 255) c = 255;
3532
3906
  #endif
3533
- if ((start_bits[c/8] & (1 << (c&7))) != 0) break;
3534
- current_subject++;
3907
+ if ((start_bits[c/8] & (1u << (c&7))) != 0) break;
3908
+ start_match++;
3535
3909
  }
3910
+
3911
+ /* See comment above in first_cu checking about the next line. */
3912
+
3913
+ if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0 &&
3914
+ start_match >= mb->end_subject)
3915
+ break;
3536
3916
  }
3537
- }
3917
+ } /* End of first code unit handling */
3538
3918
 
3539
3919
  /* Restore fudged end_subject */
3540
3920
 
3541
- end_subject = save_end_subject;
3921
+ end_subject = mb->end_subject;
3542
3922
 
3543
- /* The following two optimizations are disabled for partial matching or if
3544
- disabling is explicitly requested (and of course, by the test above, this
3545
- code is not obeyed when restarting after a partial match). */
3923
+ /* The following two optimizations are disabled for partial matching. */
3546
3924
 
3547
- if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 &&
3548
- (options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0)
3925
+ if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0)
3549
3926
  {
3550
- /* If the pattern was studied, a minimum subject length may be set. This
3551
- is a lower bound; no actual string of that length may actually match the
3552
- pattern. Although the value is, strictly, in characters, we treat it as
3553
- in pcre_uchar units to avoid spending too much time in this optimization.
3554
- */
3555
-
3556
- if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
3557
- (pcre_uint32)(end_subject - current_subject) < study->minlength)
3558
- return PCRE_ERROR_NOMATCH;
3559
-
3560
- /* If req_char is set, we know that that pcre_uchar must appear in the
3561
- subject for the match to succeed. If the first pcre_uchar is set,
3562
- req_char must be later in the subject; otherwise the test starts at the
3563
- match point. This optimization can save a huge amount of work in patterns
3564
- with nested unlimited repeats that aren't going to match. Writing
3565
- separate code for cased/caseless versions makes it go faster, as does
3566
- using an autoincrement and backing off on a match.
3927
+ PCRE2_SPTR p;
3928
+
3929
+ /* The minimum matching length is a lower bound; no actual string of that
3930
+ length may actually match the pattern. Although the value is, strictly,
3931
+ in characters, we treat it as code units to avoid spending too much time
3932
+ in this optimization. */
3933
+
3934
+ if (end_subject - start_match < re->minlength) goto NOMATCH_EXIT;
3935
+
3936
+ /* If req_cu is set, we know that that code unit must appear in the
3937
+ subject for the match to succeed. If the first code unit is set, req_cu
3938
+ must be later in the subject; otherwise the test starts at the match
3939
+ point. This optimization can save a huge amount of backtracking in
3940
+ patterns with nested unlimited repeats that aren't going to match.
3941
+ Writing separate code for cased/caseless versions makes it go faster, as
3942
+ does using an autoincrement and backing off on a match. As in the case of
3943
+ the first code unit, using memchr() in the 8-bit library gives a big
3944
+ speed up. Unlike the first_cu check above, we do not need to call
3945
+ memchr() twice in the caseless case because we only need to check for the
3946
+ presence of the character in either case, not find the first occurrence.
3947
+
3948
+ The search can be skipped if the code unit was found later than the
3949
+ current starting point in a previous iteration of the bumpalong loop.
3567
3950
 
3568
3951
  HOWEVER: when the subject string is very, very long, searching to its end
3569
3952
  can take a long time, and give bad performance on quite ordinary
3570
- patterns. This showed up when somebody was matching /^C/ on a 32-megabyte
3571
- string... so we don't do this when the string is sufficiently long. */
3953
+ patterns. This showed up when somebody was matching something like
3954
+ /^\d+C/ on a 32-megabyte string... so we don't do this when the string is
3955
+ sufficiently long, but it's worth searching a lot more for unanchored
3956
+ patterns. */
3572
3957
 
3573
- if (has_req_char && end_subject - current_subject < REQ_BYTE_MAX)
3958
+ p = start_match + (has_first_cu? 1:0);
3959
+ if (has_req_cu && p > req_cu_ptr)
3574
3960
  {
3575
- register PCRE_PUCHAR p = current_subject + (has_first_char? 1:0);
3576
-
3577
- /* We don't need to repeat the search if we haven't yet reached the
3578
- place we found it at last time. */
3961
+ PCRE2_SIZE check_length = end_subject - start_match;
3579
3962
 
3580
- if (p > req_char_ptr)
3963
+ if (check_length < REQ_CU_MAX ||
3964
+ (!anchored && check_length < REQ_CU_MAX * 1000))
3581
3965
  {
3582
- if (req_char != req_char2)
3966
+ if (req_cu != req_cu2) /* Caseless */
3583
3967
  {
3968
+ #if PCRE2_CODE_UNIT_WIDTH != 8
3584
3969
  while (p < end_subject)
3585
3970
  {
3586
- register pcre_uint32 pp = UCHAR21INCTEST(p);
3587
- if (pp == req_char || pp == req_char2) { p--; break; }
3971
+ uint32_t pp = UCHAR21INCTEST(p);
3972
+ if (pp == req_cu || pp == req_cu2) { p--; break; }
3588
3973
  }
3974
+ #else /* 8-bit code units */
3975
+ PCRE2_SPTR pp = p;
3976
+ p = memchr(pp, req_cu, end_subject - pp);
3977
+ if (p == NULL)
3978
+ {
3979
+ p = memchr(pp, req_cu2, end_subject - pp);
3980
+ if (p == NULL) p = end_subject;
3981
+ }
3982
+ #endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
3589
3983
  }
3984
+
3985
+ /* The caseful case */
3986
+
3590
3987
  else
3591
3988
  {
3989
+ #if PCRE2_CODE_UNIT_WIDTH != 8
3592
3990
  while (p < end_subject)
3593
3991
  {
3594
- if (UCHAR21INCTEST(p) == req_char) { p--; break; }
3992
+ if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
3595
3993
  }
3994
+
3995
+ #else /* 8-bit code units */
3996
+ p = memchr(p, req_cu, end_subject - p);
3997
+ if (p == NULL) p = end_subject;
3998
+ #endif
3596
3999
  }
3597
4000
 
3598
- /* If we can't find the required pcre_uchar, break the matching loop,
3599
- which will cause a return or PCRE_ERROR_NOMATCH. */
4001
+ /* If we can't find the required code unit, break the matching loop,
4002
+ forcing a match failure. */
3600
4003
 
3601
4004
  if (p >= end_subject) break;
3602
4005
 
3603
- /* If we have found the required pcre_uchar, save the point where we
4006
+ /* If we have found the required code unit, save the point where we
3604
4007
  found it, so that we don't search again next time round the loop if
3605
- the start hasn't passed this point yet. */
4008
+ the start hasn't passed this code unit yet. */
3606
4009
 
3607
- req_char_ptr = p;
4010
+ req_cu_ptr = p;
3608
4011
  }
3609
4012
  }
3610
4013
  }
3611
- } /* End of optimizations that are done when not restarting */
4014
+ }
3612
4015
 
3613
- /* OK, now we can do the business */
4016
+ /* ------------ End of start of match optimizations ------------ */
4017
+
4018
+ /* Give no match if we have passed the bumpalong limit. */
3614
4019
 
3615
- md->start_used_ptr = current_subject;
3616
- md->recursive = NULL;
4020
+ if (start_match > bumpalong_limit) break;
3617
4021
 
3618
- rc = internal_dfa_exec(
3619
- md, /* fixed match data */
3620
- md->start_code, /* this subexpression's code */
3621
- current_subject, /* where we currently are */
3622
- start_offset, /* start offset in subject */
3623
- offsets, /* offset vector */
3624
- offsetcount, /* size of same */
3625
- workspace, /* workspace vector */
3626
- wscount, /* size of same */
3627
- 0); /* function recurse level */
4022
+ /* OK, now we can do the business */
4023
+
4024
+ mb->start_used_ptr = start_match;
4025
+ mb->last_used_ptr = start_match;
4026
+ mb->recursive = NULL;
4027
+
4028
+ rc = internal_dfa_match(
4029
+ mb, /* fixed match data */
4030
+ mb->start_code, /* this subexpression's code */
4031
+ start_match, /* where we currently are */
4032
+ start_offset, /* start offset in subject */
4033
+ match_data->ovector, /* offset vector */
4034
+ (uint32_t)match_data->oveccount * 2, /* actual size of same */
4035
+ workspace, /* workspace vector */
4036
+ (int)wscount, /* size of same */
4037
+ 0, /* function recurse level */
4038
+ base_recursion_workspace); /* initial workspace for recursion */
3628
4039
 
3629
4040
  /* Anything other than "no match" means we are done, always; otherwise, carry
3630
4041
  on only if not anchored. */
3631
4042
 
3632
- if (rc != PCRE_ERROR_NOMATCH || anchored)
4043
+ if (rc != PCRE2_ERROR_NOMATCH || anchored)
3633
4044
  {
3634
- if (rc == PCRE_ERROR_PARTIAL && offsetcount >= 2)
4045
+ if (rc == PCRE2_ERROR_NOMATCH) goto NOMATCH_EXIT;
4046
+
4047
+ if (rc == PCRE2_ERROR_PARTIAL && match_data->oveccount > 0)
3635
4048
  {
3636
- offsets[0] = (int)(md->start_used_ptr - (PCRE_PUCHAR)subject);
3637
- offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
3638
- if (offsetcount > 2)
3639
- offsets[2] = (int)(current_subject - (PCRE_PUCHAR)subject);
4049
+ match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject);
4050
+ match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject);
3640
4051
  }
3641
- return rc;
4052
+
4053
+ if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)
4054
+ {
4055
+ match_data->subject_length = length;
4056
+ match_data->start_offset = start_offset;
4057
+ match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);
4058
+ match_data->rightchar = (PCRE2_SIZE)(mb->last_used_ptr - subject);
4059
+ match_data->startchar = (PCRE2_SIZE)(start_match - subject);
4060
+ }
4061
+
4062
+ if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
4063
+ {
4064
+ if (length != 0)
4065
+ {
4066
+ match_data->subject = match_data->memctl.malloc(CU2BYTES(length),
4067
+ match_data->memctl.memory_data);
4068
+ if (match_data->subject == NULL)
4069
+ { rc = PCRE2_ERROR_NOMEMORY; goto EXIT; }
4070
+ memcpy((void *)match_data->subject, subject, CU2BYTES(length));
4071
+ }
4072
+ else
4073
+ match_data->subject = NULL;
4074
+ match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
4075
+ }
4076
+ else if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)
4077
+ {
4078
+ match_data->subject = original_subject;
4079
+ }
4080
+ goto EXIT;
3642
4081
  }
3643
4082
 
3644
4083
  /* Advance to the next subject character unless we are at the end of a line
3645
4084
  and firstline is set. */
3646
4085
 
3647
- if (firstline && IS_NEWLINE(current_subject)) break;
3648
- current_subject++;
3649
- #ifdef SUPPORT_UTF
4086
+ if (firstline && IS_NEWLINE(start_match)) break;
4087
+ start_match++;
4088
+ #ifdef SUPPORT_UNICODE
3650
4089
  if (utf)
3651
4090
  {
3652
- ACROSSCHAR(current_subject < end_subject, *current_subject,
3653
- current_subject++);
4091
+ ACROSSCHAR(start_match < end_subject, start_match, start_match++);
3654
4092
  }
3655
4093
  #endif
3656
- if (current_subject > end_subject) break;
4094
+ if (start_match > end_subject) break;
3657
4095
 
3658
4096
  /* If we have just passed a CR and we are now at a LF, and the pattern does
3659
4097
  not contain any explicit matches for \r or \n, and the newline option is CRLF
3660
4098
  or ANY or ANYCRLF, advance the match position by one more character. */
3661
4099
 
3662
- if (UCHAR21TEST(current_subject - 1) == CHAR_CR &&
3663
- current_subject < end_subject &&
3664
- UCHAR21TEST(current_subject) == CHAR_NL &&
3665
- (re->flags & PCRE_HASCRORLF) == 0 &&
3666
- (md->nltype == NLTYPE_ANY ||
3667
- md->nltype == NLTYPE_ANYCRLF ||
3668
- md->nllen == 2))
3669
- current_subject++;
4100
+ if (UCHAR21TEST(start_match - 1) == CHAR_CR &&
4101
+ start_match < end_subject &&
4102
+ UCHAR21TEST(start_match) == CHAR_NL &&
4103
+ (re->flags & PCRE2_HASCRORLF) == 0 &&
4104
+ (mb->nltype == NLTYPE_ANY ||
4105
+ mb->nltype == NLTYPE_ANYCRLF ||
4106
+ mb->nllen == 2))
4107
+ start_match++;
3670
4108
 
3671
4109
  } /* "Bumpalong" loop */
3672
4110
 
3673
- return PCRE_ERROR_NOMATCH;
4111
+ NOMATCH_EXIT:
4112
+ match_data->subject = original_subject;
4113
+ match_data->subject_length = length;
4114
+ match_data->start_offset = start_offset;
4115
+ rc = PCRE2_ERROR_NOMATCH;
4116
+
4117
+ EXIT:
4118
+ while (rws->next != NULL)
4119
+ {
4120
+ RWS_anchor *next = rws->next;
4121
+ rws->next = next->next;
4122
+ mb->memctl.free(next, mb->memctl.memory_data);
4123
+ }
4124
+
4125
+ match_data->rc = rc;
4126
+ return rc;
3674
4127
  }
3675
4128
 
3676
- /* End of pcre_dfa_exec.c */
4129
+ /* These #undefs are here to enable unity builds with CMake. */
4130
+
4131
+ #undef NLBLOCK /* Block containing newline information */
4132
+ #undef PSSTART /* Field containing processed string start */
4133
+ #undef PSEND /* Field containing processed string end */
4134
+
4135
+ /* End of pcre2_dfa_match.c */