Blame glib/pcre/pcre_byte_order.c

Packit ae235b
/*************************************************
Packit ae235b
*      Perl-Compatible Regular Expressions       *
Packit ae235b
*************************************************/
Packit ae235b
Packit ae235b
/* PCRE is a library of functions to support regular expressions whose syntax
Packit ae235b
and semantics are as close as possible to those of the Perl 5 language.
Packit ae235b
Packit ae235b
                       Written by Philip Hazel
Packit ae235b
           Copyright (c) 1997-2012 University of Cambridge
Packit ae235b
Packit ae235b
-----------------------------------------------------------------------------
Packit ae235b
Redistribution and use in source and binary forms, with or without
Packit ae235b
modification, are permitted provided that the following conditions are met:
Packit ae235b
Packit ae235b
    * Redistributions of source code must retain the above copyright notice,
Packit ae235b
      this list of conditions and the following disclaimer.
Packit ae235b
Packit ae235b
    * Redistributions in binary form must reproduce the above copyright
Packit ae235b
      notice, this list of conditions and the following disclaimer in the
Packit ae235b
      documentation and/or other materials provided with the distribution.
Packit ae235b
Packit ae235b
    * Neither the name of the University of Cambridge nor the names of its
Packit ae235b
      contributors may be used to endorse or promote products derived from
Packit ae235b
      this software without specific prior written permission.
Packit ae235b
Packit ae235b
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit ae235b
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit ae235b
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit ae235b
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
Packit ae235b
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit ae235b
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Packit ae235b
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit ae235b
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Packit ae235b
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit ae235b
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Packit ae235b
POSSIBILITY OF SUCH DAMAGE.
Packit ae235b
-----------------------------------------------------------------------------
Packit ae235b
*/
Packit ae235b
Packit ae235b
Packit ae235b
/* This module contains an internal function that tests a compiled pattern to
Packit ae235b
see if it was compiled with the opposite endianness. If so, it uses an
Packit ae235b
auxiliary local function to flip the appropriate bytes. */
Packit ae235b
Packit ae235b
Packit ae235b
#include "config.h"
Packit ae235b
Packit ae235b
#include "pcre_internal.h"
Packit ae235b
Packit ae235b
Packit ae235b
/*************************************************
Packit ae235b
*             Swap byte functions                *
Packit ae235b
*************************************************/
Packit ae235b
Packit ae235b
/* The following functions swap the bytes of a pcre_uint16
Packit ae235b
and pcre_uint32 value.
Packit ae235b
Packit ae235b
Arguments:
Packit ae235b
  value        any number
Packit ae235b
Packit ae235b
Returns:       the byte swapped value
Packit ae235b
*/
Packit ae235b
Packit ae235b
static pcre_uint32
Packit ae235b
swap_uint32(pcre_uint32 value)
Packit ae235b
{
Packit ae235b
return ((value & 0x000000ff) << 24) |
Packit ae235b
       ((value & 0x0000ff00) <<  8) |
Packit ae235b
       ((value & 0x00ff0000) >>  8) |
Packit ae235b
       (value >> 24);
Packit ae235b
}
Packit ae235b
Packit ae235b
static pcre_uint16
Packit ae235b
swap_uint16(pcre_uint16 value)
Packit ae235b
{
Packit ae235b
return (value >> 8) | (value << 8);
Packit ae235b
}
Packit ae235b
Packit ae235b
Packit ae235b
/*************************************************
Packit ae235b
*       Test for a byte-flipped compiled regex   *
Packit ae235b
*************************************************/
Packit ae235b
Packit ae235b
/* This function swaps the bytes of a compiled pattern usually
Packit ae235b
loaded form the disk. It also sets the tables pointer, which
Packit ae235b
is likely an invalid pointer after reload.
Packit ae235b
Packit ae235b
Arguments:
Packit ae235b
  argument_re     points to the compiled expression
Packit ae235b
  extra_data      points to extra data or is NULL
Packit ae235b
  tables          points to the character tables or NULL
Packit ae235b
Packit ae235b
Returns:          0 if the swap is successful, negative on error
Packit ae235b
*/
Packit ae235b
Packit ae235b
#ifdef COMPILE_PCRE8
Packit ae235b
PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re,
Packit ae235b
  pcre_extra *extra_data, const unsigned char *tables)
Packit ae235b
#else
Packit ae235b
PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re,
Packit ae235b
  pcre16_extra *extra_data, const unsigned char *tables)
Packit ae235b
#endif
Packit ae235b
{
Packit ae235b
REAL_PCRE *re = (REAL_PCRE *)argument_re;
Packit ae235b
pcre_study_data *study;
Packit ae235b
#ifndef COMPILE_PCRE8
Packit ae235b
pcre_uchar *ptr;
Packit ae235b
int length;
Packit ae235b
#ifdef SUPPORT_UTF
Packit ae235b
BOOL utf;
Packit ae235b
BOOL utf16_char;
Packit ae235b
#endif /* SUPPORT_UTF */
Packit ae235b
#endif /* !COMPILE_PCRE8 */
Packit ae235b
Packit ae235b
if (re == NULL) return PCRE_ERROR_NULL;
Packit ae235b
if (re->magic_number == MAGIC_NUMBER)
Packit ae235b
  {
Packit ae235b
  if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
Packit ae235b
  re->tables = tables;
Packit ae235b
  return 0;
Packit ae235b
  }
Packit ae235b
Packit ae235b
if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
Packit ae235b
if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
Packit ae235b
Packit ae235b
re->magic_number = MAGIC_NUMBER;
Packit ae235b
re->size = swap_uint32(re->size);
Packit ae235b
re->options = swap_uint32(re->options);
Packit ae235b
re->flags = swap_uint16(re->flags);
Packit ae235b
re->top_bracket = swap_uint16(re->top_bracket);
Packit ae235b
re->top_backref = swap_uint16(re->top_backref);
Packit ae235b
re->first_char = swap_uint16(re->first_char);
Packit ae235b
re->req_char = swap_uint16(re->req_char);
Packit ae235b
re->name_table_offset = swap_uint16(re->name_table_offset);
Packit ae235b
re->name_entry_size = swap_uint16(re->name_entry_size);
Packit ae235b
re->name_count = swap_uint16(re->name_count);
Packit ae235b
re->ref_count = swap_uint16(re->ref_count);
Packit ae235b
re->tables = tables;
Packit ae235b
Packit ae235b
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
Packit ae235b
  {
Packit ae235b
  study = (pcre_study_data *)extra_data->study_data;
Packit ae235b
  study->size = swap_uint32(study->size);
Packit ae235b
  study->flags = swap_uint32(study->flags);
Packit ae235b
  study->minlength = swap_uint32(study->minlength);
Packit ae235b
  }
Packit ae235b
Packit ae235b
#ifndef COMPILE_PCRE8
Packit ae235b
ptr = (pcre_uchar *)re + re->name_table_offset;
Packit ae235b
length = re->name_count * re->name_entry_size;
Packit ae235b
#ifdef SUPPORT_UTF
Packit ae235b
utf = (re->options & PCRE_UTF16) != 0;
Packit ae235b
utf16_char = FALSE;
Packit ae235b
#endif
Packit ae235b
Packit ae235b
while(TRUE)
Packit ae235b
  {
Packit ae235b
  /* Swap previous characters. */
Packit ae235b
  while (length-- > 0)
Packit ae235b
    {
Packit ae235b
    *ptr = swap_uint16(*ptr);
Packit ae235b
    ptr++;
Packit ae235b
    }
Packit ae235b
#ifdef SUPPORT_UTF
Packit ae235b
  if (utf16_char)
Packit ae235b
    {
Packit ae235b
    if (HAS_EXTRALEN(ptr[-1]))
Packit ae235b
      {
Packit ae235b
      /* We know that there is only one extra character in UTF-16. */
Packit ae235b
      *ptr = swap_uint16(*ptr);
Packit ae235b
      ptr++;
Packit ae235b
      }
Packit ae235b
    }
Packit ae235b
  utf16_char = FALSE;
Packit ae235b
#endif /* SUPPORT_UTF */
Packit ae235b
Packit ae235b
  /* Get next opcode. */
Packit ae235b
  length = 0;
Packit ae235b
  *ptr = swap_uint16(*ptr);
Packit ae235b
  switch (*ptr)
Packit ae235b
    {
Packit ae235b
    case OP_END:
Packit ae235b
    return 0;
Packit ae235b
Packit ae235b
#ifdef SUPPORT_UTF
Packit ae235b
    case OP_CHAR:
Packit ae235b
    case OP_CHARI:
Packit ae235b
    case OP_NOT:
Packit ae235b
    case OP_NOTI:
Packit ae235b
    case OP_STAR:
Packit ae235b
    case OP_MINSTAR:
Packit ae235b
    case OP_PLUS:
Packit ae235b
    case OP_MINPLUS:
Packit ae235b
    case OP_QUERY:
Packit ae235b
    case OP_MINQUERY:
Packit ae235b
    case OP_UPTO:
Packit ae235b
    case OP_MINUPTO:
Packit ae235b
    case OP_EXACT:
Packit ae235b
    case OP_POSSTAR:
Packit ae235b
    case OP_POSPLUS:
Packit ae235b
    case OP_POSQUERY:
Packit ae235b
    case OP_POSUPTO:
Packit ae235b
    case OP_STARI:
Packit ae235b
    case OP_MINSTARI:
Packit ae235b
    case OP_PLUSI:
Packit ae235b
    case OP_MINPLUSI:
Packit ae235b
    case OP_QUERYI:
Packit ae235b
    case OP_MINQUERYI:
Packit ae235b
    case OP_UPTOI:
Packit ae235b
    case OP_MINUPTOI:
Packit ae235b
    case OP_EXACTI:
Packit ae235b
    case OP_POSSTARI:
Packit ae235b
    case OP_POSPLUSI:
Packit ae235b
    case OP_POSQUERYI:
Packit ae235b
    case OP_POSUPTOI:
Packit ae235b
    case OP_NOTSTAR:
Packit ae235b
    case OP_NOTMINSTAR:
Packit ae235b
    case OP_NOTPLUS:
Packit ae235b
    case OP_NOTMINPLUS:
Packit ae235b
    case OP_NOTQUERY:
Packit ae235b
    case OP_NOTMINQUERY:
Packit ae235b
    case OP_NOTUPTO:
Packit ae235b
    case OP_NOTMINUPTO:
Packit ae235b
    case OP_NOTEXACT:
Packit ae235b
    case OP_NOTPOSSTAR:
Packit ae235b
    case OP_NOTPOSPLUS:
Packit ae235b
    case OP_NOTPOSQUERY:
Packit ae235b
    case OP_NOTPOSUPTO:
Packit ae235b
    case OP_NOTSTARI:
Packit ae235b
    case OP_NOTMINSTARI:
Packit ae235b
    case OP_NOTPLUSI:
Packit ae235b
    case OP_NOTMINPLUSI:
Packit ae235b
    case OP_NOTQUERYI:
Packit ae235b
    case OP_NOTMINQUERYI:
Packit ae235b
    case OP_NOTUPTOI:
Packit ae235b
    case OP_NOTMINUPTOI:
Packit ae235b
    case OP_NOTEXACTI:
Packit ae235b
    case OP_NOTPOSSTARI:
Packit ae235b
    case OP_NOTPOSPLUSI:
Packit ae235b
    case OP_NOTPOSQUERYI:
Packit ae235b
    case OP_NOTPOSUPTOI:
Packit ae235b
    if (utf) utf16_char = TRUE;
Packit ae235b
#endif
Packit ae235b
    /* Fall through. */
Packit ae235b
Packit ae235b
    default:
Packit ae235b
    length = PRIV(OP_lengths)[*ptr] - 1;
Packit ae235b
    break;
Packit ae235b
Packit ae235b
    case OP_CLASS:
Packit ae235b
    case OP_NCLASS:
Packit ae235b
    /* Skip the character bit map. */
Packit ae235b
    ptr += 32/sizeof(pcre_uchar);
Packit ae235b
    length = 0;
Packit ae235b
    break;
Packit ae235b
Packit ae235b
    case OP_XCLASS:
Packit ae235b
    /* Reverse the size of the XCLASS instance. */
Packit ae235b
    ptr++;
Packit ae235b
    *ptr = swap_uint16(*ptr);
Packit ae235b
    if (LINK_SIZE > 1)
Packit ae235b
      {
Packit ae235b
      /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
Packit ae235b
      ptr++;
Packit ae235b
      *ptr = swap_uint16(*ptr);
Packit ae235b
      }
Packit ae235b
    ptr++;
Packit ae235b
    length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1);
Packit ae235b
    *ptr = swap_uint16(*ptr);
Packit ae235b
    if ((*ptr & XCL_MAP) != 0)
Packit ae235b
      {
Packit ae235b
      /* Skip the character bit map. */
Packit ae235b
      ptr += 32/sizeof(pcre_uchar);
Packit ae235b
      length -= 32/sizeof(pcre_uchar);
Packit ae235b
      }
Packit ae235b
    break;
Packit ae235b
    }
Packit ae235b
  ptr++;
Packit ae235b
  }
Packit ae235b
/* Control should never reach here in 16 bit mode. */
Packit ae235b
#endif /* !COMPILE_PCRE8 */
Packit ae235b
Packit ae235b
return 0;
Packit ae235b
}
Packit ae235b
Packit ae235b
/* End of pcre_byte_order.c */