提交 92d675d1 编写于 作者: A Aurelien Jarno

cirrus_vga: fix division by 0 for color expansion rop

Commit d85d0d38 introduces a regression
with Windows ME that leads to a division by 0 and a crash.

It uses the color expansion rop with the source pitch set to 0. This is
something allowed, as the manual explicitely says "When the source of
color-expand data is display memory, the source pitch is ignored.".

This patch fixes this regression by computing sx, sy and others
variables only if they are going to be used later, that is for a plain
copy ROP. It basically consists in moving code.
Signed-off-by: NAurelien Jarno <aurelien@aurel32.net>
上级 9ae19b65
......@@ -675,43 +675,44 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
{
int sx, sy;
int dx, dy;
int width, height;
int depth;
int notify = 0;
depth = s->vga.get_bpp(&s->vga) / 8;
s->vga.get_resolution(&s->vga, &width, &height);
/* extra x, y */
sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
sy = (src / ABS(s->cirrus_blt_srcpitch));
dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
dy = (dst / ABS(s->cirrus_blt_dstpitch));
/* normalize width */
w /= depth;
/* if we're doing a backward copy, we have to adjust
our x/y to be the upper left corner (instead of the lower
right corner) */
if (s->cirrus_blt_dstpitch < 0) {
sx -= (s->cirrus_blt_width / depth) - 1;
dx -= (s->cirrus_blt_width / depth) - 1;
sy -= s->cirrus_blt_height - 1;
dy -= s->cirrus_blt_height - 1;
}
/* make sure to only copy if it's a plain copy ROP */
if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src ||
*s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) {
/* are we in the visible portion of memory? */
if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
(sx + w) <= width && (sy + h) <= height &&
(dx + w) <= width && (dy + h) <= height) {
notify = 1;
}
int width, height;
depth = s->vga.get_bpp(&s->vga) / 8;
s->vga.get_resolution(&s->vga, &width, &height);
/* extra x, y */
sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
sy = (src / ABS(s->cirrus_blt_srcpitch));
dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
dy = (dst / ABS(s->cirrus_blt_dstpitch));
/* make to sure only copy if it's a plain copy ROP */
if (*s->cirrus_rop != cirrus_bitblt_rop_fwd_src &&
*s->cirrus_rop != cirrus_bitblt_rop_bkwd_src)
notify = 0;
/* normalize width */
w /= depth;
/* if we're doing a backward copy, we have to adjust
our x/y to be the upper left corner (instead of the lower
right corner) */
if (s->cirrus_blt_dstpitch < 0) {
sx -= (s->cirrus_blt_width / depth) - 1;
dx -= (s->cirrus_blt_width / depth) - 1;
sy -= s->cirrus_blt_height - 1;
dy -= s->cirrus_blt_height - 1;
}
/* are we in the visible portion of memory? */
if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
(sx + w) <= width && (sy + h) <= height &&
(dx + w) <= width && (dy + h) <= height) {
notify = 1;
}
}
/* we have to flush all pending changes so that the copy
is generated at the appropriate moment in time */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册