Commit | Line | Data |
---|---|---|
13bea701 VM |
1 | Index: pcre/configure.ac |
2 | =================================================================== | |
3 | --- pcre/configure.ac (revision 1553) | |
4 | +++ pcre/configure.ac (working copy) | |
5 | @@ -9,9 +9,9 @@ | |
6 | dnl be defined as -RC2, for example. For real releases, it should be empty. | |
7 | ||
8 | m4_define(pcre_major, [8]) | |
9 | -m4_define(pcre_minor, [37]) | |
10 | -m4_define(pcre_prerelease, []) | |
11 | -m4_define(pcre_date, [2015-04-28]) | |
12 | +m4_define(pcre_minor, [38]) | |
13 | +m4_define(pcre_prerelease, [-RC1]) | |
14 | +m4_define(pcre_date, [2015-05-03]) | |
15 | ||
16 | # NOTE: The CMakeLists.txt file searches for the above variables in the first | |
17 | # 50 lines of this file. Please update that if the variables above are moved. | |
18 | Index: pcre/sljit/sljitConfig.h | |
19 | =================================================================== | |
20 | --- pcre/sljit/sljitConfig.h (revision 1553) | |
21 | +++ pcre/sljit/sljitConfig.h (working copy) | |
22 | @@ -96,6 +96,15 @@ | |
23 | #define SLJIT_EXECUTABLE_ALLOCATOR 1 | |
24 | #endif | |
25 | ||
26 | +/* Force cdecl calling convention even if a better calling | |
27 | + convention (e.g. fastcall) is supported by the C compiler. | |
28 | + If this option is enabled, C functions without | |
29 | + SLJIT_CALL can also be called from JIT code. */ | |
30 | +#ifndef SLJIT_USE_CDECL_CALLING_CONVENTION | |
31 | +/* Disabled by default */ | |
32 | +#define SLJIT_USE_CDECL_CALLING_CONVENTION 0 | |
33 | +#endif | |
34 | + | |
35 | /* Return with error when an invalid argument is passed. */ | |
36 | #ifndef SLJIT_ARGUMENT_CHECKS | |
37 | /* Disabled by default */ | |
38 | Index: pcre/sljit/sljitLir.c | |
39 | =================================================================== | |
40 | --- pcre/sljit/sljitLir.c (revision 1553) | |
41 | +++ pcre/sljit/sljitLir.c (working copy) | |
42 | @@ -845,8 +845,8 @@ | |
43 | } | |
44 | ||
45 | static SLJIT_CONST char* op0_names[] = { | |
46 | - (char*)"breakpoint", (char*)"nop", | |
47 | - (char*)"lumul", (char*)"lsmul", (char*)"ludiv", (char*)"lsdiv", | |
48 | + (char*)"breakpoint", (char*)"nop", (char*)"lumul", (char*)"lsmul", | |
49 | + (char*)"udivmod", (char*)"sdivmod", (char*)"udivi", (char*)"sdivi" | |
50 | }; | |
51 | ||
52 | static SLJIT_CONST char* op1_names[] = { | |
53 | @@ -1036,7 +1036,7 @@ | |
54 | { | |
55 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) | |
56 | CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LSMUL) | |
57 | - || ((op & ~SLJIT_INT_OP) >= SLJIT_LUDIV && (op & ~SLJIT_INT_OP) <= SLJIT_LSDIV)); | |
58 | + || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIVMOD && (op & ~SLJIT_INT_OP) <= SLJIT_SDIVI)); | |
59 | CHECK_ARGUMENT(op < SLJIT_LUMUL || compiler->scratches >= 2); | |
60 | #endif | |
61 | #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) | |
62 | @@ -1447,6 +1447,8 @@ | |
63 | ||
64 | static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) | |
65 | { | |
66 | + SLJIT_UNUSED_ARG(offset); | |
67 | + | |
68 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) | |
69 | FUNCTION_CHECK_DST(dst, dstw); | |
70 | #endif | |
71 | @@ -1462,6 +1464,8 @@ | |
72 | ||
73 | static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) | |
74 | { | |
75 | + SLJIT_UNUSED_ARG(init_value); | |
76 | + | |
77 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) | |
78 | FUNCTION_CHECK_DST(dst, dstw); | |
79 | #endif | |
80 | Index: pcre/sljit/sljitNativeMIPS_common.c | |
81 | =================================================================== | |
82 | --- pcre/sljit/sljitNativeMIPS_common.c (revision 1553) | |
83 | +++ pcre/sljit/sljitNativeMIPS_common.c (working copy) | |
84 | @@ -1053,8 +1053,11 @@ | |
85 | #endif | |
86 | FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); | |
87 | return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); | |
88 | - case SLJIT_LUDIV: | |
89 | - case SLJIT_LSDIV: | |
90 | + case SLJIT_UDIVMOD: | |
91 | + case SLJIT_SDIVMOD: | |
92 | + case SLJIT_UDIVI: | |
93 | + case SLJIT_SDIVI: | |
94 | + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); | |
95 | #if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) | |
96 | FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); | |
97 | FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); | |
98 | @@ -1062,15 +1065,15 @@ | |
99 | ||
100 | #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) | |
101 | if (int_op) | |
102 | - FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); | |
103 | + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); | |
104 | else | |
105 | - FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); | |
106 | + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); | |
107 | #else | |
108 | - FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); | |
109 | + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); | |
110 | #endif | |
111 | ||
112 | FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); | |
113 | - return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); | |
114 | + return (op >= SLJIT_UDIVI) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); | |
115 | } | |
116 | ||
117 | return SLJIT_SUCCESS; | |
118 | Index: pcre/sljit/sljitNativeSPARC_common.c | |
119 | =================================================================== | |
120 | --- pcre/sljit/sljitNativeSPARC_common.c (revision 1553) | |
121 | +++ pcre/sljit/sljitNativeSPARC_common.c (working copy) | |
122 | @@ -777,20 +777,25 @@ | |
123 | #else | |
124 | #error "Implementation required" | |
125 | #endif | |
126 | - case SLJIT_LUDIV: | |
127 | - case SLJIT_LSDIV: | |
128 | + case SLJIT_UDIVMOD: | |
129 | + case SLJIT_SDIVMOD: | |
130 | + case SLJIT_UDIVI: | |
131 | + case SLJIT_SDIVI: | |
132 | + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); | |
133 | #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) | |
134 | - if (op == SLJIT_LUDIV) | |
135 | + if ((op | 0x2) == SLJIT_UDIVI) | |
136 | FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS)); | |
137 | else { | |
138 | FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1))); | |
139 | FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS)); | |
140 | } | |
141 | - FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2))); | |
142 | - FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); | |
143 | + if (op <= SLJIT_SDIVMOD) | |
144 | + FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2))); | |
145 | + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); | |
146 | + if (op >= SLJIT_UDIVI) | |
147 | + return SLJIT_SUCCESS; | |
148 | FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1))); | |
149 | - FAIL_IF(push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1))); | |
150 | - return SLJIT_SUCCESS; | |
151 | + return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1)); | |
152 | #else | |
153 | #error "Implementation required" | |
154 | #endif | |
155 | Index: pcre/sljit/sljitNativeARM_32.c | |
156 | =================================================================== | |
157 | --- pcre/sljit/sljitNativeARM_32.c (revision 1553) | |
158 | +++ pcre/sljit/sljitNativeARM_32.c (working copy) | |
159 | @@ -1833,18 +1833,33 @@ | |
160 | | (reg_map[SLJIT_R0] << 8) | |
161 | | reg_map[TMP_REG1]); | |
162 | #endif | |
163 | - case SLJIT_LUDIV: | |
164 | - case SLJIT_LSDIV: | |
165 | - if (compiler->scratches >= 3) | |
166 | + case SLJIT_UDIVMOD: | |
167 | + case SLJIT_SDIVMOD: | |
168 | + case SLJIT_UDIVI: | |
169 | + case SLJIT_SDIVI: | |
170 | + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); | |
171 | + SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping); | |
172 | + | |
173 | + if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { | |
174 | FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */)); | |
175 | + FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */)); | |
176 | + } | |
177 | + else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) | |
178 | + FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */)); | |
179 | + | |
180 | #if defined(__GNUC__) | |
181 | FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, | |
182 | - (op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); | |
183 | + ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); | |
184 | #else | |
185 | #error "Software divmod functions are needed" | |
186 | #endif | |
187 | - if (compiler->scratches >= 3) | |
188 | - return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */); | |
189 | + | |
190 | + if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { | |
191 | + FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */)); | |
192 | + FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */)); | |
193 | + } | |
194 | + else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) | |
195 | + return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */); | |
196 | return SLJIT_SUCCESS; | |
197 | } | |
198 | ||
199 | Index: pcre/sljit/sljitLir.h | |
200 | =================================================================== | |
201 | --- pcre/sljit/sljitLir.h (revision 1553) | |
202 | +++ pcre/sljit/sljitLir.h (working copy) | |
203 | @@ -687,7 +687,7 @@ | |
204 | #define SLJIT_OP0_BASE 0 | |
205 | ||
206 | /* Flags: - (never set any flags) | |
207 | - Note: breakpoint instruction is not supported by all architectures (namely ppc) | |
208 | + Note: breakpoint instruction is not supported by all architectures (e.g. ppc) | |
209 | It falls back to SLJIT_NOP in those cases. */ | |
210 | #define SLJIT_BREAKPOINT (SLJIT_OP0_BASE + 0) | |
211 | /* Flags: - (never set any flags) | |
212 | @@ -696,24 +696,42 @@ | |
213 | #define SLJIT_NOP (SLJIT_OP0_BASE + 1) | |
214 | /* Flags: - (may destroy flags) | |
215 | Unsigned multiplication of SLJIT_R0 and SLJIT_R1. | |
216 | - Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */ | |
217 | + Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */ | |
218 | #define SLJIT_LUMUL (SLJIT_OP0_BASE + 2) | |
219 | /* Flags: - (may destroy flags) | |
220 | Signed multiplication of SLJIT_R0 and SLJIT_R1. | |
221 | - Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */ | |
222 | + Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */ | |
223 | #define SLJIT_LSMUL (SLJIT_OP0_BASE + 3) | |
224 | /* Flags: I - (may destroy flags) | |
225 | Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1. | |
226 | - The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1. | |
227 | - Note: if SLJIT_R1 contains 0, the behaviour is undefined. */ | |
228 | -#define SLJIT_LUDIV (SLJIT_OP0_BASE + 4) | |
229 | -#define SLJIT_ILUDIV (SLJIT_LUDIV | SLJIT_INT_OP) | |
230 | + The result is placed into SLJIT_R0 and the remainder into SLJIT_R1. | |
231 | + Note: if SLJIT_R1 is 0, the behaviour is undefined. */ | |
232 | +#define SLJIT_UDIVMOD (SLJIT_OP0_BASE + 4) | |
233 | +#define SLJIT_IUDIVMOD (SLJIT_UDIVMOD | SLJIT_INT_OP) | |
234 | /* Flags: I - (may destroy flags) | |
235 | Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1. | |
236 | - The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1. | |
237 | - Note: if SLJIT_R1 contains 0, the behaviour is undefined. */ | |
238 | -#define SLJIT_LSDIV (SLJIT_OP0_BASE + 5) | |
239 | -#define SLJIT_ILSDIV (SLJIT_LSDIV | SLJIT_INT_OP) | |
240 | + The result is placed into SLJIT_R0 and the remainder into SLJIT_R1. | |
241 | + Note: if SLJIT_R1 is 0, the behaviour is undefined. | |
242 | + Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00), | |
243 | + the behaviour is undefined. */ | |
244 | +#define SLJIT_SDIVMOD (SLJIT_OP0_BASE + 5) | |
245 | +#define SLJIT_ISDIVMOD (SLJIT_SDIVMOD | SLJIT_INT_OP) | |
246 | +/* Flags: I - (may destroy flags) | |
247 | + Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1. | |
248 | + The result is placed into SLJIT_R0. SLJIT_R1 preserves its value. | |
249 | + Note: if SLJIT_R1 is 0, the behaviour is undefined. | |
250 | + Note: SLJIT_SDIV is single precision divide. */ | |
251 | +#define SLJIT_UDIVI (SLJIT_OP0_BASE + 6) | |
252 | +#define SLJIT_IUDIVI (SLJIT_UDIVI | SLJIT_INT_OP) | |
253 | +/* Flags: I - (may destroy flags) | |
254 | + Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1. | |
255 | + The result is placed into SLJIT_R0. SLJIT_R1 preserves its value. | |
256 | + Note: if SLJIT_R1 is 0, the behaviour is undefined. | |
257 | + Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00), | |
258 | + the behaviour is undefined. | |
259 | + Note: SLJIT_SDIV is single precision divide. */ | |
260 | +#define SLJIT_SDIVI (SLJIT_OP0_BASE + 7) | |
261 | +#define SLJIT_ISDIVI (SLJIT_SDIVI | SLJIT_INT_OP) | |
262 | ||
263 | SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op); | |
264 | ||
265 | Index: pcre/sljit/sljitNativeARM_T2_32.c | |
266 | =================================================================== | |
267 | --- pcre/sljit/sljitNativeARM_T2_32.c (revision 1553) | |
268 | +++ pcre/sljit/sljitNativeARM_T2_32.c (working copy) | |
269 | @@ -1239,6 +1239,9 @@ | |
270 | ||
271 | SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) | |
272 | { | |
273 | + sljit_sw saved_reg_list[3]; | |
274 | + sljit_sw saved_reg_count; | |
275 | + | |
276 | CHECK_ERROR(); | |
277 | CHECK(check_sljit_emit_op0(compiler, op)); | |
278 | ||
279 | @@ -1255,24 +1258,53 @@ | |
280 | | (reg_map[SLJIT_R0] << 12) | |
281 | | (reg_map[SLJIT_R0] << 16) | |
282 | | reg_map[SLJIT_R1]); | |
283 | - case SLJIT_LUDIV: | |
284 | - case SLJIT_LSDIV: | |
285 | - if (compiler->scratches >= 4) { | |
286 | - FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */)); | |
287 | - FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */)); | |
288 | - } else if (compiler->scratches >= 3) | |
289 | - FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */)); | |
290 | + case SLJIT_UDIVMOD: | |
291 | + case SLJIT_SDIVMOD: | |
292 | + case SLJIT_UDIVI: | |
293 | + case SLJIT_SDIVI: | |
294 | + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); | |
295 | + SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping); | |
296 | + | |
297 | + saved_reg_count = 0; | |
298 | + if (compiler->scratches >= 4) | |
299 | + saved_reg_list[saved_reg_count++] = 12; | |
300 | + if (compiler->scratches >= 3) | |
301 | + saved_reg_list[saved_reg_count++] = 2; | |
302 | + if (op >= SLJIT_UDIVI) | |
303 | + saved_reg_list[saved_reg_count++] = 1; | |
304 | + | |
305 | + if (saved_reg_count > 0) { | |
306 | + FAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8) | |
307 | + | (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */)); | |
308 | + if (saved_reg_count >= 2) { | |
309 | + SLJIT_ASSERT(saved_reg_list[1] < 8); | |
310 | + FAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */)); | |
311 | + } | |
312 | + if (saved_reg_count >= 3) { | |
313 | + SLJIT_ASSERT(saved_reg_list[2] < 8); | |
314 | + FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */)); | |
315 | + } | |
316 | + } | |
317 | + | |
318 | #if defined(__GNUC__) | |
319 | FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, | |
320 | - (op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); | |
321 | + ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); | |
322 | #else | |
323 | #error "Software divmod functions are needed" | |
324 | #endif | |
325 | - if (compiler->scratches >= 4) { | |
326 | - FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */)); | |
327 | - return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */); | |
328 | - } else if (compiler->scratches >= 3) | |
329 | - return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */); | |
330 | + | |
331 | + if (saved_reg_count > 0) { | |
332 | + if (saved_reg_count >= 3) { | |
333 | + SLJIT_ASSERT(saved_reg_list[2] < 8); | |
334 | + FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */)); | |
335 | + } | |
336 | + if (saved_reg_count >= 2) { | |
337 | + SLJIT_ASSERT(saved_reg_list[1] < 8); | |
338 | + FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */)); | |
339 | + } | |
340 | + return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8) | |
341 | + | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */); | |
342 | + } | |
343 | return SLJIT_SUCCESS; | |
344 | } | |
345 | ||
346 | Index: pcre/sljit/sljitNativeARM_64.c | |
347 | =================================================================== | |
348 | --- pcre/sljit/sljitNativeARM_64.c (revision 1553) | |
349 | +++ pcre/sljit/sljitNativeARM_64.c (working copy) | |
350 | @@ -1087,14 +1087,20 @@ | |
351 | saved_regs_size += sizeof(sljit_sw); | |
352 | } | |
353 | local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; | |
354 | - FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); | |
355 | + if (saved_regs_size > 0) | |
356 | + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); | |
357 | } | |
358 | ||
359 | tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; | |
360 | prev = -1; | |
361 | for (i = SLJIT_S0; i >= tmp; i--) { | |
362 | if (prev == -1) { | |
363 | - prev = i; | |
364 | + if (!(offs & (1 << 15))) { | |
365 | + prev = i; | |
366 | + continue; | |
367 | + } | |
368 | + FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); | |
369 | + offs += 1 << 15; | |
370 | continue; | |
371 | } | |
372 | FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); | |
373 | @@ -1104,7 +1110,12 @@ | |
374 | ||
375 | for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { | |
376 | if (prev == -1) { | |
377 | - prev = i; | |
378 | + if (!(offs & (1 << 15))) { | |
379 | + prev = i; | |
380 | + continue; | |
381 | + } | |
382 | + FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); | |
383 | + offs += 1 << 15; | |
384 | continue; | |
385 | } | |
386 | FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); | |
387 | @@ -1112,8 +1123,7 @@ | |
388 | prev = -1; | |
389 | } | |
390 | ||
391 | - if (prev != -1) | |
392 | - FAIL_IF(push_inst(compiler, STRI | RT(prev) | RN(TMP_SP) | (offs >> 5))); | |
393 | + SLJIT_ASSERT(prev == -1); | |
394 | ||
395 | if (compiler->local_size > (63 * sizeof(sljit_sw))) { | |
396 | /* The local_size is already adjusted by the saved registers. */ | |
397 | @@ -1188,7 +1198,12 @@ | |
398 | prev = -1; | |
399 | for (i = SLJIT_S0; i >= tmp; i--) { | |
400 | if (prev == -1) { | |
401 | - prev = i; | |
402 | + if (!(offs & (1 << 15))) { | |
403 | + prev = i; | |
404 | + continue; | |
405 | + } | |
406 | + FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); | |
407 | + offs += 1 << 15; | |
408 | continue; | |
409 | } | |
410 | FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); | |
411 | @@ -1198,7 +1213,12 @@ | |
412 | ||
413 | for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { | |
414 | if (prev == -1) { | |
415 | - prev = i; | |
416 | + if (!(offs & (1 << 15))) { | |
417 | + prev = i; | |
418 | + continue; | |
419 | + } | |
420 | + FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); | |
421 | + offs += 1 << 15; | |
422 | continue; | |
423 | } | |
424 | FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); | |
425 | @@ -1206,13 +1226,12 @@ | |
426 | prev = -1; | |
427 | } | |
428 | ||
429 | - if (prev != -1) | |
430 | - FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(TMP_SP) | (offs >> 5))); | |
431 | + SLJIT_ASSERT(prev == -1); | |
432 | ||
433 | if (compiler->local_size <= (63 * sizeof(sljit_sw))) { | |
434 | FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) | |
435 | | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); | |
436 | - } else { | |
437 | + } else if (saved_regs_size > 0) { | |
438 | FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); | |
439 | } | |
440 | ||
441 | @@ -1242,12 +1261,15 @@ | |
442 | FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); | |
443 | FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); | |
444 | return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); | |
445 | - case SLJIT_LUDIV: | |
446 | - case SLJIT_LSDIV: | |
447 | + case SLJIT_UDIVMOD: | |
448 | + case SLJIT_SDIVMOD: | |
449 | FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); | |
450 | - FAIL_IF(push_inst(compiler, ((op == SLJIT_LUDIV ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); | |
451 | + FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); | |
452 | FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); | |
453 | return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); | |
454 | + case SLJIT_UDIVI: | |
455 | + case SLJIT_SDIVI: | |
456 | + return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); | |
457 | } | |
458 | ||
459 | return SLJIT_SUCCESS; | |
460 | Index: pcre/sljit/sljitNativePPC_common.c | |
461 | =================================================================== | |
462 | --- pcre/sljit/sljitNativePPC_common.c (revision 1553) | |
463 | +++ pcre/sljit/sljitNativePPC_common.c (working copy) | |
464 | @@ -1267,22 +1267,23 @@ | |
465 | FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); | |
466 | return push_inst(compiler, (op == SLJIT_LUMUL ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); | |
467 | #endif | |
468 | - case SLJIT_LUDIV: | |
469 | - case SLJIT_LSDIV: | |
470 | + case SLJIT_UDIVMOD: | |
471 | + case SLJIT_SDIVMOD: | |
472 | FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); | |
473 | #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) | |
474 | - if (int_op) { | |
475 | - FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVWU : DIVW) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); | |
476 | - FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); | |
477 | - } else { | |
478 | - FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVDU : DIVD) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); | |
479 | - FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); | |
480 | - } | |
481 | - return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1)); | |
482 | + FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_UDIVMOD ? DIVWU : DIVW) : (op == SLJIT_UDIVMOD ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); | |
483 | + FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); | |
484 | #else | |
485 | - FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVWU : DIVW) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); | |
486 | + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIVMOD ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); | |
487 | FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); | |
488 | +#endif | |
489 | return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1)); | |
490 | + case SLJIT_UDIVI: | |
491 | + case SLJIT_SDIVI: | |
492 | +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) | |
493 | + return push_inst(compiler, (int_op ? (op == SLJIT_UDIVI ? DIVWU : DIVW) : (op == SLJIT_UDIVI ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); | |
494 | +#else | |
495 | + return push_inst(compiler, (op == SLJIT_UDIVI ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); | |
496 | #endif | |
497 | } | |
498 | ||
499 | Index: pcre/sljit/sljitNativeX86_common.c | |
500 | =================================================================== | |
501 | --- pcre/sljit/sljitNativeX86_common.c (revision 1553) | |
502 | +++ pcre/sljit/sljitNativeX86_common.c (working copy) | |
503 | @@ -742,8 +742,10 @@ | |
504 | break; | |
505 | case SLJIT_LUMUL: | |
506 | case SLJIT_LSMUL: | |
507 | - case SLJIT_LUDIV: | |
508 | - case SLJIT_LSDIV: | |
509 | + case SLJIT_UDIVMOD: | |
510 | + case SLJIT_SDIVMOD: | |
511 | + case SLJIT_UDIVI: | |
512 | + case SLJIT_SDIVI: | |
513 | compiler->flags_saved = 0; | |
514 | #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) | |
515 | #ifdef _WIN64 | |
516 | @@ -761,9 +763,10 @@ | |
517 | #endif | |
518 | compiler->mode32 = op & SLJIT_INT_OP; | |
519 | #endif | |
520 | + SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); | |
521 | ||
522 | op = GET_OPCODE(op); | |
523 | - if (op == SLJIT_LUDIV) { | |
524 | + if ((op | 0x2) == SLJIT_UDIVI) { | |
525 | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) | |
526 | EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); | |
527 | inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0); | |
528 | @@ -774,7 +777,7 @@ | |
529 | *inst = XOR_r_rm; | |
530 | } | |
531 | ||
532 | - if (op == SLJIT_LSDIV) { | |
533 | + if ((op | 0x2) == SLJIT_SDIVI) { | |
534 | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) | |
535 | EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); | |
536 | #endif | |
537 | @@ -805,10 +808,10 @@ | |
538 | FAIL_IF(!inst); | |
539 | INC_SIZE(2); | |
540 | *inst++ = GROUP_F7; | |
541 | - *inst = MOD_REG | ((op >= SLJIT_LUDIV) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); | |
542 | + *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); | |
543 | #else | |
544 | #ifdef _WIN64 | |
545 | - size = (!compiler->mode32 || op >= SLJIT_LUDIV) ? 3 : 2; | |
546 | + size = (!compiler->mode32 || op >= SLJIT_UDIVMOD) ? 3 : 2; | |
547 | #else | |
548 | size = (!compiler->mode32) ? 3 : 2; | |
549 | #endif | |
550 | @@ -817,11 +820,11 @@ | |
551 | INC_SIZE(size); | |
552 | #ifdef _WIN64 | |
553 | if (!compiler->mode32) | |
554 | - *inst++ = REX_W | ((op >= SLJIT_LUDIV) ? REX_B : 0); | |
555 | - else if (op >= SLJIT_LUDIV) | |
556 | + *inst++ = REX_W | ((op >= SLJIT_UDIVMOD) ? REX_B : 0); | |
557 | + else if (op >= SLJIT_UDIVMOD) | |
558 | *inst++ = REX_B; | |
559 | *inst++ = GROUP_F7; | |
560 | - *inst = MOD_REG | ((op >= SLJIT_LUDIV) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); | |
561 | + *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); | |
562 | #else | |
563 | if (!compiler->mode32) | |
564 | *inst++ = REX_W; | |
565 | @@ -836,15 +839,21 @@ | |
566 | case SLJIT_LSMUL: | |
567 | *inst |= IMUL; | |
568 | break; | |
569 | - case SLJIT_LUDIV: | |
570 | + case SLJIT_UDIVMOD: | |
571 | + case SLJIT_UDIVI: | |
572 | *inst |= DIV; | |
573 | break; | |
574 | - case SLJIT_LSDIV: | |
575 | + case SLJIT_SDIVMOD: | |
576 | + case SLJIT_SDIVI: | |
577 | *inst |= IDIV; | |
578 | break; | |
579 | } | |
580 | #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) | |
581 | - EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); | |
582 | + if (op <= SLJIT_SDIVMOD) | |
583 | + EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); | |
584 | +#else | |
585 | + if (op >= SLJIT_UDIVI) | |
586 | + EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); | |
587 | #endif | |
588 | break; | |
589 | } | |
590 | @@ -1905,60 +1914,62 @@ | |
591 | return SLJIT_SUCCESS; | |
592 | } | |
593 | ||
594 | - if (FAST_IS_REG(src1)) { | |
595 | + if (!(src1 & SLJIT_IMM)) { | |
596 | if (src2 & SLJIT_IMM) { | |
597 | #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) | |
598 | if (IS_HALFWORD(src2w) || compiler->mode32) { | |
599 | - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); | |
600 | + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w); | |
601 | FAIL_IF(!inst); | |
602 | *inst = GROUP_F7; | |
603 | } | |
604 | else { | |
605 | FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); | |
606 | - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0); | |
607 | + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, src1w); | |
608 | FAIL_IF(!inst); | |
609 | *inst = TEST_rm_r; | |
610 | } | |
611 | #else | |
612 | - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); | |
613 | + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w); | |
614 | FAIL_IF(!inst); | |
615 | *inst = GROUP_F7; | |
616 | #endif | |
617 | + return SLJIT_SUCCESS; | |
618 | } | |
619 | - else { | |
620 | + else if (FAST_IS_REG(src1)) { | |
621 | inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); | |
622 | FAIL_IF(!inst); | |
623 | *inst = TEST_rm_r; | |
624 | + return SLJIT_SUCCESS; | |
625 | } | |
626 | - return SLJIT_SUCCESS; | |
627 | } | |
628 | ||
629 | - if (FAST_IS_REG(src2)) { | |
630 | + if (!(src2 & SLJIT_IMM)) { | |
631 | if (src1 & SLJIT_IMM) { | |
632 | #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) | |
633 | if (IS_HALFWORD(src1w) || compiler->mode32) { | |
634 | - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0); | |
635 | + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w); | |
636 | FAIL_IF(!inst); | |
637 | *inst = GROUP_F7; | |
638 | } | |
639 | else { | |
640 | FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w)); | |
641 | - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0); | |
642 | + inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, src2w); | |
643 | FAIL_IF(!inst); | |
644 | *inst = TEST_rm_r; | |
645 | } | |
646 | #else | |
647 | - inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0); | |
648 | + inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, src2w); | |
649 | FAIL_IF(!inst); | |
650 | *inst = GROUP_F7; | |
651 | #endif | |
652 | + return SLJIT_SUCCESS; | |
653 | } | |
654 | - else { | |
655 | + else if (FAST_IS_REG(src2)) { | |
656 | inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); | |
657 | FAIL_IF(!inst); | |
658 | *inst = TEST_rm_r; | |
659 | + return SLJIT_SUCCESS; | |
660 | } | |
661 | - return SLJIT_SUCCESS; | |
662 | } | |
663 | ||
664 | EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); | |
665 | Index: pcre/sljit/sljitConfigInternal.h | |
666 | =================================================================== | |
667 | --- pcre/sljit/sljitConfigInternal.h (revision 1553) | |
668 | +++ pcre/sljit/sljitConfigInternal.h (working copy) | |
669 | @@ -468,7 +468,12 @@ | |
670 | ||
671 | #ifndef SLJIT_CALL | |
672 | ||
673 | -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) | |
674 | +#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION) | |
675 | + | |
676 | +/* Force cdecl. */ | |
677 | +#define SLJIT_CALL | |
678 | + | |
679 | +#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) | |
680 | ||
681 | #if defined(__GNUC__) && !defined(__APPLE__) | |
682 | ||
683 | Index: pcre/ChangeLog | |
684 | =================================================================== | |
685 | --- pcre/ChangeLog (revision 1553) | |
686 | +++ pcre/ChangeLog (working copy) | |
687 | @@ -1,6 +1,46 @@ | |
688 | ChangeLog for PCRE | |
689 | ------------------ | |
690 | ||
691 | +Note that the PCRE 8.xx series (PCRE1) is now in a bugfix-only state. All | |
692 | +development is happening in the PCRE2 10.xx series. | |
693 | + | |
694 | +Version 8.38 xx-xxx-xxxx | |
695 | +------------------------ | |
696 | + | |
697 | +1. If a group that contained a recursive back reference also contained a | |
698 | + forward reference subroutine call followed by a non-forward-reference | |
699 | + subroutine call, for example /.((?2)(?R)\1)()/, pcre2_compile() failed to | |
700 | + compile correct code, leading to undefined behaviour or an internally | |
701 | + detected error. This bug was discovered by the LLVM fuzzer. | |
702 | + | |
703 | +2. Quantification of certain items (e.g. atomic back references) could cause | |
704 | + incorrect code to be compiled when recursive forward references were | |
705 | + involved. For example, in this pattern: /(?1)()((((((\1++))\x85)+)|))/. | |
706 | + This bug was discovered by the LLVM fuzzer. | |
707 | + | |
708 | +3. A repeated conditional group whose condition was a reference by name caused | |
709 | + a buffer overflow if there was more than one group with the given name. | |
710 | + This bug was discovered by the LLVM fuzzer. | |
711 | + | |
712 | +4. A recursive back reference by name within a group that had the same name as | |
713 | + another group caused a buffer overflow. For example: | |
714 | + /(?J)(?'d'(?'d'\g{d}))/. This bug was discovered by the LLVM fuzzer. | |
715 | + | |
716 | +5. A forward reference by name to a group whose number is the same as the | |
717 | + current group, for example in this pattern: /(?|(\k'Pm')|(?'Pm'))/, caused | |
718 | + a buffer overflow at compile time. This bug was discovered by the LLVM | |
719 | + fuzzer. | |
720 | + | |
721 | +6. A lookbehind assertion within a set of mutually recursive subpatterns could | |
722 | + provoke a buffer overflow. This bug was discovered by the LLVM fuzzer. | |
723 | + | |
724 | +7. Another buffer overflow bug involved duplicate named groups with a | |
725 | + reference between their definition, with a group that reset capture | |
726 | + numbers, for example: /(?J:(?|(?'R')(\k'R')|((?'R'))))/. This has been | |
727 | + fixed by always allowing for more memory, even if not needed. (A proper fix | |
728 | + is implemented in PCRE2, but it involves more refactoring.) | |
729 | + | |
730 | + | |
731 | Version 8.37 28-April-2015 | |
732 | -------------------------- | |
733 | ||
734 | Index: pcre/testdata/testoutput1 | |
735 | =================================================================== | |
736 | --- pcre/testdata/testoutput1 (revision 1553) | |
737 | +++ pcre/testdata/testoutput1 (working copy) | |
738 | @@ -9429,4 +9429,9 @@ | |
739 | 0: aaaaaaaaa | |
740 | 1: a | |
741 | ||
742 | +"(?|(\k'Pm')|(?'Pm'))" | |
743 | + abcd | |
744 | + 0: | |
745 | + 1: | |
746 | + | |
747 | /-- End of testinput1 --/ | |
748 | Index: pcre/testdata/testoutput2 | |
749 | =================================================================== | |
750 | --- pcre/testdata/testoutput2 (revision 1553) | |
751 | +++ pcre/testdata/testoutput2 (working copy) | |
752 | @@ -14423,4 +14423,42 @@ | |
753 | ||
754 | /((?2){73}(?2))((?1))/ | |
755 | ||
756 | +/.((?2)(?R)\1)()/BZ | |
757 | +------------------------------------------------------------------ | |
758 | + Bra | |
759 | + Any | |
760 | + Once | |
761 | + CBra 1 | |
762 | + Recurse | |
763 | + Recurse | |
764 | + \1 | |
765 | + Ket | |
766 | + Ket | |
767 | + CBra 2 | |
768 | + Ket | |
769 | + Ket | |
770 | + End | |
771 | +------------------------------------------------------------------ | |
772 | + | |
773 | +/(?1)()((((((\1++))\x85)+)|))/ | |
774 | + | |
775 | +/(\9*+(?2);\3++()2|)++{/ | |
776 | +Failed: reference to non-existent subpattern at offset 22 | |
777 | + | |
778 | +/\V\x85\9*+((?2)\3++()2)*:2/ | |
779 | +Failed: reference to non-existent subpattern at offset 26 | |
780 | + | |
781 | +/(((?(R)){0,2}) (?''((?'R')((?'R')))))/J | |
782 | + | |
783 | +/(((?(X)){0,2}) (?''((?'X')((?'X')))))/J | |
784 | + | |
785 | +/(((?(R)){0,2}) (?''((?'X')((?'R')))))/ | |
786 | + | |
787 | +"(?J)(?'d'(?'d'\g{d}))" | |
788 | + | |
789 | +".*?\h.+.\.+\R*?\xd(?i)(?=!(?=b`b`b`\`b\xa9b!)`\a`bbbbbbbbbbbbb`bbbbbbbbbbbb*R\x85bbbbbbb\C?{((?2)(?))(( | |
790 | +\H){8(?<=(?1){29}\xa8bbbb\x16\xd\xc6^($(?<! )(\xa9H4){4}h}1)B))\x15')" | |
791 | + | |
792 | +"(?J:(?|(?'R')(\k'R')|((?'R'))))" | |
793 | + | |
794 | /-- End of testinput2 --/ | |
795 | Index: pcre/testdata/testoutput11-16 | |
796 | =================================================================== | |
797 | --- pcre/testdata/testoutput11-16 (revision 1553) | |
798 | +++ pcre/testdata/testoutput11-16 (working copy) | |
799 | @@ -231,7 +231,7 @@ | |
800 | ------------------------------------------------------------------ | |
801 | ||
802 | /(?P<a>a)...(?P=a)bbb(?P>a)d/BM | |
803 | -Memory allocation (code space): 61 | |
804 | +Memory allocation (code space): 77 | |
805 | ------------------------------------------------------------------ | |
806 | 0 24 Bra | |
807 | 2 5 CBra 1 | |
808 | @@ -748,4 +748,21 @@ | |
809 | 22 End | |
810 | ------------------------------------------------------------------ | |
811 | ||
812 | +/.((?2)(?R)\1)()/B | |
813 | +------------------------------------------------------------------ | |
814 | + 0 23 Bra | |
815 | + 2 Any | |
816 | + 3 13 Once | |
817 | + 5 9 CBra 1 | |
818 | + 8 18 Recurse | |
819 | + 10 0 Recurse | |
820 | + 12 \1 | |
821 | + 14 9 Ket | |
822 | + 16 13 Ket | |
823 | + 18 3 CBra 2 | |
824 | + 21 3 Ket | |
825 | + 23 23 Ket | |
826 | + 25 End | |
827 | +------------------------------------------------------------------ | |
828 | + | |
829 | /-- End of testinput11 --/ | |
830 | Index: pcre/testdata/testinput11 | |
831 | =================================================================== | |
832 | --- pcre/testdata/testinput11 (revision 1553) | |
833 | +++ pcre/testdata/testinput11 (working copy) | |
834 | @@ -136,4 +136,6 @@ | |
835 | ||
836 | /((?+1)(\1))/B | |
837 | ||
838 | +/.((?2)(?R)\1)()/B | |
839 | + | |
840 | /-- End of testinput11 --/ | |
841 | Index: pcre/testdata/testoutput11-8 | |
842 | =================================================================== | |
843 | --- pcre/testdata/testoutput11-8 (revision 1553) | |
844 | +++ pcre/testdata/testoutput11-8 (working copy) | |
845 | @@ -231,7 +231,7 @@ | |
846 | ------------------------------------------------------------------ | |
847 | ||
848 | /(?P<a>a)...(?P=a)bbb(?P>a)d/BM | |
849 | -Memory allocation (code space): 38 | |
850 | +Memory allocation (code space): 50 | |
851 | ------------------------------------------------------------------ | |
852 | 0 30 Bra | |
853 | 3 7 CBra 1 | |
854 | @@ -748,4 +748,21 @@ | |
855 | 34 End | |
856 | ------------------------------------------------------------------ | |
857 | ||
858 | +/.((?2)(?R)\1)()/B | |
859 | +------------------------------------------------------------------ | |
860 | + 0 35 Bra | |
861 | + 3 Any | |
862 | + 4 20 Once | |
863 | + 7 14 CBra 1 | |
864 | + 12 27 Recurse | |
865 | + 15 0 Recurse | |
866 | + 18 \1 | |
867 | + 21 14 Ket | |
868 | + 24 20 Ket | |
869 | + 27 5 CBra 2 | |
870 | + 32 5 Ket | |
871 | + 35 35 Ket | |
872 | + 38 End | |
873 | +------------------------------------------------------------------ | |
874 | + | |
875 | /-- End of testinput11 --/ | |
876 | Index: pcre/testdata/testinput1 | |
877 | =================================================================== | |
878 | --- pcre/testdata/testinput1 (revision 1553) | |
879 | +++ pcre/testdata/testinput1 (working copy) | |
880 | @@ -5730,4 +5730,7 @@ | |
881 | "(?1)(?#?'){8}(a)" | |
882 | baaaaaaaaac | |
883 | ||
884 | +"(?|(\k'Pm')|(?'Pm'))" | |
885 | + abcd | |
886 | + | |
887 | /-- End of testinput1 --/ | |
888 | Index: pcre/testdata/testinput2 | |
889 | =================================================================== | |
890 | --- pcre/testdata/testinput2 (revision 1553) | |
891 | +++ pcre/testdata/testinput2 (working copy) | |
892 | @@ -4152,4 +4152,25 @@ | |
893 | ||
894 | /((?2){73}(?2))((?1))/ | |
895 | ||
896 | +/.((?2)(?R)\1)()/BZ | |
897 | + | |
898 | +/(?1)()((((((\1++))\x85)+)|))/ | |
899 | + | |
900 | +/(\9*+(?2);\3++()2|)++{/ | |
901 | + | |
902 | +/\V\x85\9*+((?2)\3++()2)*:2/ | |
903 | + | |
904 | +/(((?(R)){0,2}) (?''((?'R')((?'R')))))/J | |
905 | + | |
906 | +/(((?(X)){0,2}) (?''((?'X')((?'X')))))/J | |
907 | + | |
908 | +/(((?(R)){0,2}) (?''((?'X')((?'R')))))/ | |
909 | + | |
910 | +"(?J)(?'d'(?'d'\g{d}))" | |
911 | + | |
912 | +".*?\h.+.\.+\R*?\xd(?i)(?=!(?=b`b`b`\`b\xa9b!)`\a`bbbbbbbbbbbbb`bbbbbbbbbbbb*R\x85bbbbbbb\C?{((?2)(?))(( | |
913 | +\H){8(?<=(?1){29}\xa8bbbb\x16\xd\xc6^($(?<! )(\xa9H4){4}h}1)B))\x15')" | |
914 | + | |
915 | +"(?J:(?|(?'R')(\k'R')|((?'R'))))" | |
916 | + | |
917 | /-- End of testinput2 --/ | |
918 | Index: pcre/testdata/testoutput11-32 | |
919 | =================================================================== | |
920 | --- pcre/testdata/testoutput11-32 (revision 1553) | |
921 | +++ pcre/testdata/testoutput11-32 (working copy) | |
922 | @@ -231,7 +231,7 @@ | |
923 | ------------------------------------------------------------------ | |
924 | ||
925 | /(?P<a>a)...(?P=a)bbb(?P>a)d/BM | |
926 | -Memory allocation (code space): 125 | |
927 | +Memory allocation (code space): 157 | |
928 | ------------------------------------------------------------------ | |
929 | 0 24 Bra | |
930 | 2 5 CBra 1 | |
931 | @@ -748,4 +748,21 @@ | |
932 | 22 End | |
933 | ------------------------------------------------------------------ | |
934 | ||
935 | +/.((?2)(?R)\1)()/B | |
936 | +------------------------------------------------------------------ | |
937 | + 0 23 Bra | |
938 | + 2 Any | |
939 | + 3 13 Once | |
940 | + 5 9 CBra 1 | |
941 | + 8 18 Recurse | |
942 | + 10 0 Recurse | |
943 | + 12 \1 | |
944 | + 14 9 Ket | |
945 | + 16 13 Ket | |
946 | + 18 3 CBra 2 | |
947 | + 21 3 Ket | |
948 | + 23 23 Ket | |
949 | + 25 End | |
950 | +------------------------------------------------------------------ | |
951 | + | |
952 | /-- End of testinput11 --/ | |
953 | Index: pcre/pcre_compile.c | |
954 | =================================================================== | |
955 | --- pcre/pcre_compile.c (revision 1553) | |
956 | +++ pcre/pcre_compile.c (working copy) | |
957 | @@ -1799,7 +1799,7 @@ | |
958 | case OP_ASSERTBACK: | |
959 | case OP_ASSERTBACK_NOT: | |
960 | do cc += GET(cc, 1); while (*cc == OP_ALT); | |
961 | - cc += PRIV(OP_lengths)[*cc]; | |
962 | + cc += 1 + LINK_SIZE; | |
963 | break; | |
964 | ||
965 | /* Skip over things that don't match chars */ | |
966 | @@ -3985,11 +3985,12 @@ | |
967 | is called, the partially compiled regex must be temporarily terminated with | |
968 | OP_END. | |
969 | ||
970 | -This function has been extended with the possibility of forward references for | |
971 | -recursions and subroutine calls. It must also check the list of such references | |
972 | -for the group we are dealing with. If it finds that one of the recursions in | |
973 | -the current group is on this list, it adjusts the offset in the list, not the | |
974 | -value in the reference (which is a group number). | |
975 | +This function has been extended to cope with forward references for recursions | |
976 | +and subroutine calls. It must check the list of such references for the | |
977 | +group we are dealing with. If it finds that one of the recursions in the | |
978 | +current group is on this list, it does not adjust the value in the reference | |
979 | +(which is a group number). After the group has been scanned, all the offsets in | |
980 | +the forward reference list for the group are adjusted. | |
981 | ||
982 | Arguments: | |
983 | group points to the start of the group | |
984 | @@ -4005,29 +4006,21 @@ | |
985 | adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd, | |
986 | size_t save_hwm_offset) | |
987 | { | |
988 | +int offset; | |
989 | +pcre_uchar *hc; | |
990 | pcre_uchar *ptr = group; | |
991 | ||
992 | while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL) | |
993 | { | |
994 | - int offset; | |
995 | - pcre_uchar *hc; | |
996 | - | |
997 | - /* See if this recursion is on the forward reference list. If so, adjust the | |
998 | - reference. */ | |
999 | - | |
1000 | for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm; | |
1001 | hc += LINK_SIZE) | |
1002 | { | |
1003 | offset = (int)GET(hc, 0); | |
1004 | - if (cd->start_code + offset == ptr + 1) | |
1005 | - { | |
1006 | - PUT(hc, 0, offset + adjust); | |
1007 | - break; | |
1008 | - } | |
1009 | + if (cd->start_code + offset == ptr + 1) break; | |
1010 | } | |
1011 | ||
1012 | - /* Otherwise, adjust the recursion offset if it's after the start of this | |
1013 | - group. */ | |
1014 | + /* If we have not found this recursion on the forward reference list, adjust | |
1015 | + the recursion's offset if it's after the start of this group. */ | |
1016 | ||
1017 | if (hc >= cd->hwm) | |
1018 | { | |
1019 | @@ -4037,6 +4030,15 @@ | |
1020 | ||
1021 | ptr += 1 + LINK_SIZE; | |
1022 | } | |
1023 | + | |
1024 | +/* Now adjust all forward reference offsets for the group. */ | |
1025 | + | |
1026 | +for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm; | |
1027 | + hc += LINK_SIZE) | |
1028 | + { | |
1029 | + offset = (int)GET(hc, 0); | |
1030 | + PUT(hc, 0, offset + adjust); | |
1031 | + } | |
1032 | } | |
1033 | ||
1034 | ||
1035 | @@ -4465,7 +4467,7 @@ | |
1036 | const pcre_uchar *nestptr = NULL; | |
1037 | pcre_uchar *previous = NULL; | |
1038 | pcre_uchar *previous_callout = NULL; | |
1039 | -size_t save_hwm_offset = 0; | |
1040 | +size_t item_hwm_offset = 0; | |
1041 | pcre_uint8 classbits[32]; | |
1042 | ||
1043 | /* We can fish out the UTF-8 setting once and for all into a BOOL, but we | |
1044 | @@ -4767,6 +4769,7 @@ | |
1045 | zeroreqchar = reqchar; | |
1046 | zeroreqcharflags = reqcharflags; | |
1047 | previous = code; | |
1048 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1049 | *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY; | |
1050 | break; | |
1051 | ||
1052 | @@ -4818,6 +4821,7 @@ | |
1053 | /* Handle a real character class. */ | |
1054 | ||
1055 | previous = code; | |
1056 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1057 | ||
1058 | /* PCRE supports POSIX class stuff inside a class. Perl gives an error if | |
1059 | they are encountered at the top level, so we'll do that too. */ | |
1060 | @@ -5930,7 +5934,7 @@ | |
1061 | { | |
1062 | register int i; | |
1063 | int len = (int)(code - previous); | |
1064 | - size_t base_hwm_offset = save_hwm_offset; | |
1065 | + size_t base_hwm_offset = item_hwm_offset; | |
1066 | pcre_uchar *bralink = NULL; | |
1067 | pcre_uchar *brazeroptr = NULL; | |
1068 | ||
1069 | @@ -5985,7 +5989,7 @@ | |
1070 | if (repeat_max <= 1) /* Covers 0, 1, and unlimited */ | |
1071 | { | |
1072 | *code = OP_END; | |
1073 | - adjust_recurse(previous, 1, utf, cd, save_hwm_offset); | |
1074 | + adjust_recurse(previous, 1, utf, cd, item_hwm_offset); | |
1075 | memmove(previous + 1, previous, IN_UCHARS(len)); | |
1076 | code++; | |
1077 | if (repeat_max == 0) | |
1078 | @@ -6009,7 +6013,7 @@ | |
1079 | { | |
1080 | int offset; | |
1081 | *code = OP_END; | |
1082 | - adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm_offset); | |
1083 | + adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, item_hwm_offset); | |
1084 | memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len)); | |
1085 | code += 2 + LINK_SIZE; | |
1086 | *previous++ = OP_BRAZERO + repeat_type; | |
1087 | @@ -6267,7 +6271,7 @@ | |
1088 | { | |
1089 | int nlen = (int)(code - bracode); | |
1090 | *code = OP_END; | |
1091 | - adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm_offset); | |
1092 | + adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, item_hwm_offset); | |
1093 | memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen)); | |
1094 | code += 1 + LINK_SIZE; | |
1095 | nlen += 1 + LINK_SIZE; | |
1096 | @@ -6401,7 +6405,7 @@ | |
1097 | else | |
1098 | { | |
1099 | *code = OP_END; | |
1100 | - adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset); | |
1101 | + adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset); | |
1102 | memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len)); | |
1103 | code += 1 + LINK_SIZE; | |
1104 | len += 1 + LINK_SIZE; | |
1105 | @@ -6450,7 +6454,7 @@ | |
1106 | ||
1107 | default: | |
1108 | *code = OP_END; | |
1109 | - adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset); | |
1110 | + adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset); | |
1111 | memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len)); | |
1112 | code += 1 + LINK_SIZE; | |
1113 | len += 1 + LINK_SIZE; | |
1114 | @@ -6623,7 +6627,7 @@ | |
1115 | newoptions = options; | |
1116 | skipbytes = 0; | |
1117 | bravalue = OP_CBRA; | |
1118 | - save_hwm_offset = cd->hwm - cd->start_workspace; | |
1119 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1120 | reset_bracount = FALSE; | |
1121 | ||
1122 | /* Deal with the extended parentheses; all are introduced by '?', and the | |
1123 | @@ -6769,7 +6773,7 @@ | |
1124 | ptr++; | |
1125 | } | |
1126 | namelen = (int)(ptr - name); | |
1127 | - if (lengthptr != NULL) *lengthptr += IMM2_SIZE; | |
1128 | + if (lengthptr != NULL) skipbytes += IMM2_SIZE; | |
1129 | } | |
1130 | ||
1131 | /* Check the terminator */ | |
1132 | @@ -7173,14 +7177,26 @@ | |
1133 | number. If the name is not found, set the value to 0 for a forward | |
1134 | reference. */ | |
1135 | ||
1136 | + recno = 0; | |
1137 | ng = cd->named_groups; | |
1138 | for (i = 0; i < cd->names_found; i++, ng++) | |
1139 | { | |
1140 | if (namelen == ng->length && | |
1141 | STRNCMP_UC_UC(name, ng->name, namelen) == 0) | |
1142 | - break; | |
1143 | + { | |
1144 | + open_capitem *oc; | |
1145 | + recno = ng->number; | |
1146 | + if (is_recurse) break; | |
1147 | + for (oc = cd->open_caps; oc != NULL; oc = oc->next) | |
1148 | + { | |
1149 | + if (oc->number == recno) | |
1150 | + { | |
1151 | + oc->flag = TRUE; | |
1152 | + break; | |
1153 | + } | |
1154 | + } | |
1155 | + } | |
1156 | } | |
1157 | - recno = (i < cd->names_found)? ng->number : 0; | |
1158 | ||
1159 | /* Count named back references. */ | |
1160 | ||
1161 | @@ -7191,6 +7207,19 @@ | |
1162 | 16-bit data item. */ | |
1163 | ||
1164 | *lengthptr += IMM2_SIZE; | |
1165 | + | |
1166 | + /* If this is a forward reference and we are within a (?|...) group, | |
1167 | + the reference may end up as the number of a group which we are | |
1168 | + currently inside, that is, it could be a recursive reference. In the | |
1169 | + real compile this will be picked up and the reference wrapped with | |
1170 | + OP_ONCE to make it atomic, so we must space in case this occurs. */ | |
1171 | + | |
1172 | + /* In fact, this can happen for a non-forward reference because | |
1173 | + another group with the same number might be created later. This | |
1174 | + issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance | |
1175 | + only mode, we finesse the bug by allowing more memory always. */ | |
1176 | + | |
1177 | + /* if (recno == 0) */ *lengthptr += 2 + 2*LINK_SIZE; | |
1178 | } | |
1179 | ||
1180 | /* In the real compile, search the name table. We check the name | |
1181 | @@ -7247,6 +7276,7 @@ | |
1182 | { | |
1183 | if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; | |
1184 | previous = code; | |
1185 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1186 | *code++ = ((options & PCRE_CASELESS) != 0)? OP_DNREFI : OP_DNREF; | |
1187 | PUT2INC(code, 0, index); | |
1188 | PUT2INC(code, 0, count); | |
1189 | @@ -7360,6 +7390,7 @@ | |
1190 | HANDLE_RECURSION: | |
1191 | ||
1192 | previous = code; | |
1193 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1194 | called = cd->start_code; | |
1195 | ||
1196 | /* When we are actually compiling, find the bracket that is being | |
1197 | @@ -7561,7 +7592,11 @@ | |
1198 | previous = NULL; | |
1199 | cd->iscondassert = FALSE; | |
1200 | } | |
1201 | - else previous = code; | |
1202 | + else | |
1203 | + { | |
1204 | + previous = code; | |
1205 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1206 | + } | |
1207 | ||
1208 | *code = bravalue; | |
1209 | tempcode = code; | |
1210 | @@ -7809,7 +7844,7 @@ | |
1211 | const pcre_uchar *p; | |
1212 | pcre_uint32 cf; | |
1213 | ||
1214 | - save_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */ | |
1215 | + item_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */ | |
1216 | terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? | |
1217 | CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; | |
1218 | ||
1219 | @@ -7877,6 +7912,7 @@ | |
1220 | HANDLE_REFERENCE: | |
1221 | if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; | |
1222 | previous = code; | |
1223 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1224 | *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF; | |
1225 | PUT2INC(code, 0, recno); | |
1226 | cd->backref_map |= (recno < 32)? (1 << recno) : 1; | |
1227 | @@ -7906,6 +7942,7 @@ | |
1228 | if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr)) | |
1229 | goto FAILED; | |
1230 | previous = code; | |
1231 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1232 | *code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP; | |
1233 | *code++ = ptype; | |
1234 | *code++ = pdata; | |
1235 | @@ -7946,6 +7983,7 @@ | |
1236 | ||
1237 | { | |
1238 | previous = (escape > ESC_b && escape < ESC_Z)? code : NULL; | |
1239 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1240 | *code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape; | |
1241 | } | |
1242 | } | |
1243 | @@ -7989,6 +8027,7 @@ | |
1244 | ||
1245 | ONE_CHAR: | |
1246 | previous = code; | |
1247 | + item_hwm_offset = cd->hwm - cd->start_workspace; | |
1248 | ||
1249 | /* For caseless UTF-8 mode when UCP support is available, check whether | |
1250 | this character has more than one other case. If so, generate a special |