{lzx,xpress}_decode_match(): Fix undefined pointer evalution
authorEric Biggers <ebiggers3@gmail.com>
Fri, 1 Nov 2013 05:19:32 +0000 (00:19 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Fri, 1 Nov 2013 05:42:06 +0000 (00:42 -0500)
According to C99 6.5.6.8, calculating a pointer that points before the
allocated object has undefined behavior.  However, this was done by
lzx_decode_match() and xpress_decode_match() if they received a match
pointing before the end of the window (invalid match offset).  This
commit fixes this check to be fully defined.

This change likely has no visible effect in actual builds, e.g. with gcc.

src/lzx-decompress.c
src/xpress-decompress.c

index a24b083..96332dd 100644 (file)
@@ -656,8 +656,6 @@ lzx_decode_match(unsigned main_element, int block_type,
        /* Verify that the match is in the bounds of the part of the window
         * currently in use, then copy the source of the match to the current
         * position. */
-       match_dest = window + window_pos;
-       match_src = match_dest - match_offset;
 
        if (match_len > bytes_remaining) {
                DEBUG("lzx_decode_match(): Match of length %u bytes overflows "
@@ -665,13 +663,16 @@ lzx_decode_match(unsigned main_element, int block_type,
                return -1;
        }
 
-       if (match_src < window) {
+       if (match_offset > window_pos) {
                DEBUG("lzx_decode_match(): Match of length %u bytes references "
                      "data before window (match_offset = %u, window_pos = %u)",
                      match_len, match_offset, window_pos);
                return -1;
        }
 
+       match_dest = window + window_pos;
+       match_src = match_dest - match_offset;
+
 #if 0
        printf("Match: src %u, dst %u, len %u\n", match_src - window,
                                                match_dest - window,
index e9aec13..cf08a83 100644 (file)
@@ -143,22 +143,22 @@ xpress_decode_match(unsigned huffsym, unsigned window_pos,
         * currently in use, then copy the source of the match to the current
         * position. */
 
-       match_dest = window + window_pos;
-       match_src = match_dest - match_offset;
-
        if (window_pos + match_len > window_len) {
                DEBUG("XPRESS decompression error: match of length %u "
                      "bytes overflows window", match_len);
                return -1;
        }
 
-       if (match_src < window) {
+       if (match_offset > window_pos) {
                DEBUG("XPRESS decompression error: match of length %u bytes "
                      "references data before window (match_offset = %u, "
                      "window_pos = %u)", match_len, match_offset, window_pos);
                return -1;
        }
 
+       match_dest = window + window_pos;
+       match_src = match_dest - match_offset;
+
        for (i = 0; i < match_len; i++)
                match_dest[i] = match_src[i];