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 an internal function that tests a compiled pattern to
42: see if it was compiled with the opposite endianness. If so, it uses an
43: auxiliary local function to flip the appropriate bytes. */
44:
45:
46: #ifdef HAVE_CONFIG_H
47: #include "config.h"
48: #endif
49:
50: #include "pcre_internal.h"
51:
52:
53: /*************************************************
54: * Swap byte functions *
55: *************************************************/
56:
57: /* The following functions swap the bytes of a pcre_uint16
58: and pcre_uint32 value.
59:
60: Arguments:
61: value any number
62:
63: Returns: the byte swapped value
64: */
65:
66: static pcre_uint32
67: swap_uint32(pcre_uint32 value)
68: {
69: return ((value & 0x000000ff) << 24) |
70: ((value & 0x0000ff00) << 8) |
71: ((value & 0x00ff0000) >> 8) |
72: (value >> 24);
73: }
74:
75: static pcre_uint16
76: swap_uint16(pcre_uint16 value)
77: {
78: return (value >> 8) | (value << 8);
79: }
80:
81:
82: /*************************************************
83: * Test for a byte-flipped compiled regex *
84: *************************************************/
85:
86: /* This function swaps the bytes of a compiled pattern usually
87: loaded form the disk. It also sets the tables pointer, which
88: is likely an invalid pointer after reload.
89:
90: Arguments:
91: argument_re points to the compiled expression
92: extra_data points to extra data or is NULL
93: tables points to the character tables or NULL
94:
95: Returns: 0 if the swap is successful, negative on error
96: */
97:
98: #if defined COMPILE_PCRE8
99: PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re,
100: pcre_extra *extra_data, const unsigned char *tables)
101: #elif defined COMPILE_PCRE16
102: PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re,
103: pcre16_extra *extra_data, const unsigned char *tables)
104: #elif defined COMPILE_PCRE32
105: PCRE_EXP_DECL int pcre32_pattern_to_host_byte_order(pcre32 *argument_re,
106: pcre32_extra *extra_data, const unsigned char *tables)
107: #endif
108: {
109: REAL_PCRE *re = (REAL_PCRE *)argument_re;
110: pcre_study_data *study;
111: #ifndef COMPILE_PCRE8
112: pcre_uchar *ptr;
113: int length;
114: #if defined SUPPORT_UTF && defined COMPILE_PCRE16
115: BOOL utf;
116: BOOL utf16_char;
117: #endif /* SUPPORT_UTF && COMPILE_PCRE16 */
118: #endif /* !COMPILE_PCRE8 */
119:
120: if (re == NULL) return PCRE_ERROR_NULL;
121: if (re->magic_number == MAGIC_NUMBER)
122: {
123: if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
124: re->tables = tables;
125: return 0;
126: }
127:
128: if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
129: if ((swap_uint32(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
130:
131: re->magic_number = MAGIC_NUMBER;
132: re->size = swap_uint32(re->size);
133: re->options = swap_uint32(re->options);
134: re->flags = swap_uint32(re->flags);
135: re->limit_match = swap_uint32(re->limit_match);
136: re->limit_recursion = swap_uint32(re->limit_recursion);
137:
138: #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
139: re->first_char = swap_uint16(re->first_char);
140: re->req_char = swap_uint16(re->req_char);
141: #elif defined COMPILE_PCRE32
142: re->first_char = swap_uint32(re->first_char);
143: re->req_char = swap_uint32(re->req_char);
144: #endif
145:
146: re->max_lookbehind = swap_uint16(re->max_lookbehind);
147: re->top_bracket = swap_uint16(re->top_bracket);
148: re->top_backref = swap_uint16(re->top_backref);
149: re->name_table_offset = swap_uint16(re->name_table_offset);
150: re->name_entry_size = swap_uint16(re->name_entry_size);
151: re->name_count = swap_uint16(re->name_count);
152: re->ref_count = swap_uint16(re->ref_count);
153: re->tables = tables;
154:
155: if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
156: {
157: study = (pcre_study_data *)extra_data->study_data;
158: study->size = swap_uint32(study->size);
159: study->flags = swap_uint32(study->flags);
160: study->minlength = swap_uint32(study->minlength);
161: }
162:
163: #ifndef COMPILE_PCRE8
164: ptr = (pcre_uchar *)re + re->name_table_offset;
165: length = re->name_count * re->name_entry_size;
166: #if defined SUPPORT_UTF && defined COMPILE_PCRE16
167: utf = (re->options & PCRE_UTF16) != 0;
168: utf16_char = FALSE;
169: #endif /* SUPPORT_UTF && COMPILE_PCRE16 */
170:
171: while(TRUE)
172: {
173: /* Swap previous characters. */
174: while (length-- > 0)
175: {
176: #if defined COMPILE_PCRE16
177: *ptr = swap_uint16(*ptr);
178: #elif defined COMPILE_PCRE32
179: *ptr = swap_uint32(*ptr);
180: #endif
181: ptr++;
182: }
183: #if defined SUPPORT_UTF && defined COMPILE_PCRE16
184: if (utf16_char)
185: {
186: if (HAS_EXTRALEN(ptr[-1]))
187: {
188: /* We know that there is only one extra character in UTF-16. */
189: *ptr = swap_uint16(*ptr);
190: ptr++;
191: }
192: }
193: utf16_char = FALSE;
194: #endif /* SUPPORT_UTF */
195:
196: /* Get next opcode. */
197: length = 0;
198: #if defined COMPILE_PCRE16
199: *ptr = swap_uint16(*ptr);
200: #elif defined COMPILE_PCRE32
201: *ptr = swap_uint32(*ptr);
202: #endif
203: switch (*ptr)
204: {
205: case OP_END:
206: return 0;
207:
208: #if defined SUPPORT_UTF && defined COMPILE_PCRE16
209: case OP_CHAR:
210: case OP_CHARI:
211: case OP_NOT:
212: case OP_NOTI:
213: case OP_STAR:
214: case OP_MINSTAR:
215: case OP_PLUS:
216: case OP_MINPLUS:
217: case OP_QUERY:
218: case OP_MINQUERY:
219: case OP_UPTO:
220: case OP_MINUPTO:
221: case OP_EXACT:
222: case OP_POSSTAR:
223: case OP_POSPLUS:
224: case OP_POSQUERY:
225: case OP_POSUPTO:
226: case OP_STARI:
227: case OP_MINSTARI:
228: case OP_PLUSI:
229: case OP_MINPLUSI:
230: case OP_QUERYI:
231: case OP_MINQUERYI:
232: case OP_UPTOI:
233: case OP_MINUPTOI:
234: case OP_EXACTI:
235: case OP_POSSTARI:
236: case OP_POSPLUSI:
237: case OP_POSQUERYI:
238: case OP_POSUPTOI:
239: case OP_NOTSTAR:
240: case OP_NOTMINSTAR:
241: case OP_NOTPLUS:
242: case OP_NOTMINPLUS:
243: case OP_NOTQUERY:
244: case OP_NOTMINQUERY:
245: case OP_NOTUPTO:
246: case OP_NOTMINUPTO:
247: case OP_NOTEXACT:
248: case OP_NOTPOSSTAR:
249: case OP_NOTPOSPLUS:
250: case OP_NOTPOSQUERY:
251: case OP_NOTPOSUPTO:
252: case OP_NOTSTARI:
253: case OP_NOTMINSTARI:
254: case OP_NOTPLUSI:
255: case OP_NOTMINPLUSI:
256: case OP_NOTQUERYI:
257: case OP_NOTMINQUERYI:
258: case OP_NOTUPTOI:
259: case OP_NOTMINUPTOI:
260: case OP_NOTEXACTI:
261: case OP_NOTPOSSTARI:
262: case OP_NOTPOSPLUSI:
263: case OP_NOTPOSQUERYI:
264: case OP_NOTPOSUPTOI:
265: if (utf) utf16_char = TRUE;
266: #endif
267: /* Fall through. */
268:
269: default:
270: length = PRIV(OP_lengths)[*ptr] - 1;
271: break;
272:
273: case OP_CLASS:
274: case OP_NCLASS:
275: /* Skip the character bit map. */
276: ptr += 32/sizeof(pcre_uchar);
277: length = 0;
278: break;
279:
280: case OP_XCLASS:
281: /* Reverse the size of the XCLASS instance. */
282: ptr++;
283: #if defined COMPILE_PCRE16
284: *ptr = swap_uint16(*ptr);
285: #elif defined COMPILE_PCRE32
286: *ptr = swap_uint32(*ptr);
287: #endif
288: #ifndef COMPILE_PCRE32
289: if (LINK_SIZE > 1)
290: {
291: /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
292: ptr++;
293: *ptr = swap_uint16(*ptr);
294: }
295: #endif
296: ptr++;
297: length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1);
298: #if defined COMPILE_PCRE16
299: *ptr = swap_uint16(*ptr);
300: #elif defined COMPILE_PCRE32
301: *ptr = swap_uint32(*ptr);
302: #endif
303: if ((*ptr & XCL_MAP) != 0)
304: {
305: /* Skip the character bit map. */
306: ptr += 32/sizeof(pcre_uchar);
307: length -= 32/sizeof(pcre_uchar);
308: }
309: break;
310: }
311: ptr++;
312: }
313: /* Control should never reach here in 16/32 bit mode. */
314: #endif /* !COMPILE_PCRE8 */
315:
316: return 0;
317: }
318:
319: /* End of pcre_byte_order.c */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>