1*22dc650dSSadaf Ebrahimi /*************************************************
2*22dc650dSSadaf Ebrahimi * Perl-Compatible Regular Expressions *
3*22dc650dSSadaf Ebrahimi *************************************************/
4*22dc650dSSadaf Ebrahimi
5*22dc650dSSadaf Ebrahimi /* PCRE is a library of functions to support regular expressions whose syntax
6*22dc650dSSadaf Ebrahimi and semantics are as close as possible to those of the Perl 5 language.
7*22dc650dSSadaf Ebrahimi
8*22dc650dSSadaf Ebrahimi Written by Philip Hazel
9*22dc650dSSadaf Ebrahimi Original API code Copyright (c) 1997-2012 University of Cambridge
10*22dc650dSSadaf Ebrahimi New API code Copyright (c) 2016-2023 University of Cambridge
11*22dc650dSSadaf Ebrahimi
12*22dc650dSSadaf Ebrahimi -----------------------------------------------------------------------------
13*22dc650dSSadaf Ebrahimi Redistribution and use in source and binary forms, with or without
14*22dc650dSSadaf Ebrahimi modification, are permitted provided that the following conditions are met:
15*22dc650dSSadaf Ebrahimi
16*22dc650dSSadaf Ebrahimi * Redistributions of source code must retain the above copyright notice,
17*22dc650dSSadaf Ebrahimi this list of conditions and the following disclaimer.
18*22dc650dSSadaf Ebrahimi
19*22dc650dSSadaf Ebrahimi * Redistributions in binary form must reproduce the above copyright
20*22dc650dSSadaf Ebrahimi notice, this list of conditions and the following disclaimer in the
21*22dc650dSSadaf Ebrahimi documentation and/or other materials provided with the distribution.
22*22dc650dSSadaf Ebrahimi
23*22dc650dSSadaf Ebrahimi * Neither the name of the University of Cambridge nor the names of its
24*22dc650dSSadaf Ebrahimi contributors may be used to endorse or promote products derived from
25*22dc650dSSadaf Ebrahimi this software without specific prior written permission.
26*22dc650dSSadaf Ebrahimi
27*22dc650dSSadaf Ebrahimi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28*22dc650dSSadaf Ebrahimi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*22dc650dSSadaf Ebrahimi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*22dc650dSSadaf Ebrahimi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31*22dc650dSSadaf Ebrahimi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*22dc650dSSadaf Ebrahimi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*22dc650dSSadaf Ebrahimi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*22dc650dSSadaf Ebrahimi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*22dc650dSSadaf Ebrahimi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*22dc650dSSadaf Ebrahimi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*22dc650dSSadaf Ebrahimi POSSIBILITY OF SUCH DAMAGE.
38*22dc650dSSadaf Ebrahimi -----------------------------------------------------------------------------
39*22dc650dSSadaf Ebrahimi */
40*22dc650dSSadaf Ebrahimi
41*22dc650dSSadaf Ebrahimi #ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE
42*22dc650dSSadaf Ebrahimi #error This file must be included from pcre2_jit_compile.c.
43*22dc650dSSadaf Ebrahimi #endif
44*22dc650dSSadaf Ebrahimi
45*22dc650dSSadaf Ebrahimi #if defined(__has_feature)
46*22dc650dSSadaf Ebrahimi #if __has_feature(memory_sanitizer)
47*22dc650dSSadaf Ebrahimi #include <sanitizer/msan_interface.h>
48*22dc650dSSadaf Ebrahimi #endif /* __has_feature(memory_sanitizer) */
49*22dc650dSSadaf Ebrahimi #endif /* defined(__has_feature) */
50*22dc650dSSadaf Ebrahimi
51*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_JIT
52*22dc650dSSadaf Ebrahimi
jit_machine_stack_exec(jit_arguments * arguments,jit_function executable_func)53*22dc650dSSadaf Ebrahimi static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func)
54*22dc650dSSadaf Ebrahimi {
55*22dc650dSSadaf Ebrahimi sljit_u8 local_space[MACHINE_STACK_SIZE];
56*22dc650dSSadaf Ebrahimi struct sljit_stack local_stack;
57*22dc650dSSadaf Ebrahimi
58*22dc650dSSadaf Ebrahimi local_stack.min_start = local_space;
59*22dc650dSSadaf Ebrahimi local_stack.start = local_space;
60*22dc650dSSadaf Ebrahimi local_stack.end = local_space + MACHINE_STACK_SIZE;
61*22dc650dSSadaf Ebrahimi local_stack.top = local_space + MACHINE_STACK_SIZE;
62*22dc650dSSadaf Ebrahimi arguments->stack = &local_stack;
63*22dc650dSSadaf Ebrahimi return executable_func(arguments);
64*22dc650dSSadaf Ebrahimi }
65*22dc650dSSadaf Ebrahimi
66*22dc650dSSadaf Ebrahimi #endif
67*22dc650dSSadaf Ebrahimi
68*22dc650dSSadaf Ebrahimi
69*22dc650dSSadaf Ebrahimi /*************************************************
70*22dc650dSSadaf Ebrahimi * Do a JIT pattern match *
71*22dc650dSSadaf Ebrahimi *************************************************/
72*22dc650dSSadaf Ebrahimi
73*22dc650dSSadaf Ebrahimi /* This function runs a JIT pattern match.
74*22dc650dSSadaf Ebrahimi
75*22dc650dSSadaf Ebrahimi Arguments:
76*22dc650dSSadaf Ebrahimi code points to the compiled expression
77*22dc650dSSadaf Ebrahimi subject points to the subject string
78*22dc650dSSadaf Ebrahimi length length of subject string (may contain binary zeros)
79*22dc650dSSadaf Ebrahimi start_offset where to start in the subject string
80*22dc650dSSadaf Ebrahimi options option bits
81*22dc650dSSadaf Ebrahimi match_data points to a match_data block
82*22dc650dSSadaf Ebrahimi mcontext points to a match context
83*22dc650dSSadaf Ebrahimi
84*22dc650dSSadaf Ebrahimi Returns: > 0 => success; value is the number of ovector pairs filled
85*22dc650dSSadaf Ebrahimi = 0 => success, but ovector is not big enough
86*22dc650dSSadaf Ebrahimi -1 => failed to match (PCRE_ERROR_NOMATCH)
87*22dc650dSSadaf Ebrahimi < -1 => some kind of unexpected problem
88*22dc650dSSadaf Ebrahimi */
89*22dc650dSSadaf Ebrahimi
90*22dc650dSSadaf Ebrahimi PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_jit_match(const pcre2_code * code,PCRE2_SPTR subject,PCRE2_SIZE length,PCRE2_SIZE start_offset,uint32_t options,pcre2_match_data * match_data,pcre2_match_context * mcontext)91*22dc650dSSadaf Ebrahimi pcre2_jit_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
92*22dc650dSSadaf Ebrahimi PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
93*22dc650dSSadaf Ebrahimi pcre2_match_context *mcontext)
94*22dc650dSSadaf Ebrahimi {
95*22dc650dSSadaf Ebrahimi #ifndef SUPPORT_JIT
96*22dc650dSSadaf Ebrahimi
97*22dc650dSSadaf Ebrahimi (void)code;
98*22dc650dSSadaf Ebrahimi (void)subject;
99*22dc650dSSadaf Ebrahimi (void)length;
100*22dc650dSSadaf Ebrahimi (void)start_offset;
101*22dc650dSSadaf Ebrahimi (void)options;
102*22dc650dSSadaf Ebrahimi (void)match_data;
103*22dc650dSSadaf Ebrahimi (void)mcontext;
104*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_JIT_BADOPTION;
105*22dc650dSSadaf Ebrahimi
106*22dc650dSSadaf Ebrahimi #else /* SUPPORT_JIT */
107*22dc650dSSadaf Ebrahimi
108*22dc650dSSadaf Ebrahimi pcre2_real_code *re = (pcre2_real_code *)code;
109*22dc650dSSadaf Ebrahimi executable_functions *functions = (executable_functions *)re->executable_jit;
110*22dc650dSSadaf Ebrahimi pcre2_jit_stack *jit_stack;
111*22dc650dSSadaf Ebrahimi uint32_t oveccount = match_data->oveccount;
112*22dc650dSSadaf Ebrahimi uint32_t max_oveccount;
113*22dc650dSSadaf Ebrahimi union {
114*22dc650dSSadaf Ebrahimi void *executable_func;
115*22dc650dSSadaf Ebrahimi jit_function call_executable_func;
116*22dc650dSSadaf Ebrahimi } convert_executable_func;
117*22dc650dSSadaf Ebrahimi jit_arguments arguments;
118*22dc650dSSadaf Ebrahimi int rc;
119*22dc650dSSadaf Ebrahimi int index = 0;
120*22dc650dSSadaf Ebrahimi
121*22dc650dSSadaf Ebrahimi if ((options & PCRE2_PARTIAL_HARD) != 0)
122*22dc650dSSadaf Ebrahimi index = 2;
123*22dc650dSSadaf Ebrahimi else if ((options & PCRE2_PARTIAL_SOFT) != 0)
124*22dc650dSSadaf Ebrahimi index = 1;
125*22dc650dSSadaf Ebrahimi
126*22dc650dSSadaf Ebrahimi if (functions == NULL || functions->executable_funcs[index] == NULL)
127*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_JIT_BADOPTION;
128*22dc650dSSadaf Ebrahimi
129*22dc650dSSadaf Ebrahimi /* Sanity checks should be handled by pcre2_match. */
130*22dc650dSSadaf Ebrahimi arguments.str = subject + start_offset;
131*22dc650dSSadaf Ebrahimi arguments.begin = subject;
132*22dc650dSSadaf Ebrahimi arguments.end = subject + length;
133*22dc650dSSadaf Ebrahimi arguments.match_data = match_data;
134*22dc650dSSadaf Ebrahimi arguments.startchar_ptr = subject;
135*22dc650dSSadaf Ebrahimi arguments.mark_ptr = NULL;
136*22dc650dSSadaf Ebrahimi arguments.options = options;
137*22dc650dSSadaf Ebrahimi
138*22dc650dSSadaf Ebrahimi if (mcontext != NULL)
139*22dc650dSSadaf Ebrahimi {
140*22dc650dSSadaf Ebrahimi arguments.callout = mcontext->callout;
141*22dc650dSSadaf Ebrahimi arguments.callout_data = mcontext->callout_data;
142*22dc650dSSadaf Ebrahimi arguments.offset_limit = mcontext->offset_limit;
143*22dc650dSSadaf Ebrahimi arguments.limit_match = (mcontext->match_limit < re->limit_match)?
144*22dc650dSSadaf Ebrahimi mcontext->match_limit : re->limit_match;
145*22dc650dSSadaf Ebrahimi if (mcontext->jit_callback != NULL)
146*22dc650dSSadaf Ebrahimi jit_stack = mcontext->jit_callback(mcontext->jit_callback_data);
147*22dc650dSSadaf Ebrahimi else
148*22dc650dSSadaf Ebrahimi jit_stack = (pcre2_jit_stack *)mcontext->jit_callback_data;
149*22dc650dSSadaf Ebrahimi }
150*22dc650dSSadaf Ebrahimi else
151*22dc650dSSadaf Ebrahimi {
152*22dc650dSSadaf Ebrahimi arguments.callout = NULL;
153*22dc650dSSadaf Ebrahimi arguments.callout_data = NULL;
154*22dc650dSSadaf Ebrahimi arguments.offset_limit = PCRE2_UNSET;
155*22dc650dSSadaf Ebrahimi arguments.limit_match = (MATCH_LIMIT < re->limit_match)?
156*22dc650dSSadaf Ebrahimi MATCH_LIMIT : re->limit_match;
157*22dc650dSSadaf Ebrahimi jit_stack = NULL;
158*22dc650dSSadaf Ebrahimi }
159*22dc650dSSadaf Ebrahimi
160*22dc650dSSadaf Ebrahimi
161*22dc650dSSadaf Ebrahimi max_oveccount = functions->top_bracket;
162*22dc650dSSadaf Ebrahimi if (oveccount > max_oveccount)
163*22dc650dSSadaf Ebrahimi oveccount = max_oveccount;
164*22dc650dSSadaf Ebrahimi arguments.oveccount = oveccount << 1;
165*22dc650dSSadaf Ebrahimi
166*22dc650dSSadaf Ebrahimi
167*22dc650dSSadaf Ebrahimi convert_executable_func.executable_func = functions->executable_funcs[index];
168*22dc650dSSadaf Ebrahimi if (jit_stack != NULL)
169*22dc650dSSadaf Ebrahimi {
170*22dc650dSSadaf Ebrahimi arguments.stack = (struct sljit_stack *)(jit_stack->stack);
171*22dc650dSSadaf Ebrahimi rc = convert_executable_func.call_executable_func(&arguments);
172*22dc650dSSadaf Ebrahimi }
173*22dc650dSSadaf Ebrahimi else
174*22dc650dSSadaf Ebrahimi rc = jit_machine_stack_exec(&arguments, convert_executable_func.call_executable_func);
175*22dc650dSSadaf Ebrahimi
176*22dc650dSSadaf Ebrahimi if (rc > (int)oveccount)
177*22dc650dSSadaf Ebrahimi rc = 0;
178*22dc650dSSadaf Ebrahimi match_data->code = re;
179*22dc650dSSadaf Ebrahimi match_data->subject = (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)? subject : NULL;
180*22dc650dSSadaf Ebrahimi match_data->subject_length = length;
181*22dc650dSSadaf Ebrahimi match_data->rc = rc;
182*22dc650dSSadaf Ebrahimi match_data->startchar = arguments.startchar_ptr - subject;
183*22dc650dSSadaf Ebrahimi match_data->leftchar = 0;
184*22dc650dSSadaf Ebrahimi match_data->rightchar = 0;
185*22dc650dSSadaf Ebrahimi match_data->mark = arguments.mark_ptr;
186*22dc650dSSadaf Ebrahimi match_data->matchedby = PCRE2_MATCHEDBY_JIT;
187*22dc650dSSadaf Ebrahimi
188*22dc650dSSadaf Ebrahimi #if defined(__has_feature)
189*22dc650dSSadaf Ebrahimi #if __has_feature(memory_sanitizer)
190*22dc650dSSadaf Ebrahimi if (rc > 0)
191*22dc650dSSadaf Ebrahimi __msan_unpoison(match_data->ovector, 2 * rc * sizeof(match_data->ovector[0]));
192*22dc650dSSadaf Ebrahimi #endif /* __has_feature(memory_sanitizer) */
193*22dc650dSSadaf Ebrahimi #endif /* defined(__has_feature) */
194*22dc650dSSadaf Ebrahimi
195*22dc650dSSadaf Ebrahimi return match_data->rc;
196*22dc650dSSadaf Ebrahimi
197*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_JIT */
198*22dc650dSSadaf Ebrahimi }
199*22dc650dSSadaf Ebrahimi
200*22dc650dSSadaf Ebrahimi /* End of pcre2_jit_match.c */
201