summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/libpcre/libpcre2/CVE-2022-1587.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-support/libpcre/libpcre2/CVE-2022-1587.patch')
-rw-r--r--meta/recipes-support/libpcre/libpcre2/CVE-2022-1587.patch660
1 files changed, 660 insertions, 0 deletions
diff --git a/meta/recipes-support/libpcre/libpcre2/CVE-2022-1587.patch b/meta/recipes-support/libpcre/libpcre2/CVE-2022-1587.patch
new file mode 100644
index 0000000000..70f9f9f079
--- /dev/null
+++ b/meta/recipes-support/libpcre/libpcre2/CVE-2022-1587.patch
@@ -0,0 +1,660 @@
1From aa5aac0d209e3debf80fc2db924d9401fc50454b Mon Sep 17 00:00:00 2001
2From: Hitendra Prajapati <hprajapati@mvista.com>
3Date: Mon, 23 May 2022 14:11:11 +0530
4Subject: [PATCH] CVE-2022-1587
5
6Upstream-Status: Backport [https://github.com/PCRE2Project/pcre2/commit/03654e751e7f0700693526b67dfcadda6b42c9d0]
7CVE: CVE-2022-1587
8Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
9
10---
11 ChangeLog | 3 +
12 src/pcre2_jit_compile.c | 290 ++++++++++++++++++++++++++--------------
13 src/pcre2_jit_test.c | 1 +
14 3 files changed, 194 insertions(+), 100 deletions(-)
15
16diff --git a/ChangeLog b/ChangeLog
17index b5d72dc..de82de9 100644
18--- a/ChangeLog
19+++ b/ChangeLog
20@@ -4,6 +4,9 @@ Change Log for PCRE2
21 23. Fixed a unicode properrty matching issue in JIT. The character was not
22 fully read in caseless matching.
23
24+24. Fixed an issue affecting recursions in JIT caused by duplicated data
25+transfers.
26+
27
28 Version 10.34 21-November-2019
29 ------------------------------
30diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
31index 5d43865..493c96d 100644
32--- a/src/pcre2_jit_compile.c
33+++ b/src/pcre2_jit_compile.c
34@@ -407,6 +407,9 @@ typedef struct compiler_common {
35 /* Locals used by fast fail optimization. */
36 sljit_s32 fast_fail_start_ptr;
37 sljit_s32 fast_fail_end_ptr;
38+ /* Variables used by recursive call generator. */
39+ sljit_s32 recurse_bitset_size;
40+ uint8_t *recurse_bitset;
41
42 /* Flipped and lower case tables. */
43 const sljit_u8 *fcc;
44@@ -2109,19 +2112,39 @@ for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
45
46 #undef RECURSE_TMP_REG_COUNT
47
48+static BOOL recurse_check_bit(compiler_common *common, sljit_sw bit_index)
49+{
50+uint8_t *byte;
51+uint8_t mask;
52+
53+SLJIT_ASSERT((bit_index & (sizeof(sljit_sw) - 1)) == 0);
54+
55+bit_index >>= SLJIT_WORD_SHIFT;
56+
57+mask = 1 << (bit_index & 0x7);
58+byte = common->recurse_bitset + (bit_index >> 3);
59+
60+if (*byte & mask)
61+ return FALSE;
62+
63+*byte |= mask;
64+return TRUE;
65+}
66+
67 static int get_recurse_data_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,
68 BOOL *needs_control_head, BOOL *has_quit, BOOL *has_accept)
69 {
70 int length = 1;
71-int size;
72+int size, offset;
73 PCRE2_SPTR alternative;
74 BOOL quit_found = FALSE;
75 BOOL accept_found = FALSE;
76 BOOL setsom_found = FALSE;
77 BOOL setmark_found = FALSE;
78-BOOL capture_last_found = FALSE;
79 BOOL control_head_found = FALSE;
80
81+memset(common->recurse_bitset, 0, common->recurse_bitset_size);
82+
83 #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
84 SLJIT_ASSERT(common->control_head_ptr != 0);
85 control_head_found = TRUE;
86@@ -2144,15 +2167,17 @@ while (cc < ccend)
87 setsom_found = TRUE;
88 if (common->mark_ptr != 0)
89 setmark_found = TRUE;
90- if (common->capture_last_ptr != 0)
91- capture_last_found = TRUE;
92+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
93+ length++;
94 cc += 1 + LINK_SIZE;
95 break;
96
97 case OP_KET:
98- if (PRIVATE_DATA(cc) != 0)
99+ offset = PRIVATE_DATA(cc);
100+ if (offset != 0)
101 {
102- length++;
103+ if (recurse_check_bit(common, offset))
104+ length++;
105 SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
106 cc += PRIVATE_DATA(cc + 1);
107 }
108@@ -2169,39 +2194,55 @@ while (cc < ccend)
109 case OP_SBRA:
110 case OP_SBRAPOS:
111 case OP_SCOND:
112- length++;
113 SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
114+ if (recurse_check_bit(common, PRIVATE_DATA(cc)))
115+ length++;
116 cc += 1 + LINK_SIZE;
117 break;
118
119 case OP_CBRA:
120 case OP_SCBRA:
121- length += 2;
122- if (common->capture_last_ptr != 0)
123- capture_last_found = TRUE;
124- if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
125+ offset = GET2(cc, 1 + LINK_SIZE);
126+ if (recurse_check_bit(common, OVECTOR(offset << 1)))
127+ {
128+ SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));
129+ length += 2;
130+ }
131+ if (common->optimized_cbracket[offset] == 0 && recurse_check_bit(common, OVECTOR_PRIV(offset)))
132+ length++;
133+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
134 length++;
135 cc += 1 + LINK_SIZE + IMM2_SIZE;
136 break;
137
138 case OP_CBRAPOS:
139 case OP_SCBRAPOS:
140- length += 2 + 2;
141- if (common->capture_last_ptr != 0)
142- capture_last_found = TRUE;
143+ offset = GET2(cc, 1 + LINK_SIZE);
144+ if (recurse_check_bit(common, OVECTOR(offset << 1)))
145+ {
146+ SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));
147+ length += 2;
148+ }
149+ if (recurse_check_bit(common, OVECTOR_PRIV(offset)))
150+ length++;
151+ if (recurse_check_bit(common, PRIVATE_DATA(cc)))
152+ length++;
153+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
154+ length++;
155 cc += 1 + LINK_SIZE + IMM2_SIZE;
156 break;
157
158 case OP_COND:
159 /* Might be a hidden SCOND. */
160 alternative = cc + GET(cc, 1);
161- if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
162+ if ((*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) && recurse_check_bit(common, PRIVATE_DATA(cc)))
163 length++;
164 cc += 1 + LINK_SIZE;
165 break;
166
167 CASE_ITERATOR_PRIVATE_DATA_1
168- if (PRIVATE_DATA(cc) != 0)
169+ offset = PRIVATE_DATA(cc);
170+ if (offset != 0 && recurse_check_bit(common, offset))
171 length++;
172 cc += 2;
173 #ifdef SUPPORT_UNICODE
174@@ -2210,8 +2251,12 @@ while (cc < ccend)
175 break;
176
177 CASE_ITERATOR_PRIVATE_DATA_2A
178- if (PRIVATE_DATA(cc) != 0)
179+ offset = PRIVATE_DATA(cc);
180+ if (offset != 0 && recurse_check_bit(common, offset))
181+ {
182+ SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
183 length += 2;
184+ }
185 cc += 2;
186 #ifdef SUPPORT_UNICODE
187 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
188@@ -2219,8 +2264,12 @@ while (cc < ccend)
189 break;
190
191 CASE_ITERATOR_PRIVATE_DATA_2B
192- if (PRIVATE_DATA(cc) != 0)
193+ offset = PRIVATE_DATA(cc);
194+ if (offset != 0 && recurse_check_bit(common, offset))
195+ {
196+ SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
197 length += 2;
198+ }
199 cc += 2 + IMM2_SIZE;
200 #ifdef SUPPORT_UNICODE
201 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
202@@ -2228,20 +2277,29 @@ while (cc < ccend)
203 break;
204
205 CASE_ITERATOR_TYPE_PRIVATE_DATA_1
206- if (PRIVATE_DATA(cc) != 0)
207+ offset = PRIVATE_DATA(cc);
208+ if (offset != 0 && recurse_check_bit(common, offset))
209 length++;
210 cc += 1;
211 break;
212
213 CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
214- if (PRIVATE_DATA(cc) != 0)
215+ offset = PRIVATE_DATA(cc);
216+ if (offset != 0 && recurse_check_bit(common, offset))
217+ {
218+ SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
219 length += 2;
220+ }
221 cc += 1;
222 break;
223
224 CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
225- if (PRIVATE_DATA(cc) != 0)
226+ offset = PRIVATE_DATA(cc);
227+ if (offset != 0 && recurse_check_bit(common, offset))
228+ {
229+ SLJIT_ASSERT(recurse_check_bit(common, offset + sizeof(sljit_sw)));
230 length += 2;
231+ }
232 cc += 1 + IMM2_SIZE;
233 break;
234
235@@ -2253,7 +2311,9 @@ while (cc < ccend)
236 #else
237 size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
238 #endif
239- if (PRIVATE_DATA(cc) != 0)
240+
241+ offset = PRIVATE_DATA(cc);
242+ if (offset != 0 && recurse_check_bit(common, offset))
243 length += get_class_iterator_size(cc + size);
244 cc += size;
245 break;
246@@ -2288,8 +2348,7 @@ while (cc < ccend)
247 case OP_THEN:
248 SLJIT_ASSERT(common->control_head_ptr != 0);
249 quit_found = TRUE;
250- if (!control_head_found)
251- control_head_found = TRUE;
252+ control_head_found = TRUE;
253 cc++;
254 break;
255
256@@ -2309,8 +2368,6 @@ SLJIT_ASSERT(cc == ccend);
257
258 if (control_head_found)
259 length++;
260-if (capture_last_found)
261- length++;
262 if (quit_found)
263 {
264 if (setsom_found)
265@@ -2343,14 +2400,12 @@ sljit_sw shared_srcw[3];
266 sljit_sw kept_shared_srcw[2];
267 int private_count, shared_count, kept_shared_count;
268 int from_sp, base_reg, offset, i;
269-BOOL setsom_found = FALSE;
270-BOOL setmark_found = FALSE;
271-BOOL capture_last_found = FALSE;
272-BOOL control_head_found = FALSE;
273+
274+memset(common->recurse_bitset, 0, common->recurse_bitset_size);
275
276 #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
277 SLJIT_ASSERT(common->control_head_ptr != 0);
278-control_head_found = TRUE;
279+recurse_check_bit(common, common->control_head_ptr);
280 #endif
281
282 switch (type)
283@@ -2438,11 +2493,10 @@ while (cc < ccend)
284 {
285 case OP_SET_SOM:
286 SLJIT_ASSERT(common->has_set_som);
287- if (has_quit && !setsom_found)
288+ if (has_quit && recurse_check_bit(common, OVECTOR(0)))
289 {
290 kept_shared_srcw[0] = OVECTOR(0);
291 kept_shared_count = 1;
292- setsom_found = TRUE;
293 }
294 cc += 1;
295 break;
296@@ -2450,33 +2504,31 @@ while (cc < ccend)
297 case OP_RECURSE:
298 if (has_quit)
299 {
300- if (common->has_set_som && !setsom_found)
301+ if (common->has_set_som && recurse_check_bit(common, OVECTOR(0)))
302 {
303 kept_shared_srcw[0] = OVECTOR(0);
304 kept_shared_count = 1;
305- setsom_found = TRUE;
306 }
307- if (common->mark_ptr != 0 && !setmark_found)
308+ if (common->mark_ptr != 0 && recurse_check_bit(common, common->mark_ptr))
309 {
310 kept_shared_srcw[kept_shared_count] = common->mark_ptr;
311 kept_shared_count++;
312- setmark_found = TRUE;
313 }
314 }
315- if (common->capture_last_ptr != 0 && !capture_last_found)
316+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
317 {
318 shared_srcw[0] = common->capture_last_ptr;
319 shared_count = 1;
320- capture_last_found = TRUE;
321 }
322 cc += 1 + LINK_SIZE;
323 break;
324
325 case OP_KET:
326- if (PRIVATE_DATA(cc) != 0)
327+ private_srcw[0] = PRIVATE_DATA(cc);
328+ if (private_srcw[0] != 0)
329 {
330- private_count = 1;
331- private_srcw[0] = PRIVATE_DATA(cc);
332+ if (recurse_check_bit(common, private_srcw[0]))
333+ private_count = 1;
334 SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
335 cc += PRIVATE_DATA(cc + 1);
336 }
337@@ -2493,50 +2545,66 @@ while (cc < ccend)
338 case OP_SBRA:
339 case OP_SBRAPOS:
340 case OP_SCOND:
341- private_count = 1;
342 private_srcw[0] = PRIVATE_DATA(cc);
343+ if (recurse_check_bit(common, private_srcw[0]))
344+ private_count = 1;
345 cc += 1 + LINK_SIZE;
346 break;
347
348 case OP_CBRA:
349 case OP_SCBRA:
350- offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
351- shared_srcw[0] = OVECTOR(offset);
352- shared_srcw[1] = OVECTOR(offset + 1);
353- shared_count = 2;
354+ offset = GET2(cc, 1 + LINK_SIZE);
355+ shared_srcw[0] = OVECTOR(offset << 1);
356+ if (recurse_check_bit(common, shared_srcw[0]))
357+ {
358+ shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);
359+ SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));
360+ shared_count = 2;
361+ }
362
363- if (common->capture_last_ptr != 0 && !capture_last_found)
364+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
365 {
366- shared_srcw[2] = common->capture_last_ptr;
367- shared_count = 3;
368- capture_last_found = TRUE;
369+ shared_srcw[shared_count] = common->capture_last_ptr;
370+ shared_count++;
371 }
372
373- if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
374+ if (common->optimized_cbracket[offset] == 0)
375 {
376- private_count = 1;
377- private_srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
378+ private_srcw[0] = OVECTOR_PRIV(offset);
379+ if (recurse_check_bit(common, private_srcw[0]))
380+ private_count = 1;
381 }
382+
383 cc += 1 + LINK_SIZE + IMM2_SIZE;
384 break;
385
386 case OP_CBRAPOS:
387 case OP_SCBRAPOS:
388- offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
389- shared_srcw[0] = OVECTOR(offset);
390- shared_srcw[1] = OVECTOR(offset + 1);
391- shared_count = 2;
392+ offset = GET2(cc, 1 + LINK_SIZE);
393+ shared_srcw[0] = OVECTOR(offset << 1);
394+ if (recurse_check_bit(common, shared_srcw[0]))
395+ {
396+ shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);
397+ SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));
398+ shared_count = 2;
399+ }
400
401- if (common->capture_last_ptr != 0 && !capture_last_found)
402+ if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
403 {
404- shared_srcw[2] = common->capture_last_ptr;
405- shared_count = 3;
406- capture_last_found = TRUE;
407+ shared_srcw[shared_count] = common->capture_last_ptr;
408+ shared_count++;
409 }
410
411- private_count = 2;
412 private_srcw[0] = PRIVATE_DATA(cc);
413- private_srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
414+ if (recurse_check_bit(common, private_srcw[0]))
415+ private_count = 1;
416+
417+ offset = OVECTOR_PRIV(offset);
418+ if (recurse_check_bit(common, offset))
419+ {
420+ private_srcw[private_count] = offset;
421+ private_count++;
422+ }
423 cc += 1 + LINK_SIZE + IMM2_SIZE;
424 break;
425
426@@ -2545,18 +2613,17 @@ while (cc < ccend)
427 alternative = cc + GET(cc, 1);
428 if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
429 {
430- private_count = 1;
431 private_srcw[0] = PRIVATE_DATA(cc);
432+ if (recurse_check_bit(common, private_srcw[0]))
433+ private_count = 1;
434 }
435 cc += 1 + LINK_SIZE;
436 break;
437
438 CASE_ITERATOR_PRIVATE_DATA_1
439- if (PRIVATE_DATA(cc))
440- {
441+ private_srcw[0] = PRIVATE_DATA(cc);
442+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
443 private_count = 1;
444- private_srcw[0] = PRIVATE_DATA(cc);
445- }
446 cc += 2;
447 #ifdef SUPPORT_UNICODE
448 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
449@@ -2564,11 +2631,12 @@ while (cc < ccend)
450 break;
451
452 CASE_ITERATOR_PRIVATE_DATA_2A
453- if (PRIVATE_DATA(cc))
454+ private_srcw[0] = PRIVATE_DATA(cc);
455+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
456 {
457 private_count = 2;
458- private_srcw[0] = PRIVATE_DATA(cc);
459- private_srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
460+ private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
461+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
462 }
463 cc += 2;
464 #ifdef SUPPORT_UNICODE
465@@ -2577,11 +2645,12 @@ while (cc < ccend)
466 break;
467
468 CASE_ITERATOR_PRIVATE_DATA_2B
469- if (PRIVATE_DATA(cc))
470+ private_srcw[0] = PRIVATE_DATA(cc);
471+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
472 {
473 private_count = 2;
474- private_srcw[0] = PRIVATE_DATA(cc);
475- private_srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
476+ private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
477+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
478 }
479 cc += 2 + IMM2_SIZE;
480 #ifdef SUPPORT_UNICODE
481@@ -2590,30 +2659,30 @@ while (cc < ccend)
482 break;
483
484 CASE_ITERATOR_TYPE_PRIVATE_DATA_1
485- if (PRIVATE_DATA(cc))
486- {
487+ private_srcw[0] = PRIVATE_DATA(cc);
488+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
489 private_count = 1;
490- private_srcw[0] = PRIVATE_DATA(cc);
491- }
492 cc += 1;
493 break;
494
495 CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
496- if (PRIVATE_DATA(cc))
497+ private_srcw[0] = PRIVATE_DATA(cc);
498+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
499 {
500 private_count = 2;
501- private_srcw[0] = PRIVATE_DATA(cc);
502 private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
503+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
504 }
505 cc += 1;
506 break;
507
508 CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
509- if (PRIVATE_DATA(cc))
510+ private_srcw[0] = PRIVATE_DATA(cc);
511+ if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
512 {
513 private_count = 2;
514- private_srcw[0] = PRIVATE_DATA(cc);
515 private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
516+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
517 }
518 cc += 1 + IMM2_SIZE;
519 break;
520@@ -2630,14 +2699,17 @@ while (cc < ccend)
521 switch(get_class_iterator_size(cc + i))
522 {
523 case 1:
524- private_count = 1;
525 private_srcw[0] = PRIVATE_DATA(cc);
526 break;
527
528 case 2:
529- private_count = 2;
530 private_srcw[0] = PRIVATE_DATA(cc);
531- private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
532+ if (recurse_check_bit(common, private_srcw[0]))
533+ {
534+ private_count = 2;
535+ private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
536+ SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
537+ }
538 break;
539
540 default:
541@@ -2652,28 +2724,25 @@ while (cc < ccend)
542 case OP_PRUNE_ARG:
543 case OP_THEN_ARG:
544 SLJIT_ASSERT(common->mark_ptr != 0);
545- if (has_quit && !setmark_found)
546+ if (has_quit && recurse_check_bit(common, common->mark_ptr))
547 {
548 kept_shared_srcw[0] = common->mark_ptr;
549 kept_shared_count = 1;
550- setmark_found = TRUE;
551 }
552- if (common->control_head_ptr != 0 && !control_head_found)
553+ if (common->control_head_ptr != 0 && recurse_check_bit(common, common->control_head_ptr))
554 {
555 shared_srcw[0] = common->control_head_ptr;
556 shared_count = 1;
557- control_head_found = TRUE;
558 }
559 cc += 1 + 2 + cc[1];
560 break;
561
562 case OP_THEN:
563 SLJIT_ASSERT(common->control_head_ptr != 0);
564- if (!control_head_found)
565+ if (recurse_check_bit(common, common->control_head_ptr))
566 {
567 shared_srcw[0] = common->control_head_ptr;
568 shared_count = 1;
569- control_head_found = TRUE;
570 }
571 cc++;
572 break;
573@@ -2681,7 +2750,7 @@ while (cc < ccend)
574 default:
575 cc = next_opcode(common, cc);
576 SLJIT_ASSERT(cc != NULL);
577- break;
578+ continue;
579 }
580
581 if (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)
582@@ -13262,7 +13331,7 @@ SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
583 common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
584
585 total_length = ccend - common->start;
586-common->private_data_ptrs = (sljit_s32 *)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data);
587+common->private_data_ptrs = (sljit_s32*)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data);
588 if (!common->private_data_ptrs)
589 {
590 SLJIT_FREE(common->optimized_cbracket, allocator_data);
591@@ -13304,6 +13373,7 @@ if (!compiler)
592 common->compiler = compiler;
593
594 /* Main pcre_jit_exec entry. */
595+LJIT_ASSERT((private_data_size & (sizeof(sljit_sw) - 1)) == 0);
596 sljit_emit_enter(compiler, 0, SLJIT_ARG1(SW), 5, 5, 0, 0, private_data_size);
597
598 /* Register init. */
599@@ -13524,20 +13594,40 @@ common->fast_fail_end_ptr = 0;
600 common->currententry = common->entries;
601 common->local_quit_available = TRUE;
602 quit_label = common->quit_label;
603-while (common->currententry != NULL)
604+if (common->currententry != NULL)
605 {
606- /* Might add new entries. */
607- compile_recurse(common);
608- if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
609+ /* A free bit for each private data. */
610+ common->recurse_bitset_size = ((private_data_size / (int)sizeof(sljit_sw)) + 7) >> 3;
611+ SLJIT_ASSERT(common->recurse_bitset_size > 0);
612+ common->recurse_bitset = (sljit_u8*)SLJIT_MALLOC(common->recurse_bitset_size, allocator_data);;
613+
614+ if (common->recurse_bitset != NULL)
615+ {
616+ do
617+ {
618+ /* Might add new entries. */
619+ compile_recurse(common);
620+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
621+ break;
622+ flush_stubs(common);
623+ common->currententry = common->currententry->next;
624+ }
625+ while (common->currententry != NULL);
626+
627+ SLJIT_FREE(common->recurse_bitset, allocator_data);
628+ }
629+
630+ if (common->currententry != NULL)
631 {
632+ /* The common->recurse_bitset has been freed. */
633+ SLJIT_ASSERT(sljit_get_compiler_error(compiler) || common->recurse_bitset == NULL);
634+
635 sljit_free_compiler(compiler);
636 SLJIT_FREE(common->optimized_cbracket, allocator_data);
637 SLJIT_FREE(common->private_data_ptrs, allocator_data);
638 PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
639 return PCRE2_ERROR_NOMEMORY;
640 }
641- flush_stubs(common);
642- common->currententry = common->currententry->next;
643 }
644 common->local_quit_available = FALSE;
645 common->quit_label = quit_label;
646diff --git a/src/pcre2_jit_test.c b/src/pcre2_jit_test.c
647index 9df87fd..2f84834 100644
648--- a/src/pcre2_jit_test.c
649+++ b/src/pcre2_jit_test.c
650@@ -746,6 +746,7 @@ static struct regression_test_case regression_test_cases[] = {
651 { MU, A, 0, 0, "((?(R)a|(?1)){1,3}?)M", "aaaM" },
652 { MU, A, 0, 0, "((.)(?:.|\\2(?1))){0}#(?1)#", "#aabbccdde# #aabbccddee#" },
653 { MU, A, 0, 0, "((.)(?:\\2|\\2{4}b)){0}#(?:(?1))+#", "#aaaab# #aaaaab#" },
654+ { MU, A, 0, 0 | F_NOMATCH, "(?1)$((.|\\2xx){1,2})", "abc" },
655
656 /* 16 bit specific tests. */
657 { CM, A, 0, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" },
658--
6592.25.1
660