/[pcre]/code/trunk/pcre_byte_order.c
ViewVC logotype

Diff of /code/trunk/pcre_byte_order.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

code/trunk/pcre_try_flipped.c revision 85 by nigel, Sat Feb 24 21:41:13 2007 UTC code/trunk/pcre_byte_order.c revision 836 by ph10, Wed Dec 28 17:16:11 2011 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2005 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 43  see if it was compiled with the opposite Line 43  see if it was compiled with the opposite
43  auxiliary local function to flip the appropriate bytes. */  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"  #include "pcre_internal.h"
51    
52    
53  /*************************************************  /*************************************************
54  *         Flip bytes in an integer               *  *             Swap byte functions                *
55  *************************************************/  *************************************************/
56    
57  /* This function is called when the magic number in a regex doesn't match, in  /* The following functions swap the bytes of a pcre_uint16
58  order to flip its bytes to see if we are dealing with a pattern that was  and pcre_uint32 value.
 compiled on a host of different endianness. If so, this function is used to  
 flip other byte values.  
59    
60  Arguments:  Arguments:
61    value        the number to flip    value        any number
   n            the number of bytes to flip (assumed to be 2 or 4)  
62    
63  Returns:       the flipped value  Returns:       the byte swapped value
64  */  */
65    
66  static long int  static pcre_uint32
67  byteflip(long int value, int n)  swap_uint32(pcre_uint32 value)
68  {  {
 if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);  
69  return ((value & 0x000000ff) << 24) |  return ((value & 0x000000ff) << 24) |
70         ((value & 0x0000ff00) <<  8) |         ((value & 0x0000ff00) <<  8) |
71         ((value & 0x00ff0000) >>  8) |         ((value & 0x00ff0000) >>  8) |
72         ((value & 0xff000000) >> 24);         (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   *  *       Test for a byte-flipped compiled regex   *
84  *************************************************/  *************************************************/
85    
86  /* This function is called from pcre_exec(), pcre_dfa_exec(), and also from  /* This function swaps the bytes of a compiled pattern usually
87  pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that  loaded form the disk. It also sets the tables pointer, which
88  is, it was compiled on a system of opposite endianness. The function is called  is likely an invalid pointer after reload.
 only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped,  
 we flip all the relevant values into a different data block, and return it.  
89    
90  Arguments:  Arguments:
91    re               points to the regex    argument_re     points to the compiled expression
92    study            points to study data, or NULL    extra_data      points to extra data or is NULL
93    internal_re      points to a new regex block    tables          points to the character tables or NULL
   internal_study   points to a new study block  
94    
95  Returns:           the new block if is is indeed a byte-flipped regex  Returns:          0 if the swap is successful, negative on error
                    NULL if it is not  
96  */  */
97    
98  PCRE_EXPORT real_pcre *  #ifdef COMPILE_PCRE8
99  _pcre_try_flipped(const real_pcre *re, real_pcre *internal_re,  PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re,
100    const pcre_study_data *study, pcre_study_data *internal_study)    pcre_extra *extra_data, const unsigned char *tables)
101    #else
102    PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre *argument_re,
103      pcre_extra *extra_data, const unsigned char *tables)
104    #endif
105  {  {
106  if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER)  real_pcre *re = (real_pcre *)argument_re;
107    return NULL;  pcre_study_data *study;
108    #ifndef COMPILE_PCRE8
109    pcre_uchar *ptr;
110    int length;
111    #ifdef SUPPORT_UTF
112    BOOL utf;
113    BOOL utf16_char;
114    #endif /* SUPPORT_UTF */
115    #endif /* !COMPILE_PCRE8 */
116    
117    if (re == NULL) return PCRE_ERROR_NULL;
118    if (re->magic_number == MAGIC_NUMBER)
119      {
120      if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
121      re->tables = tables;
122      return 0;
123      }
124    
125    if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
126    if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
127    
128    re->magic_number = MAGIC_NUMBER;
129    re->size = swap_uint32(re->size);
130    re->options = swap_uint32(re->options);
131    re->flags = swap_uint16(re->flags);
132    re->top_bracket = swap_uint16(re->top_bracket);
133    re->top_backref = swap_uint16(re->top_backref);
134    re->first_char = swap_uint16(re->first_char);
135    re->req_char = swap_uint16(re->req_char);
136    re->name_table_offset = swap_uint16(re->name_table_offset);
137    re->name_entry_size = swap_uint16(re->name_entry_size);
138    re->name_count = swap_uint16(re->name_count);
139    re->ref_count = swap_uint16(re->ref_count);
140    re->tables = tables;
141    
142    if (extra_data != NULL && (re->flags & PCRE_EXTRA_STUDY_DATA) != 0)
143      {
144      study = (pcre_study_data *)extra_data->study_data;
145      study->size = swap_uint32(study->size);
146      study->flags = swap_uint32(study->flags);
147      study->minlength = swap_uint32(study->minlength);
148      }
149    
150  *internal_re = *re;           /* To copy other fields */  #ifndef COMPILE_PCRE8
151  internal_re->size = byteflip(re->size, sizeof(re->size));  ptr = (pcre_uchar *)re + re->name_table_offset;
152  internal_re->options = byteflip(re->options, sizeof(re->options));  length = re->name_count * re->name_entry_size;
153  internal_re->top_bracket =  #ifdef SUPPORT_UTF
154    (pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket));  utf = (re->options & PCRE_UTF16) != 0;
155  internal_re->top_backref =  utf16_char = FALSE;
156    (pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref));  #endif
 internal_re->first_byte =  
   (pcre_uint16)byteflip(re->first_byte, sizeof(re->first_byte));  
 internal_re->req_byte =  
   (pcre_uint16)byteflip(re->req_byte, sizeof(re->req_byte));  
 internal_re->name_table_offset =  
   (pcre_uint16)byteflip(re->name_table_offset, sizeof(re->name_table_offset));  
 internal_re->name_entry_size =  
   (pcre_uint16)byteflip(re->name_entry_size, sizeof(re->name_entry_size));  
 internal_re->name_count =  
   (pcre_uint16)byteflip(re->name_count, sizeof(re->name_count));  
157    
158  if (study != NULL)  while(TRUE)
159    {    {
160    *internal_study = *study;   /* To copy other fields */    /* Swap previous characters. */
161    internal_study->size = byteflip(study->size, sizeof(study->size));    while (length-- > 0)
162    internal_study->options = byteflip(study->options, sizeof(study->options));      {
163        *ptr = swap_uint16(*ptr);
164        ptr++;
165        }
166    #ifdef SUPPORT_UTF
167      if (utf16_char)
168        {
169        if (HAS_EXTRALEN(ptr[-1]))
170          {
171          /* We know that there is only one extra character in UTF-16. */
172          *ptr = swap_uint16(*ptr);
173          ptr++;
174          }
175        }
176      utf16_char = FALSE;
177    #endif /* SUPPORT_UTF */
178    
179      /* Get next opcode. */
180      length = 0;
181      *ptr = swap_uint16(*ptr);
182      switch (*ptr)
183        {
184        case OP_END:
185        return 0;
186    
187    #ifdef SUPPORT_UTF
188        case OP_CHAR:
189        case OP_CHARI:
190        case OP_NOT:
191        case OP_NOTI:
192        case OP_STAR:
193        case OP_MINSTAR:
194        case OP_PLUS:
195        case OP_MINPLUS:
196        case OP_QUERY:
197        case OP_MINQUERY:
198        case OP_UPTO:
199        case OP_MINUPTO:
200        case OP_EXACT:
201        case OP_POSSTAR:
202        case OP_POSPLUS:
203        case OP_POSQUERY:
204        case OP_POSUPTO:
205        case OP_STARI:
206        case OP_MINSTARI:
207        case OP_PLUSI:
208        case OP_MINPLUSI:
209        case OP_QUERYI:
210        case OP_MINQUERYI:
211        case OP_UPTOI:
212        case OP_MINUPTOI:
213        case OP_EXACTI:
214        case OP_POSSTARI:
215        case OP_POSPLUSI:
216        case OP_POSQUERYI:
217        case OP_POSUPTOI:
218        case OP_NOTSTAR:
219        case OP_NOTMINSTAR:
220        case OP_NOTPLUS:
221        case OP_NOTMINPLUS:
222        case OP_NOTQUERY:
223        case OP_NOTMINQUERY:
224        case OP_NOTUPTO:
225        case OP_NOTMINUPTO:
226        case OP_NOTEXACT:
227        case OP_NOTPOSSTAR:
228        case OP_NOTPOSPLUS:
229        case OP_NOTPOSQUERY:
230        case OP_NOTPOSUPTO:
231        case OP_NOTSTARI:
232        case OP_NOTMINSTARI:
233        case OP_NOTPLUSI:
234        case OP_NOTMINPLUSI:
235        case OP_NOTQUERYI:
236        case OP_NOTMINQUERYI:
237        case OP_NOTUPTOI:
238        case OP_NOTMINUPTOI:
239        case OP_NOTEXACTI:
240        case OP_NOTPOSSTARI:
241        case OP_NOTPOSPLUSI:
242        case OP_NOTPOSQUERYI:
243        case OP_NOTPOSUPTOI:
244        if (utf) utf16_char = TRUE;
245    #endif
246        /* Fall through. */
247    
248        default:
249        length = PRIV(OP_lengths)[*ptr] - 1;
250        break;
251    
252        case OP_CLASS:
253        case OP_NCLASS:
254        /* Skip the character bit map. */
255        ptr += 32/sizeof(pcre_uchar);
256        length = 0;
257        break;
258    
259        case OP_XCLASS:
260        /* Reverse the size of the XCLASS instance. */
261        ptr++;
262        *ptr = swap_uint16(*ptr);
263        if (LINK_SIZE > 1)
264          {
265          /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
266          ptr++;
267          *ptr = swap_uint16(*ptr);
268          }
269        ptr++;
270        length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1);
271        *ptr = swap_uint16(*ptr);
272        if ((*ptr & XCL_MAP) != 0)
273          {
274          /* Skip the character bit map. */
275          ptr += 32/sizeof(pcre_uchar);
276          length -= 32/sizeof(pcre_uchar);
277          }
278        break;
279        }
280      ptr++;
281    }    }
282    /* Control should never reach here in 16 bit mode. */
283    #endif /* !COMPILE_PCRE8 */
284    
285  return internal_re;  return 0;
286  }  }
287    
288  /* End of pcre_tryflipped.c */  /* End of pcre_byte_order.c */

Legend:
Removed from v.85  
changed lines
  Added in v.836

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12