xref: /PHP-7.1/ext/pcre/pcrelib/pcre_fullinfo.c (revision 5f9df47e)
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 "config.h"
46 
47 #include "pcre_internal.h"
48 
49 
50 /*************************************************
51 *        Return info about compiled pattern      *
52 *************************************************/
53 
54 /* This is a newer "info" function which has an extensible interface so
55 that additional items can be added compatibly.
56 
57 Arguments:
58   argument_re      points to compiled code
59   extra_data       points extra data, or NULL
60   what             what information is required
61   where            where to put the information
62 
63 Returns:           0 if data returned, negative on error
64 */
65 
66 #if defined COMPILE_PCRE8
67 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_fullinfo(const pcre * argument_re,const pcre_extra * extra_data,int what,void * where)68 pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data,
69   int what, void *where)
70 #elif defined COMPILE_PCRE16
71 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
72 pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data,
73   int what, void *where)
74 #elif defined COMPILE_PCRE32
75 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
76 pcre32_fullinfo(const pcre32 *argument_re, const pcre32_extra *extra_data,
77   int what, void *where)
78 #endif
79 {
80 const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
81 const pcre_study_data *study = NULL;
82 
83 if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
84 
85 if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
86   study = (const pcre_study_data *)extra_data->study_data;
87 
88 /* Check that the first field in the block is the magic number. If it is not,
89 return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
90 REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
91 means that the pattern is likely compiled with different endianness. */
92 
93 if (re->magic_number != MAGIC_NUMBER)
94   return re->magic_number == REVERSED_MAGIC_NUMBER?
95     PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
96 
97 /* Check that this pattern was compiled in the correct bit mode */
98 
99 if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
100 
101 switch (what)
102   {
103   case PCRE_INFO_OPTIONS:
104   *((unsigned long int *)where) = re->options & PUBLIC_COMPILE_OPTIONS;
105   break;
106 
107   case PCRE_INFO_SIZE:
108   *((size_t *)where) = re->size;
109   break;
110 
111   case PCRE_INFO_STUDYSIZE:
112   *((size_t *)where) = (study == NULL)? 0 : study->size;
113   break;
114 
115   case PCRE_INFO_JITSIZE:
116 #ifdef SUPPORT_JIT
117   *((size_t *)where) =
118       (extra_data != NULL &&
119       (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
120       extra_data->executable_jit != NULL)?
121     PRIV(jit_get_size)(extra_data->executable_jit) : 0;
122 #else
123   *((size_t *)where) = 0;
124 #endif
125   break;
126 
127   case PCRE_INFO_CAPTURECOUNT:
128   *((int *)where) = re->top_bracket;
129   break;
130 
131   case PCRE_INFO_BACKREFMAX:
132   *((int *)where) = re->top_backref;
133   break;
134 
135   case PCRE_INFO_FIRSTBYTE:
136   *((int *)where) =
137     ((re->flags & PCRE_FIRSTSET) != 0)? (int)re->first_char :
138     ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
139   break;
140 
141   case PCRE_INFO_FIRSTCHARACTER:
142     *((pcre_uint32 *)where) =
143       (re->flags & PCRE_FIRSTSET) != 0 ? re->first_char : 0;
144     break;
145 
146   case PCRE_INFO_FIRSTCHARACTERFLAGS:
147     *((int *)where) =
148       ((re->flags & PCRE_FIRSTSET) != 0) ? 1 :
149       ((re->flags & PCRE_STARTLINE) != 0) ? 2 : 0;
150     break;
151 
152   /* Make sure we pass back the pointer to the bit vector in the external
153   block, not the internal copy (with flipped integer fields). */
154 
155   case PCRE_INFO_FIRSTTABLE:
156   *((const pcre_uint8 **)where) =
157     (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)?
158       ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
159   break;
160 
161   case PCRE_INFO_MINLENGTH:
162   *((int *)where) =
163     (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)?
164       (int)(study->minlength) : -1;
165   break;
166 
167   case PCRE_INFO_JIT:
168   *((int *)where) = extra_data != NULL &&
169                     (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
170                     extra_data->executable_jit != NULL;
171   break;
172 
173   case PCRE_INFO_LASTLITERAL:
174   *((int *)where) =
175     ((re->flags & PCRE_REQCHSET) != 0)? (int)re->req_char : -1;
176   break;
177 
178   case PCRE_INFO_REQUIREDCHAR:
179     *((pcre_uint32 *)where) =
180       ((re->flags & PCRE_REQCHSET) != 0) ? re->req_char : 0;
181     break;
182 
183   case PCRE_INFO_REQUIREDCHARFLAGS:
184     *((int *)where) =
185       ((re->flags & PCRE_REQCHSET) != 0);
186     break;
187 
188   case PCRE_INFO_NAMEENTRYSIZE:
189   *((int *)where) = re->name_entry_size;
190   break;
191 
192   case PCRE_INFO_NAMECOUNT:
193   *((int *)where) = re->name_count;
194   break;
195 
196   case PCRE_INFO_NAMETABLE:
197   *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset;
198   break;
199 
200   case PCRE_INFO_DEFAULT_TABLES:
201   *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables));
202   break;
203 
204   /* From release 8.00 this will always return TRUE because NOPARTIAL is
205   no longer ever set (the restrictions have been removed). */
206 
207   case PCRE_INFO_OKPARTIAL:
208   *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0;
209   break;
210 
211   case PCRE_INFO_JCHANGED:
212   *((int *)where) = (re->flags & PCRE_JCHANGED) != 0;
213   break;
214 
215   case PCRE_INFO_HASCRORLF:
216   *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0;
217   break;
218 
219   case PCRE_INFO_MAXLOOKBEHIND:
220   *((int *)where) = re->max_lookbehind;
221   break;
222 
223   case PCRE_INFO_MATCHLIMIT:
224   if ((re->flags & PCRE_MLSET) == 0) return PCRE_ERROR_UNSET;
225   *((pcre_uint32 *)where) = re->limit_match;
226   break;
227 
228   case PCRE_INFO_RECURSIONLIMIT:
229   if ((re->flags & PCRE_RLSET) == 0) return PCRE_ERROR_UNSET;
230   *((pcre_uint32 *)where) = re->limit_recursion;
231   break;
232 
233   case PCRE_INFO_MATCH_EMPTY:
234   *((int *)where) = (re->flags & PCRE_MATCH_EMPTY) != 0;
235   break;
236 
237   default: return PCRE_ERROR_BADOPTION;
238   }
239 
240 return 0;
241 }
242 
243 /* End of pcre_fullinfo.c */
244