Revision: 194
http://www.exim.org/viewvc/pcre2?view=rev&revision=194
Author: ph10
Date: 2015-02-07 16:22:48 +0000 (Sat, 07 Feb 2015)
Log Message:
-----------
Fix alignement problem in deserialization on 64-bit SPARC.
Modified Paths:
--------------
code/trunk/src/pcre2_intmodedep.h
code/trunk/src/pcre2_serialize.c
Modified: code/trunk/src/pcre2_intmodedep.h
===================================================================
--- code/trunk/src/pcre2_intmodedep.h 2015-02-06 17:51:55 UTC (rev 193)
+++ code/trunk/src/pcre2_intmodedep.h 2015-02-07 16:22:48 UTC (rev 194)
@@ -584,14 +584,21 @@
uint32_t recursion_limit;
} pcre2_real_match_context;
-/* The real compiled code structure */
+/* The real compiled code structure. The type for the blocksize field is
+defined specially because it is required in pcre2_serialize_decode() when
+copying the size from possibly unaligned memory into a variable of the same
+type. Use a macro rather than a typedef to avoid compiler warnings when this
+file is included multiple times by pcre2test. */
+#undef CODE_BLOCKSIZE_TYPE
+#define CODE_BLOCKSIZE_TYPE size_t
+
typedef struct pcre2_real_code {
pcre2_memctl memctl; /* Memory control fields */
const uint8_t *tables; /* The character tables */
void *executable_jit; /* Pointer to JIT code */
uint8_t start_bitmap[32]; /* Bitmap for starting code unit < 256 */
- size_t blocksize; /* Total (bytes) that was malloc-ed */
+ CODE_BLOCKSIZE_TYPE blocksize; /* Total (bytes) that was malloc-ed */
uint32_t magic_number; /* Paranoid and endianness check */
uint32_t compile_options; /* Options passed to pcre2_compile() */
uint32_t overall_options; /* Options after processing the pattern */
Modified: code/trunk/src/pcre2_serialize.c
===================================================================
--- code/trunk/src/pcre2_serialize.c 2015-02-06 17:51:55 UTC (rev 193)
+++ code/trunk/src/pcre2_serialize.c 2015-02-07 16:22:48 UTC (rev 194)
@@ -150,7 +150,6 @@
&gcontext->memctl : &PRIV(default_compile_context).memctl;
const uint8_t *src_bytes;
-pcre2_real_code *src_re;
pcre2_real_code *dst_re;
uint8_t *tables;
int32_t i, j;
@@ -178,15 +177,22 @@
*(PCRE2_SIZE *)(tables + tables_length) = number_of_codes;
src_bytes += tables_length;
-/* Decode byte stream. */
+/* Decode the byte stream. We must not try to read the size from the compiled
+code block in the stream, because it might be unaligned, which causes errors on
+hardware such as Sparc-64 that doesn't like unaligned memory accesses. The type
+of the blocksize field is given its own name to ensure that it is the same here
+as in the block. */
for (i = 0; i < number_of_codes; i++)
{
- src_re = (pcre2_real_code *)src_bytes;
+ CODE_BLOCKSIZE_TYPE blocksize;
+ memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize),
+ sizeof(CODE_BLOCKSIZE_TYPE));
/* The allocator provided by gcontext replaces the original one. */
- dst_re = (pcre2_real_code *)PRIV(memctl_malloc)
- (src_re->blocksize, (pcre2_memctl *)gcontext);
+
+ dst_re = (pcre2_real_code *)PRIV(memctl_malloc)(blocksize,
+ (pcre2_memctl *)gcontext);
if (dst_re == NULL)
{
memctl->free(tables, memctl->memory_data);
@@ -199,17 +205,18 @@
}
/* The new allocator must be preserved. */
+
memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl),
- src_bytes + sizeof(pcre2_memctl),
- src_re->blocksize - sizeof(pcre2_memctl));
+ src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl));
/* At the moment only one table is supported. */
+
dst_re->tables = tables;
dst_re->executable_jit = NULL;
dst_re->flags |= PCRE2_DEREF_TABLES;
codes[i] = dst_re;
- src_bytes += src_re->blocksize;
+ src_bytes += blocksize;
}
return number_of_codes;