From: Samuel Williams Date: Fri, 16 Feb 2018 10:49:55 +0000 (+1300) Subject: Prefer memcpy and memcmp over direct memory read/comparisons. (#135) X-Git-Tag: 1.9.9-b1~645 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72214719ca8db882ab49d31872528b8b456362aa;p=thirdparty%2Fzlib-ng.git Prefer memcpy and memcmp over direct memory read/comparisons. (#135) * 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. --- diff --git a/arch/x86/insert_string_sse.c b/arch/x86/insert_string_sse.c index 8d198e973..a0ae9322d 100644 --- a/arch/x86/insert_string_sse.c +++ b/arch/x86/insert_string_sse.c @@ -19,11 +19,11 @@ 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 18874dfec..a3885ccad 100644 --- 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