diff --git a/pl_mpeg.h b/pl_mpeg.h index b42f53f..ab99610 100755 --- a/pl_mpeg.h +++ b/pl_mpeg.h @@ -3356,8 +3356,17 @@ void plm_video_process_macroblock( unsigned int si = ((self->mb_row * block_size) + vp) * dw + (self->mb_col * block_size) + hp; unsigned int di = (self->mb_row * dw + self->mb_col) * block_size; - unsigned int max_address = (dw * (self->mb_height * block_size - block_size + 1) - block_size); - if (si > max_address || di > max_address) { + // The half-pel prediction reads s[si+1], s[si+dw] and s[si+dw+1], and the + // block loop spans block_size rows/cols, so the deepest source byte read is + // si + (block_size-1)*dw + (block_size-1) + (odd_v?dw:0) + (odd_h?1:0). + // Bound the actual deepest source AND destination offsets against the + // plane, not just the base indices si/di. + unsigned int plane_size = dw * (self->mb_height * block_size); + unsigned int max_di = di + (block_size - 1) * dw + (block_size - 1); + unsigned int max_si = si + (block_size - 1) * dw + (block_size - 1) + + (odd_v ? dw : 0) + (odd_h ? 1 : 0); + if (si >= plane_size || di >= plane_size || + max_si >= plane_size || max_di >= plane_size) { return; // corrupt video }