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.
- checksums.yaml +4 -4
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +1 -1
- data/vendor/libgit2/COPYING +83 -11
- data/vendor/libgit2/cmake/SelectRegex.cmake +8 -3
- data/vendor/libgit2/deps/pcre2/CMakeLists.txt +110 -0
- data/vendor/libgit2/deps/pcre2/LICENCE.md +104 -0
- data/vendor/libgit2/deps/pcre2/config.h.in +54 -0
- data/vendor/libgit2/deps/pcre2/pcre2.h +1079 -0
- data/vendor/libgit2/deps/pcre2/pcre2_auto_possess.c +1416 -0
- data/vendor/libgit2/deps/{pcre/pcre_chartables.c → pcre2/pcre2_chartables.c} +41 -47
- data/vendor/libgit2/deps/{pcre/pcre_ord2utf8.c → pcre2/pcre2_chkdint.c} +36 -36
- data/vendor/libgit2/deps/pcre2/pcre2_compile.c +11345 -0
- data/vendor/libgit2/deps/pcre2/pcre2_compile.h +356 -0
- data/vendor/libgit2/deps/pcre2/pcre2_compile_cgroup.c +632 -0
- data/vendor/libgit2/deps/pcre2/pcre2_compile_class.c +2777 -0
- data/vendor/libgit2/deps/pcre2/pcre2_config.c +250 -0
- data/vendor/libgit2/deps/pcre2/pcre2_context.c +557 -0
- data/vendor/libgit2/deps/pcre2/pcre2_convert.c +1263 -0
- data/vendor/libgit2/deps/{pcre/pcre_dfa_exec.c → pcre2/pcre2_dfa_match.c} +1402 -943
- data/vendor/libgit2/deps/pcre2/pcre2_error.c +384 -0
- data/vendor/libgit2/deps/pcre2/pcre2_extuni.c +159 -0
- data/vendor/libgit2/deps/pcre2/pcre2_find_bracket.c +217 -0
- data/vendor/libgit2/deps/pcre2/pcre2_fuzzsupport.c +844 -0
- data/vendor/libgit2/deps/pcre2/pcre2_internal.h +2353 -0
- data/vendor/libgit2/deps/pcre2/pcre2_intmodedep.h +1044 -0
- data/vendor/libgit2/deps/pcre2/pcre2_maketables.c +177 -0
- data/vendor/libgit2/deps/pcre2/pcre2_match.c +8244 -0
- data/vendor/libgit2/deps/pcre2/pcre2_match_data.c +184 -0
- data/vendor/libgit2/deps/pcre2/pcre2_match_next.c +171 -0
- data/vendor/libgit2/deps/{pcre/pcre_newline.c → pcre2/pcre2_newline.c} +92 -63
- data/vendor/libgit2/deps/{pcre/pcre_refcount.c → pcre2/pcre2_ord2utf.c} +64 -38
- data/vendor/libgit2/deps/pcre2/pcre2_pattern_info.c +430 -0
- data/vendor/libgit2/deps/pcre2/pcre2_printint_inc.h +1098 -0
- data/vendor/libgit2/deps/pcre2/pcre2_script_run.c +344 -0
- data/vendor/libgit2/deps/pcre2/pcre2_serialize.c +284 -0
- data/vendor/libgit2/deps/pcre2/pcre2_string_utils.c +199 -0
- data/vendor/libgit2/deps/pcre2/pcre2_study.c +2087 -0
- data/vendor/libgit2/deps/pcre2/pcre2_substitute.c +1761 -0
- data/vendor/libgit2/deps/pcre2/pcre2_substring.c +553 -0
- data/vendor/libgit2/deps/pcre2/pcre2_tables.c +310 -0
- data/vendor/libgit2/deps/pcre2/pcre2_ucd.c +5805 -0
- data/vendor/libgit2/deps/pcre2/pcre2_ucp.h +408 -0
- data/vendor/libgit2/deps/pcre2/pcre2_ucptables_inc.h +1596 -0
- data/vendor/libgit2/deps/pcre2/pcre2_util.h +179 -0
- data/vendor/libgit2/deps/pcre2/pcre2_valid_utf.c +397 -0
- data/vendor/libgit2/deps/pcre2/pcre2_xclass.c +547 -0
- data/vendor/libgit2/include/git2/common.h +13 -1
- data/vendor/libgit2/include/git2/version.h +2 -2
- data/vendor/libgit2/src/libgit2/blame.c +6 -0
- data/vendor/libgit2/src/libgit2/delta.c +8 -0
- data/vendor/libgit2/src/libgit2/indexer.c +3 -2
- data/vendor/libgit2/src/libgit2/settings.c +9 -0
- data/vendor/libgit2/src/libgit2/streams/openssl.c +4 -1
- data/vendor/libgit2/src/libgit2/submodule.c +77 -12
- data/vendor/libgit2/src/libgit2/transports/http.c +4 -4
- data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +2 -1
- data/vendor/libgit2/src/util/fs_path.h +10 -10
- data/vendor/libgit2/src/util/regexp.c +27 -12
- data/vendor/libgit2/src/util/regexp.h +7 -2
- metadata +44 -37
- data/vendor/libgit2/deps/pcre/CMakeLists.txt +0 -140
- data/vendor/libgit2/deps/pcre/COPYING +0 -5
- data/vendor/libgit2/deps/pcre/LICENCE +0 -93
- data/vendor/libgit2/deps/pcre/cmake/COPYING-CMAKE-SCRIPTS +0 -22
- data/vendor/libgit2/deps/pcre/cmake/FindEditline.cmake +0 -17
- data/vendor/libgit2/deps/pcre/cmake/FindPackageHandleStandardArgs.cmake +0 -58
- data/vendor/libgit2/deps/pcre/cmake/FindReadline.cmake +0 -29
- data/vendor/libgit2/deps/pcre/config.h.in +0 -57
- data/vendor/libgit2/deps/pcre/pcre.h +0 -641
- data/vendor/libgit2/deps/pcre/pcre_byte_order.c +0 -319
- data/vendor/libgit2/deps/pcre/pcre_compile.c +0 -9815
- data/vendor/libgit2/deps/pcre/pcre_config.c +0 -190
- data/vendor/libgit2/deps/pcre/pcre_exec.c +0 -7173
- data/vendor/libgit2/deps/pcre/pcre_fullinfo.c +0 -245
- data/vendor/libgit2/deps/pcre/pcre_get.c +0 -669
- data/vendor/libgit2/deps/pcre/pcre_globals.c +0 -86
- data/vendor/libgit2/deps/pcre/pcre_internal.h +0 -2787
- data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +0 -11913
- data/vendor/libgit2/deps/pcre/pcre_maketables.c +0 -156
- data/vendor/libgit2/deps/pcre/pcre_printint.c +0 -834
- data/vendor/libgit2/deps/pcre/pcre_string_utils.c +0 -211
- data/vendor/libgit2/deps/pcre/pcre_study.c +0 -1686
- data/vendor/libgit2/deps/pcre/pcre_tables.c +0 -727
- data/vendor/libgit2/deps/pcre/pcre_ucd.c +0 -3644
- data/vendor/libgit2/deps/pcre/pcre_valid_utf8.c +0 -301
- data/vendor/libgit2/deps/pcre/pcre_version.c +0 -98
- data/vendor/libgit2/deps/pcre/pcre_xclass.c +0 -268
- data/vendor/libgit2/deps/pcre/pcreposix.c +0 -420
- data/vendor/libgit2/deps/pcre/pcreposix.h +0 -117
- 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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
#
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
184
|
-
0, 0
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
256
|
-
0, 0
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
*
|
|
343
|
+
* Process a callout *
|
|
296
344
|
*************************************************/
|
|
297
345
|
|
|
298
|
-
/*
|
|
346
|
+
/* This function is called to perform a callout.
|
|
299
347
|
|
|
300
348
|
Arguments:
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
-
|
|
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
|
|
309
|
-
|
|
420
|
+
static int
|
|
421
|
+
more_workspace(RWS_anchor **rwsptr, unsigned int ovecsize, dfa_match_block *mb)
|
|
310
422
|
{
|
|
311
|
-
|
|
312
|
-
|
|
423
|
+
RWS_anchor *rws = *rwsptr;
|
|
424
|
+
RWS_anchor *new;
|
|
425
|
+
|
|
426
|
+
if (rws->next != NULL)
|
|
313
427
|
{
|
|
314
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
525
|
+
else return PCRE2_ERROR_DFA_WSSIZE
|
|
394
526
|
|
|
395
527
|
/* And now, here is the code */
|
|
396
528
|
|
|
397
529
|
static int
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
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
|
-
|
|
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
|
-
|
|
413
|
-
|
|
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
|
|
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
|
-
|
|
424
|
-
|
|
425
|
-
|
|
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
|
|
428
|
-
BOOL utf = (
|
|
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
|
-
|
|
436
|
-
|
|
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
|
-
|
|
443
|
-
|
|
444
|
-
|
|
574
|
+
ctypes = mb->tables + ctypes_offset;
|
|
575
|
+
lcc = mb->tables + lcc_offset;
|
|
576
|
+
fcc = mb->tables + fcc_offset;
|
|
445
577
|
|
|
446
|
-
|
|
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
|
|
467
|
-
|
|
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 (*
|
|
592
|
+
if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT)
|
|
471
593
|
{
|
|
472
|
-
|
|
473
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
506
|
-
|
|
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 <
|
|
513
|
-
|
|
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
|
-
|
|
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 +
|
|
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 && (
|
|
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
|
-
|
|
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
|
|
734
|
+
#ifdef SUPPORT_UNICODE
|
|
622
735
|
GETCHARLENTEST(c, ptr, clen);
|
|
623
736
|
#else
|
|
624
737
|
c = *ptr;
|
|
625
|
-
#endif /*
|
|
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
|
-
|
|
755
|
+
PCRE2_SPTR code;
|
|
756
|
+
uint32_t codevalue;
|
|
643
757
|
int state_offset = current_state->offset;
|
|
644
|
-
int
|
|
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
|
|
817
|
+
#ifdef SUPPORT_UNICODE
|
|
715
818
|
if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
|
|
716
|
-
#endif /*
|
|
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
|
|
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
|
-
|
|
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
|
-
((
|
|
787
|
-
((
|
|
788
|
-
current_subject > start_subject +
|
|
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,
|
|
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] = (
|
|
798
|
-
offsets[1] = (
|
|
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 && (
|
|
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 && (
|
|
871
|
-
(ptr != end_subject
|
|
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 ((
|
|
880
|
-
|
|
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 >=
|
|
907
|
-
(
|
|
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
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
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 ((
|
|
1023
|
+
if ((mb->moptions & PCRE2_NOTEOL) == 0)
|
|
938
1024
|
{
|
|
939
|
-
if (clen == 0 && (
|
|
1025
|
+
if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
|
|
940
1026
|
could_continue = TRUE;
|
|
941
1027
|
else if (clen == 0 ||
|
|
942
|
-
((
|
|
943
|
-
(ptr == end_subject -
|
|
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 >=
|
|
947
|
-
(
|
|
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 ((
|
|
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 ((
|
|
1050
|
+
if ((mb->moptions & PCRE2_NOTEOL) == 0)
|
|
965
1051
|
{
|
|
966
|
-
if (clen == 0 && (
|
|
1052
|
+
if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
|
|
967
1053
|
could_continue = TRUE;
|
|
968
1054
|
else if (clen == 0 ||
|
|
969
|
-
((
|
|
1055
|
+
((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
|
|
970
1056
|
{ ADD_ACTIVE(state_offset + 1, 0); }
|
|
971
|
-
else if (ptr + 1 >=
|
|
972
|
-
(
|
|
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 ((
|
|
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
|
-
|
|
1017
|
-
if (temp <
|
|
1018
|
-
#if defined
|
|
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
|
|
1023
|
-
if (
|
|
1110
|
+
#ifdef SUPPORT_UNICODE
|
|
1111
|
+
if (codevalue == OP_UCP_WORD_BOUNDARY ||
|
|
1112
|
+
codevalue == OP_NOT_UCP_WORD_BOUNDARY)
|
|
1024
1113
|
{
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
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
|
-
|
|
1040
|
-
if ((md->poptions & PCRE_UCP) != 0)
|
|
1127
|
+
if (ptr >= mb->last_used_ptr)
|
|
1041
1128
|
{
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
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) ==
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1081
|
-
|
|
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
|
-
|
|
1100
|
-
|
|
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
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
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 >=
|
|
1171
|
-
(
|
|
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 >=
|
|
1202
|
-
(
|
|
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 >=
|
|
1232
|
-
(
|
|
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 >=
|
|
1260
|
-
(
|
|
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 >=
|
|
1289
|
-
(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1339
|
-
|
|
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
|
-
|
|
1358
|
-
|
|
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
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
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
|
-
|
|
1438
|
-
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1591
|
-
|
|
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
|
-
|
|
1610
|
-
|
|
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
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
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
|
-
|
|
1700
|
-
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1868
|
-
|
|
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
|
-
|
|
1887
|
-
|
|
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
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1971
|
-
|
|
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 (
|
|
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
|
|
2126
|
-
if (
|
|
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 /*
|
|
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
|
|
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
|
-
|
|
2168
|
-
|
|
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 (
|
|
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 ((
|
|
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
|
-
|
|
2291
|
-
#ifdef
|
|
2292
|
-
if (
|
|
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 /*
|
|
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
|
-
|
|
2454
|
+
uint32_t otherd = NOTACHAR;
|
|
2330
2455
|
if (caseless)
|
|
2331
2456
|
{
|
|
2332
|
-
#ifdef
|
|
2333
|
-
if (
|
|
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 /*
|
|
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
|
-
|
|
2497
|
+
uint32_t otherd = NOTACHAR;
|
|
2377
2498
|
if (caseless)
|
|
2378
2499
|
{
|
|
2379
|
-
#ifdef
|
|
2380
|
-
if (
|
|
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 /*
|
|
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
|
-
|
|
2538
|
+
uint32_t otherd = NOTACHAR;
|
|
2422
2539
|
if (caseless)
|
|
2423
2540
|
{
|
|
2424
|
-
#ifdef
|
|
2425
|
-
if (
|
|
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 /*
|
|
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
|
-
|
|
2571
|
+
uint32_t otherd = NOTACHAR;
|
|
2459
2572
|
if (caseless)
|
|
2460
2573
|
{
|
|
2461
|
-
#ifdef
|
|
2462
|
-
if (
|
|
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 /*
|
|
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
|
-
|
|
2611
|
+
uint32_t otherd = NOTACHAR;
|
|
2503
2612
|
if (caseless)
|
|
2504
2613
|
{
|
|
2505
|
-
#ifdef
|
|
2506
|
-
if (
|
|
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 /*
|
|
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
|
-
|
|
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(
|
|
2682
|
+
ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR));
|
|
2549
2683
|
if (clen > 0)
|
|
2550
2684
|
{
|
|
2551
2685
|
isinclass = (c > 255)? (codevalue == OP_NCLASS) :
|
|
2552
|
-
((((
|
|
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
|
|
2666
|
-
|
|
2667
|
-
|
|
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 =
|
|
2672
|
-
|
|
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
|
-
(
|
|
2812
|
+
(PCRE2_SIZE)(ptr - start_subject), /* start offset */
|
|
2676
2813
|
local_offsets, /* offset vector */
|
|
2677
|
-
|
|
2814
|
+
RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
|
|
2678
2815
|
local_workspace, /* workspace vector */
|
|
2679
|
-
|
|
2680
|
-
rlevel
|
|
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
|
|
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
|
|
2693
|
-
|
|
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
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
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 +=
|
|
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
|
|
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 ==
|
|
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
|
|
2755
|
-
if (
|
|
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
|
-
|
|
2766
|
-
|
|
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 =
|
|
2771
|
-
|
|
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
|
-
(
|
|
2911
|
+
(PCRE2_SIZE)(ptr - start_subject), /* start offset */
|
|
2775
2912
|
local_offsets, /* offset vector */
|
|
2776
|
-
|
|
2913
|
+
RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
|
|
2777
2914
|
local_workspace, /* workspace vector */
|
|
2778
|
-
|
|
2779
|
-
rlevel
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
2809
|
-
|
|
2810
|
-
|
|
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.
|
|
2818
|
-
|
|
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 =
|
|
2821
|
-
|
|
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
|
-
(
|
|
2983
|
+
(PCRE2_SIZE)(ptr - start_subject), /* start offset */
|
|
2825
2984
|
local_offsets, /* offset vector */
|
|
2826
|
-
|
|
2985
|
+
RWS_OVEC_RSIZE/OVEC_UNIT, /* size of same */
|
|
2827
2986
|
local_workspace, /* workspace vector */
|
|
2828
|
-
|
|
2829
|
-
rlevel
|
|
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
|
-
|
|
2834
|
-
|
|
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
|
|
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
|
-
|
|
2849
|
-
#if defined
|
|
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
|
-
|
|
2853
|
-
|
|
2854
|
-
while (p < pp) if (
|
|
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,
|
|
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 !=
|
|
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
|
|
2879
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2895
|
-
|
|
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
|
-
(
|
|
3072
|
+
(PCRE2_SIZE)(ptr - start_subject), /* start offset */
|
|
2902
3073
|
local_offsets, /* offset vector */
|
|
2903
|
-
|
|
3074
|
+
RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
|
|
2904
3075
|
local_workspace, /* workspace vector */
|
|
2905
|
-
|
|
2906
|
-
rlevel
|
|
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 !=
|
|
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
|
-
|
|
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
|
-
|
|
2951
|
-
|
|
2952
|
-
charcount = (
|
|
2953
|
-
#if defined
|
|
2954
|
-
if (utf) while (p < pp) if (
|
|
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
|
|
2967
|
-
int local_workspace
|
|
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
|
-
|
|
2970
|
-
|
|
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
|
-
(
|
|
3159
|
+
(PCRE2_SIZE)(ptr - start_subject), /* start offset */
|
|
2974
3160
|
local_offsets, /* offset vector */
|
|
2975
|
-
|
|
3161
|
+
RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */
|
|
2976
3162
|
local_workspace, /* workspace vector */
|
|
2977
|
-
|
|
2978
|
-
rlevel
|
|
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
|
-
|
|
2983
|
-
|
|
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
|
|
3224
|
+
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
|
|
3036
3225
|
if (utf)
|
|
3037
3226
|
{
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
while (p < pp) if (
|
|
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 !=
|
|
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
|
-
|
|
3058
|
-
if (PUBL(callout) != NULL)
|
|
3246
|
+
case OP_CALLOUT_STR:
|
|
3059
3247
|
{
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
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
|
|
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
|
|
3099
|
-
|
|
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 (
|
|
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
|
-
(
|
|
3279
|
+
(mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */
|
|
3116
3280
|
|| /* or... */
|
|
3117
|
-
((
|
|
3118
|
-
match_count < 0)
|
|
3281
|
+
((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 && /* Soft partial and */
|
|
3282
|
+
match_count < 0) /* no matches */
|
|
3119
3283
|
) && /* And... */
|
|
3120
3284
|
(
|
|
3121
|
-
partial_newline ||
|
|
3122
|
-
(
|
|
3123
|
-
ptr >= end_subject &&
|
|
3124
|
-
|
|
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 =
|
|
3128
|
-
|
|
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.
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
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
|
-
*
|
|
3317
|
+
* Match a pattern using the DFA algorithm *
|
|
3153
3318
|
*************************************************/
|
|
3154
3319
|
|
|
3155
|
-
/* This
|
|
3156
|
-
|
|
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
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
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
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
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
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
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
|
-
|
|
3199
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3227
|
-
|
|
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
|
-
|
|
3232
|
-
|
|
3376
|
+
pcre2_callout_block cb;
|
|
3377
|
+
dfa_match_block actual_match_block;
|
|
3378
|
+
dfa_match_block *mb = &actual_match_block;
|
|
3233
3379
|
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
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
|
-
|
|
3393
|
+
if (subject == NULL && length == 0) subject = null_str;
|
|
3242
3394
|
|
|
3243
|
-
|
|
3244
|
-
|
|
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 (
|
|
3403
|
+
if (length == PCRE2_ZERO_TERMINATED)
|
|
3247
3404
|
{
|
|
3248
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3263
|
-
|
|
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
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
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
|
-
|
|
3274
|
-
(re->options & PCRE_ANCHORED) != 0;
|
|
3418
|
+
/* Invalid UTF support is not available for DFA matching. */
|
|
3275
3419
|
|
|
3276
|
-
|
|
3420
|
+
if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)
|
|
3421
|
+
{ rc = PCRE2_ERROR_DFA_UINVALID_UTF; goto EXIT; }
|
|
3277
3422
|
|
|
3278
|
-
|
|
3279
|
-
|
|
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
|
-
|
|
3287
|
-
|
|
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 ((
|
|
3455
|
+
if ((options & PCRE2_DFA_RESTART) != 0)
|
|
3290
3456
|
{
|
|
3291
|
-
if ((
|
|
3292
|
-
|
|
3293
|
-
|
|
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
|
-
/*
|
|
3299
|
-
nothing is set at run time, whatever was used at compile time applies. */
|
|
3462
|
+
/* Set some local values */
|
|
3300
3463
|
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
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
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3334
|
-
|
|
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
|
-
|
|
3339
|
-
|
|
3518
|
+
if (mb->match_limit > re->limit_match)
|
|
3519
|
+
mb->match_limit = re->limit_match;
|
|
3340
3520
|
|
|
3341
|
-
|
|
3342
|
-
|
|
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
|
-
|
|
3372
|
-
|
|
3373
|
-
in other programs later. */
|
|
3524
|
+
if (mb->heap_limit > re->limit_heap)
|
|
3525
|
+
mb->heap_limit = re->limit_heap;
|
|
3374
3526
|
|
|
3375
|
-
|
|
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
|
-
/*
|
|
3378
|
-
where to start. */
|
|
3539
|
+
/* Process the \R and newline settings. */
|
|
3379
3540
|
|
|
3380
|
-
|
|
3381
|
-
|
|
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
|
-
/*
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
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
|
-
|
|
3590
|
+
#ifdef SUPPORT_UNICODE
|
|
3591
|
+
if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
|
|
3390
3592
|
{
|
|
3391
|
-
|
|
3593
|
+
PCRE2_SPTR check_subject = start_match; /* start_match includes offset */
|
|
3594
|
+
|
|
3595
|
+
if (start_offset > 0)
|
|
3392
3596
|
{
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
if (
|
|
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
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
3407
|
-
|
|
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
|
-
/*
|
|
3413
|
-
|
|
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 &
|
|
3634
|
+
if ((re->flags & PCRE2_FIRSTSET) != 0)
|
|
3416
3635
|
{
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
if ((re->flags &
|
|
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
|
-
|
|
3422
|
-
#
|
|
3423
|
-
|
|
3424
|
-
|
|
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
|
-
|
|
3701
|
+
/* ----------------- Start of match optimizations ---------------- */
|
|
3436
3702
|
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
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.
|
|
3443
|
-
|
|
3444
|
-
the
|
|
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
|
-
|
|
3449
|
-
#ifdef
|
|
3722
|
+
PCRE2_SPTR t = start_match;
|
|
3723
|
+
#ifdef SUPPORT_UNICODE
|
|
3450
3724
|
if (utf)
|
|
3451
3725
|
{
|
|
3452
|
-
while (t <
|
|
3726
|
+
while (t < end_subject && !IS_NEWLINE(t))
|
|
3453
3727
|
{
|
|
3454
3728
|
t++;
|
|
3455
|
-
ACROSSCHAR(t < end_subject,
|
|
3729
|
+
ACROSSCHAR(t < end_subject, t, t++);
|
|
3456
3730
|
}
|
|
3457
3731
|
}
|
|
3458
3732
|
else
|
|
3459
3733
|
#endif
|
|
3460
|
-
while (t <
|
|
3734
|
+
while (t < end_subject && !IS_NEWLINE(t)) t++;
|
|
3461
3735
|
end_subject = t;
|
|
3462
3736
|
}
|
|
3463
3737
|
|
|
3464
|
-
/*
|
|
3465
|
-
|
|
3466
|
-
|
|
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 (
|
|
3742
|
+
if (anchored)
|
|
3471
3743
|
{
|
|
3472
|
-
|
|
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
|
-
|
|
3765
|
+
else
|
|
3766
|
+
{
|
|
3767
|
+
if (has_first_cu)
|
|
3475
3768
|
{
|
|
3476
|
-
if (
|
|
3769
|
+
if (first_cu != first_cu2) /* Caseless */
|
|
3477
3770
|
{
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
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
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
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
|
-
/*
|
|
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 (
|
|
3866
|
+
if (start_match > mb->start_subject + start_offset)
|
|
3494
3867
|
{
|
|
3495
|
-
#ifdef
|
|
3868
|
+
#ifdef SUPPORT_UNICODE
|
|
3496
3869
|
if (utf)
|
|
3497
3870
|
{
|
|
3498
|
-
while (
|
|
3499
|
-
!WAS_NEWLINE(current_subject))
|
|
3871
|
+
while (start_match < end_subject && !WAS_NEWLINE(start_match))
|
|
3500
3872
|
{
|
|
3501
|
-
|
|
3502
|
-
ACROSSCHAR(
|
|
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 (
|
|
3509
|
-
|
|
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
|
|
3884
|
+
more code unit. */
|
|
3514
3885
|
|
|
3515
|
-
if (
|
|
3516
|
-
(
|
|
3517
|
-
|
|
3518
|
-
UCHAR21TEST(
|
|
3519
|
-
|
|
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
|
-
/*
|
|
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 (
|
|
3901
|
+
while (start_match < end_subject)
|
|
3528
3902
|
{
|
|
3529
|
-
|
|
3530
|
-
#
|
|
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] & (
|
|
3534
|
-
|
|
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 =
|
|
3921
|
+
end_subject = mb->end_subject;
|
|
3542
3922
|
|
|
3543
|
-
/* The following two optimizations are disabled for partial matching
|
|
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 ((
|
|
3548
|
-
(options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0)
|
|
3925
|
+
if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0)
|
|
3549
3926
|
{
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
using
|
|
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
|
|
3571
|
-
string... so we don't do this when the string is
|
|
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
|
-
|
|
3958
|
+
p = start_match + (has_first_cu? 1:0);
|
|
3959
|
+
if (has_req_cu && p > req_cu_ptr)
|
|
3574
3960
|
{
|
|
3575
|
-
|
|
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 (
|
|
3963
|
+
if (check_length < REQ_CU_MAX ||
|
|
3964
|
+
(!anchored && check_length < REQ_CU_MAX * 1000))
|
|
3581
3965
|
{
|
|
3582
|
-
if (
|
|
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
|
-
|
|
3587
|
-
if (pp ==
|
|
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) ==
|
|
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
|
|
3599
|
-
|
|
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
|
|
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
|
|
4008
|
+
the start hasn't passed this code unit yet. */
|
|
3606
4009
|
|
|
3607
|
-
|
|
4010
|
+
req_cu_ptr = p;
|
|
3608
4011
|
}
|
|
3609
4012
|
}
|
|
3610
4013
|
}
|
|
3611
|
-
}
|
|
4014
|
+
}
|
|
3612
4015
|
|
|
3613
|
-
/*
|
|
4016
|
+
/* ------------ End of start of match optimizations ------------ */
|
|
4017
|
+
|
|
4018
|
+
/* Give no match if we have passed the bumpalong limit. */
|
|
3614
4019
|
|
|
3615
|
-
|
|
3616
|
-
md->recursive = NULL;
|
|
4020
|
+
if (start_match > bumpalong_limit) break;
|
|
3617
4021
|
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
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 !=
|
|
4043
|
+
if (rc != PCRE2_ERROR_NOMATCH || anchored)
|
|
3633
4044
|
{
|
|
3634
|
-
if (rc ==
|
|
4045
|
+
if (rc == PCRE2_ERROR_NOMATCH) goto NOMATCH_EXIT;
|
|
4046
|
+
|
|
4047
|
+
if (rc == PCRE2_ERROR_PARTIAL && match_data->oveccount > 0)
|
|
3635
4048
|
{
|
|
3636
|
-
|
|
3637
|
-
|
|
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
|
-
|
|
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(
|
|
3648
|
-
|
|
3649
|
-
#ifdef
|
|
4086
|
+
if (firstline && IS_NEWLINE(start_match)) break;
|
|
4087
|
+
start_match++;
|
|
4088
|
+
#ifdef SUPPORT_UNICODE
|
|
3650
4089
|
if (utf)
|
|
3651
4090
|
{
|
|
3652
|
-
ACROSSCHAR(
|
|
3653
|
-
current_subject++);
|
|
4091
|
+
ACROSSCHAR(start_match < end_subject, start_match, start_match++);
|
|
3654
4092
|
}
|
|
3655
4093
|
#endif
|
|
3656
|
-
if (
|
|
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(
|
|
3663
|
-
|
|
3664
|
-
UCHAR21TEST(
|
|
3665
|
-
(re->flags &
|
|
3666
|
-
(
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
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
|
-
|
|
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
|
-
/*
|
|
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 */
|