]> wimlib.net Git - wimlib/commitdiff
{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 a24b0832e14be6b955499a621b0da710347cb833..96332dd8f40cf6066ed43d19c482d38c7c6e5408 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. */
        /* 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 "
 
        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;
        }
 
                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;
        }
 
                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,
 #if 0
        printf("Match: src %u, dst %u, len %u\n", match_src - window,
                                                match_dest - window,
index e9aec1361bee7ed61664053995e63c37d09f462f..cf08a836276f9478e20874738c55b290f6a6cb26 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. */
 
         * 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 (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;
        }
 
                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];
 
        for (i = 0; i < match_len; i++)
                match_dest[i] = match_src[i];