mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-06 03:28:00 +02:00
compositor: Validate buffer scale
We're supposed to generate an INVALID_SIZE error if the buffer size isn't an integer multiple of the scale. Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
parent
8cdf3fb709
commit
dc27dd7e95
3 changed files with 73 additions and 12 deletions
|
|
@ -4617,14 +4617,13 @@ weston_surface_is_pending_viewport_source_valid(
|
|||
if ((pend->status & WESTON_SURFACE_DIRTY_BUFFER) ||
|
||||
(pend->status & WESTON_SURFACE_DIRTY_SIZE)) {
|
||||
if (pend->buffer_ref.buffer) {
|
||||
bool size_ok;
|
||||
struct weston_buffer *buf = pend->buffer_ref.buffer;
|
||||
|
||||
convert_size_by_transform_scale(&width_from_buffer,
|
||||
&height_from_buffer,
|
||||
buf->width,
|
||||
buf->height,
|
||||
vp->buffer.transform,
|
||||
vp->buffer.scale);
|
||||
size_ok = convert_buffer_size_by_transform_scale(&width_from_buffer,
|
||||
&height_from_buffer,
|
||||
buf, vp);
|
||||
weston_assert_true(surface->compositor, size_ok);
|
||||
} else {
|
||||
/* No buffer: viewport is irrelevant. */
|
||||
return true;
|
||||
|
|
@ -4686,6 +4685,48 @@ surface_commit(struct wl_client *client, struct wl_resource *resource)
|
|||
struct weston_surface *surface = wl_resource_get_user_data(resource);
|
||||
WESTON_TRACE_FUNC_FLOW(&surface->flow_id);
|
||||
enum weston_surface_status status;
|
||||
struct weston_buffer *buffer;
|
||||
int32_t tmp_w, tmp_h;
|
||||
|
||||
buffer = surface->pending.buffer_ref.buffer;
|
||||
if (buffer &&
|
||||
!convert_buffer_size_by_transform_scale(&tmp_w, &tmp_h,
|
||||
buffer,
|
||||
&surface->pending.buffer_viewport)) {
|
||||
wl_resource_post_error(surface->resource,
|
||||
WL_SURFACE_ERROR_INVALID_SIZE,
|
||||
"surface size (%dx%d) was not an integer multiple of scale (%d)",
|
||||
buffer->width, buffer->height,
|
||||
surface->pending.buffer_viewport.buffer.scale);
|
||||
return;
|
||||
}
|
||||
/* If there is no pending buffer, we could be trying to use new
|
||||
* scale with an old buffer, so test surface->*_from_buffer against
|
||||
* pending scale. The stored width/height have already been divided
|
||||
* by the current scale, so multiply that back in before testing
|
||||
* against the pending scale. We might actually be confusing width
|
||||
* and height here, as we're losing transform information, but that
|
||||
* has no impact on the test.
|
||||
*
|
||||
* If we've never had a buffer, we'll be testing 0 dimensions, which
|
||||
* will just magically look ok.
|
||||
*/
|
||||
if (!buffer) {
|
||||
int32_t old_buffer_width = surface->width_from_buffer *
|
||||
surface->buffer_viewport.buffer.scale;
|
||||
int32_t old_buffer_height = surface->height_from_buffer *
|
||||
surface->buffer_viewport.buffer.scale;
|
||||
|
||||
if (old_buffer_width % surface->pending.buffer_viewport.buffer.scale ||
|
||||
old_buffer_height % surface->pending.buffer_viewport.buffer.scale) {
|
||||
wl_resource_post_error(surface->resource,
|
||||
WL_SURFACE_ERROR_INVALID_SIZE,
|
||||
"surface size (%dx%d) was not an integer multiple of scale (%d)",
|
||||
surface->width_from_buffer, surface->height_from_buffer,
|
||||
surface->pending.buffer_viewport.buffer.scale);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!weston_surface_is_pending_viewport_source_valid(surface)) {
|
||||
assert(surface->viewport_resource);
|
||||
|
|
|
|||
|
|
@ -805,6 +805,26 @@ convert_size_by_transform_scale(int32_t *width_out, int32_t *height_out,
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
convert_buffer_size_by_transform_scale(int32_t *width_out, int32_t *height_out,
|
||||
const struct weston_buffer *buf,
|
||||
const struct weston_buffer_viewport *vp)
|
||||
{
|
||||
/* Buffer dimensions must be integer multiples of the scale */
|
||||
if (buf->width % vp->buffer.scale ||
|
||||
buf->height % vp->buffer.scale)
|
||||
return false;
|
||||
|
||||
convert_size_by_transform_scale(width_out, height_out,
|
||||
buf->width, buf->height,
|
||||
vp->buffer.transform,
|
||||
vp->buffer.scale);
|
||||
if (*width_out == 0 || *height_out == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* User authentication for remote backends */
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "backend.h"
|
||||
#include "pixel-formats.h"
|
||||
#include "shared/fd-util.h"
|
||||
#include "shared/weston-assert.h"
|
||||
#include "timeline.h"
|
||||
#include "weston-trace.h"
|
||||
|
||||
|
|
@ -148,13 +149,12 @@ weston_surface_attach(struct weston_surface *surface,
|
|||
struct weston_buffer_viewport *vp = &state->buffer_viewport;
|
||||
int32_t old_width = surface->width_from_buffer;
|
||||
int32_t old_height = surface->height_from_buffer;
|
||||
bool size_ok;
|
||||
|
||||
convert_size_by_transform_scale(&surface->width_from_buffer,
|
||||
&surface->height_from_buffer,
|
||||
buffer->width,
|
||||
buffer->height,
|
||||
vp->buffer.transform,
|
||||
vp->buffer.scale);
|
||||
size_ok = convert_buffer_size_by_transform_scale(&surface->width_from_buffer,
|
||||
&surface->height_from_buffer,
|
||||
buffer, vp);
|
||||
weston_assert_true(surface->compositor, size_ok);
|
||||
|
||||
if (surface->width_from_buffer != old_width ||
|
||||
surface->height_from_buffer != old_height) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue