--- code/branches/pcre16/pcre_try_flipped.c 2011/12/15 11:57:39 806 +++ code/branches/pcre16/pcre_byte_order.c 2011/12/19 11:04:45 809 @@ -51,89 +51,236 @@ /************************************************* -* Flip bytes in an integer * +* Swap byte functions * *************************************************/ -/* This function is called when the magic number in a regex doesn't match, in -order to flip its bytes to see if we are dealing with a pattern that was -compiled on a host of different endianness. If so, this function is used to -flip other byte values. +/* The following functions swap the bytes of a pcre_uint16 +and pcre_uint32 value. Arguments: - value the number to flip - n the number of bytes to flip (assumed to be 2 or 4) + value any number -Returns: the flipped value +Returns: the byte swapped value */ -static unsigned long int -byteflip(unsigned long int value, int n) +static pcre_uint32 +swap_uint32(pcre_uint32 value) { -if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8); return ((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | - ((value & 0xff000000) >> 24); + (value >> 24); } +static pcre_uint16 +swap_uint16(pcre_uint16 value) +{ +return (value >> 8) | (value << 8); +} /************************************************* * Test for a byte-flipped compiled regex * *************************************************/ -/* This function is called from pcre_exec(), pcre_dfa_exec(), and also from -pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that -is, it was compiled on a system of opposite endianness. The function is called -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. +/* This function swaps the bytes of a compiled pattern usually +loaeded form the disk. It also sets the tables pointer, which +is likely an invalid pointer after reload. Arguments: - re points to the regex - study points to study data, or NULL - internal_re points to a new regex block - internal_study points to a new study block + argument_re points to the compiled expression + extra_data points to extra data or is NULL + tables points to the character tables or NULL -Returns: the new block if is is indeed a byte-flipped regex - NULL if it is not +Returns: 0 if the swap is successful, negative on error */ -real_pcre * -PRIV(try_flipped)(const real_pcre *re, real_pcre *internal_re, - const pcre_study_data *study, pcre_study_data *internal_study) +#ifdef COMPILE_PCRE8 +PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re, + pcre_extra *extra_data, const unsigned char *tables) +#else +PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre *argument_re, + pcre_extra *extra_data, const unsigned char *tables) +#endif { -if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER) - return NULL; +real_pcre *re = (real_pcre *)argument_re; +pcre_study_data *study; +#ifndef COMPILE_PCRE8 +pcre_uchar *ptr; +int length; +#ifdef SUPPORT_UTF +BOOL utf; +BOOL utf16_char; +#endif /* SUPPORT_UTF */ +#endif /* !COMPILE_PCRE8 */ + +if (re == NULL) return PCRE_ERROR_NULL; +if (re->magic_number == MAGIC_NUMBER) + { + if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; + re->tables = tables; + return 0; + } + +if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC; +if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; + +re->magic_number = MAGIC_NUMBER; +re->size = swap_uint32(re->size); +re->options = swap_uint32(re->options); +re->flags = swap_uint16(re->flags); +re->top_bracket = swap_uint16(re->top_bracket); +re->top_backref = swap_uint16(re->top_backref); +re->first_char = swap_uint16(re->first_char); +re->req_char = swap_uint16(re->req_char); +re->name_table_offset = swap_uint16(re->name_table_offset); +re->name_entry_size = swap_uint16(re->name_entry_size); +re->name_count = swap_uint16(re->name_count); +re->ref_count = swap_uint16(re->ref_count); + +if (extra_data != NULL && (re->flags & PCRE_EXTRA_STUDY_DATA) != 0) + { + study = (pcre_study_data *)extra_data->study_data; + study->size = swap_uint32(study->size); + study->flags = swap_uint32(study->flags); + study->minlength = swap_uint32(study->minlength); + } -*internal_re = *re; /* To copy other fields */ -internal_re->size = byteflip(re->size, sizeof(re->size)); -internal_re->options = byteflip(re->options, sizeof(re->options)); -internal_re->flags = (pcre_uint16)byteflip(re->flags, sizeof(re->flags)); -internal_re->top_bracket = - (pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket)); -internal_re->top_backref = - (pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref)); -internal_re->first_char = - (pcre_uint16)byteflip(re->first_char, sizeof(re->first_char)); -internal_re->req_char = - (pcre_uint16)byteflip(re->req_char, sizeof(re->req_char)); -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)); +#ifndef COMPILE_PCRE8 +ptr = (pcre_uchar *)re + re->name_table_offset; +length = re->name_count * re->name_entry_size; +#ifdef SUPPORT_UTF +utf = (re->options & PCRE_UTF16) != 0; +utf16_char = FALSE; +#endif -if (study != NULL) +while(TRUE) { - *internal_study = *study; /* To copy other fields */ - internal_study->size = byteflip(study->size, sizeof(study->size)); - internal_study->flags = byteflip(study->flags, sizeof(study->flags)); - internal_study->minlength = byteflip(study->minlength, - sizeof(study->minlength)); + /* Swap previous characters. */ + while (length-- > 0) + { + *ptr = swap_uint16(*ptr); + ptr++; + } +#ifdef SUPPORT_UTF + if (utf16_char) + { + if (HAS_EXTRALEN(ptr[-1])) + { + /* We know that there is only one extra character in UTF-16. */ + *ptr = swap_uint16(*ptr); + ptr++; + } + } + utf16_char = FALSE; +#endif /* SUPPORT_UTF */ + + /* Get next opcode. */ + length = 0; + *ptr = swap_uint16(*ptr); + switch (*ptr) + { + case OP_END: + return 0; + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + utf16_char = TRUE; + length = PRIV(OP_lengths)[*ptr] - 1; + break; + + case OP_CLASS: + case OP_NCLASS: + /* Skip the character bit map. */ + ptr += 32/sizeof(pcre_uchar); + length = 0; + break; + + case OP_XCLASS: + /* Reverse the size of the XCLASS instance. */ + ptr++; + *ptr = swap_uint16(*ptr); + if (LINK_SIZE > 1) + { + /* LINK_SIZE can be 1 or 2 in 16 bit mode. */ + ptr++; + *ptr = swap_uint16(*ptr); + } + ptr++; + length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1); + *ptr = swap_uint16(*ptr); + if ((*ptr & XCL_MAP) != 0) + { + /* Skip the character bit map. */ + ptr += 32/sizeof(pcre_uchar); + length -= 32/sizeof(pcre_uchar); + } + break; + + default: + length = PRIV(OP_lengths)[*ptr] - 1; + break; + } + ptr++; } +/* Control should never reach here in 16 bit mode. */ +#endif /* !COMPILE_PCRE8 */ -return internal_re; +return 0; } -/* End of pcre_tryflipped.c */ +/* End of pcre_byte_order.c */