draw_bmp: fix overflowing coordinates in mark_rcs

This is yet another unfortunate side effect of the width % SLICE_W == 0
special case. While looping through these rectangles, the rc->x1 value
on the final loop can be greater than the actual total width. This will
cause a buffer overflow if using the mp_draw_sub_overlay API. 2 of the
current VOs that use that work around it by adjusting the values
returned, but the better fix is to correct what's actually given in the
rectangles so you can safely use the values. As for the fix, it's simply
ensuring that rc->x1 doesn't extend beyond p->w with a MPCLAMP.
Previously, the code would always naively add SLICE_W (256) to rc->x0
which would easily extend past the actual width in many cases. The
adjustments in vo_vaapi and vo_dmabuf_wayland are dropped and in theory
vo_direct3d should work now since we can just trust the values given to
us in the rectangles. How nice.
This commit is contained in:
Dudemanguy 2023-07-29 22:03:49 -05:00 committed by sfan5
parent 1608059d64
commit b7bf5e619f
3 changed files with 2 additions and 9 deletions

View File

@ -968,7 +968,8 @@ static void mark_rcs(struct mp_draw_sub_cache *p, struct rc_grid *gr)
rc->y0 = MPMIN(rc->y0, y);
rc->y1 = MPMAX(rc->y1, y + 1);
rc->x0 = MPMIN(rc->x0, xpos + s->x0);
rc->x1 = MPMAX(rc->x1, xpos + s->x1);
// Ensure this does not extend beyond the total width
rc->x1 = MPCLAMP(xpos + s->x1, rc->x1, p->w);
}
}
}

View File

@ -565,10 +565,6 @@ static bool draw_osd(struct vo *vo, struct mp_image *cur, double pts)
void *src = mp_image_pixel_ptr(osd, 0, rc.x0, rc.y0);
void *dst = cur->planes[0] + rc.x0 * 4 + rc.y0 * cur->stride[0];
// Avoid overflowing if we have this special case.
if (n == num_mod_rc - 1)
--rh;
memcpy_pic(dst, src, rw * 4, rh, cur->stride[0], osd->stride[0]);
}

View File

@ -684,10 +684,6 @@ static void draw_osd(struct vo *vo)
int rw = mp_rect_w(*rc);
int rh = mp_rect_h(*rc);
// reduce width of last slice to prevent overflow
if (n == num_mod_rc - 1)
rw = w - rc->x0;
void *src = mp_image_pixel_ptr(osd, 0, rc->x0, rc->y0);
void *dst = vaimg.planes[0] + rc->y0 * vaimg.stride[0] + rc->x0 * 4;