[Pcre-svn] [194] code/trunk/src: Fix alignement problem in …

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [194] code/trunk/src: Fix alignement problem in deserialization on 64-bit SPARC.
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;