]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Prefer memcpy and memcmp over direct memory read/comparisons. (#135)
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>
Fri, 16 Feb 2018 10:49:55 +0000 (23:49 +1300)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Fri, 16 Feb 2018 10:49:55 +0000 (11:49 +0100)
* Prefer memcpy and memcmp over direct memory read/comparisons.

* Some platforms have alignment requirements and unaligned direct memory
  read/comparisons may result in undefined behaviour.
* Prefer memcpy and memcmp which are lowered to efficient assembly where
  possible.

arch/x86/insert_string_sse.c
match.c

index 8d198e973e9bf71d31ecc11ae1343932050c1c9d..a0ae9322da5d37f2f1020713cdd95678e633100f 100644 (file)
 ZLIB_INTERNAL Pos insert_string_sse(deflate_state *const s, const Pos str, unsigned int count) {
     Pos ret = 0;
     unsigned int idx;
-    unsigned *ip, val, h;
+    unsigned int *ip, val, h;
 
     for (idx = 0; idx < count; idx++) {
         ip = (unsigned *)&s->window[str+idx];
-        val = *ip;
+        memcpy(&val, ip, sizeof(val));
         h = 0;
 
         if (s->level >= TRIGGER_LEVEL)
diff --git a/match.c b/match.c
index 18874dfec22a1f9d4abc5a54c77b88568d27bf7a..a3885ccad6111204862e2f2b956571dd37cccc3a 100644 (file)
--- a/match.c
+++ b/match.c
@@ -361,8 +361,11 @@ ZLIB_INTERNAL unsigned longest_match(deflate_state *const s, IPos cur_match) {
     unsigned int wmask = s->w_mask;
 
     register unsigned char *strend = s->window + s->strstart + MAX_MATCH;
-    register uint16_t scan_start = *(uint16_t*)scan;
-    register uint16_t scan_end   = *(uint16_t*)(scan+best_len-1);
+
+    uint16_t scan_start, scan_end;
+
+    memcpy(&scan_start, scan, sizeof(scan_start));
+    memcpy(&scan_end, scan+best_len-1, sizeof(scan_end));
 
     /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
      * It is easy to get rid of this optimization if necessary.
@@ -397,7 +400,7 @@ ZLIB_INTERNAL unsigned longest_match(deflate_state *const s, IPos cur_match) {
         int cont = 1;
         do {
             match = win + cur_match;
-            if (likely(*(uint16_t*)(match+best_len-1) != scan_end)) {
+            if (likely(memcmp(match+best_len-1, &scan_end, sizeof(scan_end)) != 0)) {
                 if ((cur_match = prev[cur_match & wmask]) > limit
                     && --chain_length != 0) {
                     continue;
@@ -411,7 +414,7 @@ ZLIB_INTERNAL unsigned longest_match(deflate_state *const s, IPos cur_match) {
         if (!cont)
             break;
 
-        if (*(uint16_t*)match != scan_start)
+        if (memcmp(match, &scan_start, sizeof(scan_start)) != 0)
             continue;
 
         /* It is not necessary to compare scan[2] and match[2] since they are
@@ -426,9 +429,13 @@ ZLIB_INTERNAL unsigned longest_match(deflate_state *const s, IPos cur_match) {
         scan += 2, match+=2;
         Assert(*scan == *match, "match[2]?");
         do {
-            unsigned long sv = *(unsigned long*)(void*)scan;
-            unsigned long mv = *(unsigned long*)(void*)match;
-            unsigned long xor = sv ^ mv;
+            unsigned long sv, mv, xor;
+
+            memcpy(&sv, scan, sizeof(sv));
+            memcpy(&mv, match, sizeof(mv));
+
+            xor = sv ^ mv;
+
             if (xor) {
                 int match_byte = __builtin_ctzl(xor) / 8;
                 scan += match_byte;
@@ -452,7 +459,7 @@ ZLIB_INTERNAL unsigned longest_match(deflate_state *const s, IPos cur_match) {
             best_len = len;
             if (len >= nice_match)
                 break;
-            scan_end = *(uint16_t*)(scan+best_len-1);
+            memcpy(&scan_end, scan+best_len-1, sizeof(scan_end));
         } else {
             /*
              * The probability of finding a match later if we here