mirror of
https://github.com/qemu/qemu.git
synced 2024-11-25 20:03:37 +08:00
cirrus_vga: fix division by 0 for color expansion rop
Commit d85d0d3883
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: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
9ae19b657e
commit
92d675d1c1
@ -675,44 +675,45 @@ 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);
|
||||
/* 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) {
|
||||
|
||||
/* 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));
|
||||
int width, height;
|
||||
|
||||
/* normalize width */
|
||||
w /= depth;
|
||||
depth = s->vga.get_bpp(&s->vga) / 8;
|
||||
s->vga.get_resolution(&s->vga, &width, &height);
|
||||
|
||||
/* 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;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* we have to flush all pending changes so that the copy
|
||||
is generated at the appropriate moment in time */
|
||||
if (notify)
|
||||
|
Loading…
Reference in New Issue
Block a user