1 | /************************************************* |
2 | * Perl-Compatible Regular Expressions * |
3 | *************************************************/ |
4 | |
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 | |
8 | Written by Philip Hazel |
9 | Copyright (c) 1997-2013 University of Cambridge |
10 | |
11 | ----------------------------------------------------------------------------- |
12 | Redistribution and use in source and binary forms, with or without |
13 | modification, are permitted provided that the following conditions are met: |
14 | |
15 | * Redistributions of source code must retain the above copyright notice, |
16 | this list of conditions and the following disclaimer. |
17 | |
18 | * Redistributions in binary form must reproduce the above copyright |
19 | notice, this list of conditions and the following disclaimer in the |
20 | documentation and/or other materials provided with the distribution. |
21 | |
22 | * Neither the name of the University of Cambridge nor the names of its |
23 | contributors may be used to endorse or promote products derived from |
24 | this software without specific prior written permission. |
25 | |
26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
27 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
28 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
29 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
30 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
31 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
32 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
33 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
34 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
35 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
36 | POSSIBILITY OF SUCH DAMAGE. |
37 | ----------------------------------------------------------------------------- |
38 | */ |
39 | |
40 | |
41 | /* This module contains the external function pcre_fullinfo(), which returns |
42 | information about a compiled pattern. */ |
43 | |
44 | |
45 | #include "pcre_config.h" |
46 | #include "pcre_internal.h" |
47 | |
48 | |
49 | /************************************************* |
50 | * Return info about compiled pattern * |
51 | *************************************************/ |
52 | |
53 | /* This is a newer "info" function which has an extensible interface so |
54 | that additional items can be added compatibly. |
55 | |
56 | Arguments: |
57 | argument_re points to compiled code |
58 | extra_data points extra data, or NULL |
59 | what what information is required |
60 | where where to put the information |
61 | |
62 | Returns: 0 if data returned, negative on error |
63 | */ |
64 | |
65 | #if defined COMPILE_PCRE8 |
66 | PCRE_EXP_DEFN int PCRE_CALL_CONVENTION |
67 | pcre_fullinfo(const pcre *argument_re, const pcre_extra *, |
68 | int what, void *where) |
69 | #elif defined COMPILE_PCRE16 |
70 | PCRE_EXP_DEFN int PCRE_CALL_CONVENTION |
71 | pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data, |
72 | int what, void *where) |
73 | #elif defined COMPILE_PCRE32 |
74 | PCRE_EXP_DEFN int PCRE_CALL_CONVENTION |
75 | pcre32_fullinfo(const pcre32 *argument_re, const pcre32_extra *extra_data, |
76 | int what, void *where) |
77 | #endif |
78 | { |
79 | const REAL_PCRE *re = (const REAL_PCRE *)argument_re; |
80 | const pcre_study_data *study = NULL; |
81 | |
82 | if (re == NULL || where == NULL) return PCRE_ERROR_NULL; |
83 | |
84 | if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) |
85 | study = (const pcre_study_data *)extra_data->study_data; |
86 | |
87 | /* Check that the first field in the block is the magic number. If it is not, |
88 | return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to |
89 | REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which |
90 | means that the pattern is likely compiled with different endianness. */ |
91 | |
92 | if (re->magic_number != MAGIC_NUMBER) |
93 | return re->magic_number == REVERSED_MAGIC_NUMBER? |
94 | PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; |
95 | |
96 | /* Check that this pattern was compiled in the correct bit mode */ |
97 | |
98 | if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; |
99 | |
100 | switch (what) |
101 | { |
102 | case PCRE_INFO_OPTIONS: |
103 | *((unsigned long int *)where) = re->options & PUBLIC_COMPILE_OPTIONS; |
104 | break; |
105 | |
106 | case PCRE_INFO_SIZE: |
107 | *((size_t *)where) = re->size; |
108 | break; |
109 | |
110 | case PCRE_INFO_STUDYSIZE: |
111 | *((size_t *)where) = (study == NULL)? 0 : study->size; |
112 | break; |
113 | |
114 | case PCRE_INFO_JITSIZE: |
115 | #ifdef SUPPORT_JIT |
116 | *((size_t *)where) = |
117 | (extra_data != NULL && |
118 | (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && |
119 | extra_data->executable_jit != NULL)? |
120 | PRIV(jit_get_size)(extra_data->executable_jit) : 0; |
121 | #else |
122 | *((size_t *)where) = 0; |
123 | #endif |
124 | break; |
125 | |
126 | case PCRE_INFO_CAPTURECOUNT: |
127 | *((int *)where) = re->top_bracket; |
128 | break; |
129 | |
130 | case PCRE_INFO_BACKREFMAX: |
131 | *((int *)where) = re->top_backref; |
132 | break; |
133 | |
134 | case PCRE_INFO_FIRSTBYTE: |
135 | *((int *)where) = |
136 | ((re->flags & PCRE_FIRSTSET) != 0)? (int)re->first_char : |
137 | ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2; |
138 | break; |
139 | |
140 | case PCRE_INFO_FIRSTCHARACTER: |
141 | *((pcre_uint32 *)where) = |
142 | (re->flags & PCRE_FIRSTSET) != 0 ? re->first_char : 0; |
143 | break; |
144 | |
145 | case PCRE_INFO_FIRSTCHARACTERFLAGS: |
146 | *((int *)where) = |
147 | ((re->flags & PCRE_FIRSTSET) != 0) ? 1 : |
148 | ((re->flags & PCRE_STARTLINE) != 0) ? 2 : 0; |
149 | break; |
150 | |
151 | /* Make sure we pass back the pointer to the bit vector in the external |
152 | block, not the internal copy (with flipped integer fields). */ |
153 | |
154 | case PCRE_INFO_FIRSTTABLE: |
155 | *((const pcre_uint8 **)where) = |
156 | (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)? |
157 | ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL; |
158 | break; |
159 | |
160 | case PCRE_INFO_MINLENGTH: |
161 | *((int *)where) = |
162 | (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)? |
163 | (int)(study->minlength) : -1; |
164 | break; |
165 | |
166 | case PCRE_INFO_JIT: |
167 | *((int *)where) = extra_data != NULL && |
168 | (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && |
169 | extra_data->executable_jit != NULL; |
170 | break; |
171 | |
172 | case PCRE_INFO_LASTLITERAL: |
173 | *((int *)where) = |
174 | ((re->flags & PCRE_REQCHSET) != 0)? (int)re->req_char : -1; |
175 | break; |
176 | |
177 | case PCRE_INFO_REQUIREDCHAR: |
178 | *((pcre_uint32 *)where) = |
179 | ((re->flags & PCRE_REQCHSET) != 0) ? re->req_char : 0; |
180 | break; |
181 | |
182 | case PCRE_INFO_REQUIREDCHARFLAGS: |
183 | *((int *)where) = |
184 | ((re->flags & PCRE_REQCHSET) != 0); |
185 | break; |
186 | |
187 | case PCRE_INFO_NAMEENTRYSIZE: |
188 | *((int *)where) = re->name_entry_size; |
189 | break; |
190 | |
191 | case PCRE_INFO_NAMECOUNT: |
192 | *((int *)where) = re->name_count; |
193 | break; |
194 | |
195 | case PCRE_INFO_NAMETABLE: |
196 | *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset; |
197 | break; |
198 | |
199 | case PCRE_INFO_DEFAULT_TABLES: |
200 | *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables)); |
201 | break; |
202 | |
203 | /* From release 8.00 this will always return TRUE because NOPARTIAL is |
204 | no longer ever set (the restrictions have been removed). */ |
205 | |
206 | case PCRE_INFO_OKPARTIAL: |
207 | *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0; |
208 | break; |
209 | |
210 | case PCRE_INFO_JCHANGED: |
211 | *((int *)where) = (re->flags & PCRE_JCHANGED) != 0; |
212 | break; |
213 | |
214 | case PCRE_INFO_HASCRORLF: |
215 | *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0; |
216 | break; |
217 | |
218 | case PCRE_INFO_MAXLOOKBEHIND: |
219 | *((int *)where) = re->max_lookbehind; |
220 | break; |
221 | |
222 | case PCRE_INFO_MATCHLIMIT: |
223 | if ((re->flags & PCRE_MLSET) == 0) return PCRE_ERROR_UNSET; |
224 | *((pcre_uint32 *)where) = re->limit_match; |
225 | break; |
226 | |
227 | case PCRE_INFO_RECURSIONLIMIT: |
228 | if ((re->flags & PCRE_RLSET) == 0) return PCRE_ERROR_UNSET; |
229 | *((pcre_uint32 *)where) = re->limit_recursion; |
230 | break; |
231 | |
232 | case PCRE_INFO_MATCH_EMPTY: |
233 | *((int *)where) = (re->flags & PCRE_MATCH_EMPTY) != 0; |
234 | break; |
235 | |
236 | default: return PCRE_ERROR_BADOPTION; |
237 | } |
238 | |
239 | return 0; |
240 | } |
241 | |
242 | /* End of pcre_fullinfo.c */ |
243 | |