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.
/* 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 "
- 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,
* 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];