Home | History | Annotate | Download | only in dist
      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-2014 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 #else  /* In 8-bit mode, the pattern does not need to be processed. */
    315 return 0;
    316 #endif /* !COMPILE_PCRE8 */
    317 }
    318 
    319 /* End of pcre_byte_order.c */
    320