Signed-off-by: Christophe Fergeau <cfergeau@xxxxxxxxxx> --- server/red-parse-qxl.c | 146 +++++++++++++++++++--------------------- server/red-parse-qxl.h | 12 ++-- server/red-worker.c | 12 ++-- server/tests/test-qxl-parsing.c | 32 +++++++-- 4 files changed, 107 insertions(+), 95 deletions(-) diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c index 732eabcab..0f27b8b02 100644 --- a/server/red-parse-qxl.c +++ b/server/red-parse-qxl.c @@ -92,19 +92,18 @@ static inline uint32_t color_16_to_32(uint32_t color) static void * red_qxl_guest_resources_init(RedQXLGuestResources *guest_resources, QXLInstance *qxl_instance, RedMemSlotInfo *slots, - int group_id, - QXLPHYSICAL addr, + const QXLCommandExt *qxl_cmd, size_t size) { int error; void *red_data; - red_data = (void *)memslot_get_virt(slots, addr, size, group_id, &error); + red_data = (void *)memslot_get_virt(slots, qxl_cmd->cmd.data, size, qxl_cmd->group_id, &error); if (error) { return NULL; } guest_resources->qxl = qxl_instance; - guest_resources->release_info_ext.group_id = group_id; + guest_resources->release_info_ext.group_id = qxl_cmd->group_id; /* The 'release_info' field in QXL*Cmd is always the very first field */ guest_resources->release_info_ext.info = red_data; @@ -1040,21 +1039,21 @@ static void red_put_clip(SpiceClip *red_clip) } } -static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id, - RedDrawable *red_drawable, QXLPHYSICAL addr, uint32_t flags) +static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd, + RedDrawable *red_drawable, uint32_t flags) { QXLDrawable *qxl_drawable; int i; qxl_drawable = red_qxl_guest_resources_init(&red_drawable->guest_resources, - qxl_instance, slots, group_id, - addr, sizeof(*qxl_drawable)); + qxl_instance, slots, qxl_cmd, + sizeof(*qxl_drawable)); if (qxl_drawable == NULL) { return false; } red_get_rect_ptr(&red_drawable->bbox, &qxl_drawable->bbox); - red_get_clip_ptr(slots, group_id, &red_drawable->clip, &qxl_drawable->clip); + red_get_clip_ptr(slots, qxl_cmd->group_id, &red_drawable->clip, &qxl_drawable->clip); red_drawable->effect = qxl_drawable->effect; red_drawable->mm_time = qxl_drawable->mm_time; red_drawable->self_bitmap = qxl_drawable->self_bitmap; @@ -1069,48 +1068,48 @@ static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s red_drawable->type = qxl_drawable->type; switch (red_drawable->type) { case QXL_DRAW_ALPHA_BLEND: - red_get_alpha_blend_ptr(slots, group_id, + red_get_alpha_blend_ptr(slots, qxl_cmd->group_id, &red_drawable->u.alpha_blend, &qxl_drawable->u.alpha_blend, flags); break; case QXL_DRAW_BLACKNESS: - red_get_blackness_ptr(slots, group_id, + red_get_blackness_ptr(slots, qxl_cmd->group_id, &red_drawable->u.blackness, &qxl_drawable->u.blackness, flags); break; case QXL_DRAW_BLEND: - return red_get_blend_ptr(slots, group_id, &red_drawable->u.blend, &qxl_drawable->u.blend, flags); + return red_get_blend_ptr(slots, qxl_cmd->group_id, &red_drawable->u.blend, &qxl_drawable->u.blend, flags); case QXL_DRAW_COPY: - return red_get_copy_ptr(slots, group_id, &red_drawable->u.copy, &qxl_drawable->u.copy, flags); + return red_get_copy_ptr(slots, qxl_cmd->group_id, &red_drawable->u.copy, &qxl_drawable->u.copy, flags); case QXL_COPY_BITS: red_get_point_ptr(&red_drawable->u.copy_bits.src_pos, &qxl_drawable->u.copy_bits.src_pos); break; case QXL_DRAW_FILL: - red_get_fill_ptr(slots, group_id, &red_drawable->u.fill, &qxl_drawable->u.fill, flags); + red_get_fill_ptr(slots, qxl_cmd->group_id, &red_drawable->u.fill, &qxl_drawable->u.fill, flags); break; case QXL_DRAW_OPAQUE: - red_get_opaque_ptr(slots, group_id, &red_drawable->u.opaque, &qxl_drawable->u.opaque, flags); + red_get_opaque_ptr(slots, qxl_cmd->group_id, &red_drawable->u.opaque, &qxl_drawable->u.opaque, flags); break; case QXL_DRAW_INVERS: - red_get_invers_ptr(slots, group_id, &red_drawable->u.invers, &qxl_drawable->u.invers, flags); + red_get_invers_ptr(slots, qxl_cmd->group_id, &red_drawable->u.invers, &qxl_drawable->u.invers, flags); break; case QXL_DRAW_NOP: break; case QXL_DRAW_ROP3: - red_get_rop3_ptr(slots, group_id, &red_drawable->u.rop3, &qxl_drawable->u.rop3, flags); + red_get_rop3_ptr(slots, qxl_cmd->group_id, &red_drawable->u.rop3, &qxl_drawable->u.rop3, flags); break; case QXL_DRAW_COMPOSITE: - red_get_composite_ptr(slots, group_id, &red_drawable->u.composite, &qxl_drawable->u.composite, flags); + red_get_composite_ptr(slots, qxl_cmd->group_id, &red_drawable->u.composite, &qxl_drawable->u.composite, flags); break; case QXL_DRAW_STROKE: - return red_get_stroke_ptr(slots, group_id, &red_drawable->u.stroke, &qxl_drawable->u.stroke, flags); + return red_get_stroke_ptr(slots, qxl_cmd->group_id, &red_drawable->u.stroke, &qxl_drawable->u.stroke, flags); case QXL_DRAW_TEXT: - red_get_text_ptr(slots, group_id, &red_drawable->u.text, &qxl_drawable->u.text, flags); + red_get_text_ptr(slots, qxl_cmd->group_id, &red_drawable->u.text, &qxl_drawable->u.text, flags); break; case QXL_DRAW_TRANSPARENT: - red_get_transparent_ptr(slots, group_id, + red_get_transparent_ptr(slots, qxl_cmd->group_id, &red_drawable->u.transparent, &qxl_drawable->u.transparent, flags); break; case QXL_DRAW_WHITENESS: - red_get_whiteness_ptr(slots, group_id, + red_get_whiteness_ptr(slots, qxl_cmd->group_id, &red_drawable->u.whiteness, &qxl_drawable->u.whiteness, flags); break; default: @@ -1120,20 +1119,20 @@ static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s return true; } -static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id, - RedDrawable *red_drawable, QXLPHYSICAL addr, uint32_t flags) +static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd, + RedDrawable *red_drawable, uint32_t flags) { QXLCompatDrawable *qxl_drawable; qxl_drawable = red_qxl_guest_resources_init(&red_drawable->guest_resources, - qxl_instance, slots, group_id, - addr, sizeof(*qxl_drawable)); + qxl_instance, slots, qxl_cmd, + sizeof(*qxl_drawable)); if (qxl_drawable == NULL) { return false; } red_get_rect_ptr(&red_drawable->bbox, &qxl_drawable->bbox); - red_get_clip_ptr(slots, group_id, &red_drawable->clip, &qxl_drawable->clip); + red_get_clip_ptr(slots, qxl_cmd->group_id, &red_drawable->clip, &qxl_drawable->clip); red_drawable->effect = qxl_drawable->effect; red_drawable->mm_time = qxl_drawable->mm_time; @@ -1147,17 +1146,17 @@ static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s red_drawable->type = qxl_drawable->type; switch (red_drawable->type) { case QXL_DRAW_ALPHA_BLEND: - red_get_alpha_blend_ptr_compat(slots, group_id, + red_get_alpha_blend_ptr_compat(slots, qxl_cmd->group_id, &red_drawable->u.alpha_blend, &qxl_drawable->u.alpha_blend, flags); break; case QXL_DRAW_BLACKNESS: - red_get_blackness_ptr(slots, group_id, + red_get_blackness_ptr(slots, qxl_cmd->group_id, &red_drawable->u.blackness, &qxl_drawable->u.blackness, flags); break; case QXL_DRAW_BLEND: - return red_get_blend_ptr(slots, group_id, &red_drawable->u.blend, &qxl_drawable->u.blend, flags); + return red_get_blend_ptr(slots, qxl_cmd->group_id, &red_drawable->u.blend, &qxl_drawable->u.blend, flags); case QXL_DRAW_COPY: - return red_get_copy_ptr(slots, group_id, &red_drawable->u.copy, &qxl_drawable->u.copy, flags); + return red_get_copy_ptr(slots, qxl_cmd->group_id, &red_drawable->u.copy, &qxl_drawable->u.copy, flags); case QXL_COPY_BITS: red_get_point_ptr(&red_drawable->u.copy_bits.src_pos, &qxl_drawable->u.copy_bits.src_pos); red_drawable->surface_deps[0] = 0; @@ -1169,30 +1168,30 @@ static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s (red_drawable->bbox.bottom - red_drawable->bbox.top); break; case QXL_DRAW_FILL: - red_get_fill_ptr(slots, group_id, &red_drawable->u.fill, &qxl_drawable->u.fill, flags); + red_get_fill_ptr(slots, qxl_cmd->group_id, &red_drawable->u.fill, &qxl_drawable->u.fill, flags); break; case QXL_DRAW_OPAQUE: - red_get_opaque_ptr(slots, group_id, &red_drawable->u.opaque, &qxl_drawable->u.opaque, flags); + red_get_opaque_ptr(slots, qxl_cmd->group_id, &red_drawable->u.opaque, &qxl_drawable->u.opaque, flags); break; case QXL_DRAW_INVERS: - red_get_invers_ptr(slots, group_id, &red_drawable->u.invers, &qxl_drawable->u.invers, flags); + red_get_invers_ptr(slots, qxl_cmd->group_id, &red_drawable->u.invers, &qxl_drawable->u.invers, flags); break; case QXL_DRAW_NOP: break; case QXL_DRAW_ROP3: - red_get_rop3_ptr(slots, group_id, &red_drawable->u.rop3, &qxl_drawable->u.rop3, flags); + red_get_rop3_ptr(slots, qxl_cmd->group_id, &red_drawable->u.rop3, &qxl_drawable->u.rop3, flags); break; case QXL_DRAW_STROKE: - return red_get_stroke_ptr(slots, group_id, &red_drawable->u.stroke, &qxl_drawable->u.stroke, flags); + return red_get_stroke_ptr(slots, qxl_cmd->group_id, &red_drawable->u.stroke, &qxl_drawable->u.stroke, flags); case QXL_DRAW_TEXT: - red_get_text_ptr(slots, group_id, &red_drawable->u.text, &qxl_drawable->u.text, flags); + red_get_text_ptr(slots, qxl_cmd->group_id, &red_drawable->u.text, &qxl_drawable->u.text, flags); break; case QXL_DRAW_TRANSPARENT: - red_get_transparent_ptr(slots, group_id, + red_get_transparent_ptr(slots, qxl_cmd->group_id, &red_drawable->u.transparent, &qxl_drawable->u.transparent, flags); break; case QXL_DRAW_WHITENESS: - red_get_whiteness_ptr(slots, group_id, + red_get_whiteness_ptr(slots, qxl_cmd->group_id, &red_drawable->u.whiteness, &qxl_drawable->u.whiteness, flags); break; default: @@ -1202,15 +1201,15 @@ static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s return true; } -static bool red_get_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id, - RedDrawable *red_drawable, QXLPHYSICAL addr, uint32_t flags) +static bool red_get_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd, + RedDrawable *red_drawable, uint32_t flags) { bool ret; if (flags & QXL_COMMAND_FLAG_COMPAT) { - ret = red_get_compat_drawable(qxl_instance, slots, group_id, red_drawable, addr, flags); + ret = red_get_compat_drawable(qxl_instance, slots, qxl_cmd, red_drawable, flags); } else { - ret = red_get_native_drawable(qxl_instance, slots, group_id, red_drawable, addr, flags); + ret = red_get_native_drawable(qxl_instance, slots, qxl_cmd, red_drawable, flags); } return ret; } @@ -1265,14 +1264,14 @@ static void red_put_drawable(RedDrawable *red_drawable) red_qxl_guest_resources_release(&red_drawable->guest_resources); } -static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id, - RedUpdateCmd *red_cmd, QXLPHYSICAL addr) +static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, + const QXLCommandExt *qxl_cmd_ext, RedUpdateCmd *red_cmd) { QXLUpdateCmd *qxl_cmd; qxl_cmd = red_qxl_guest_resources_init(&red_cmd->guest_resources, - qxl_instance, slots, group_id, - addr, sizeof(*qxl_cmd)); + qxl_instance, slots, qxl_cmd_ext, + sizeof(*qxl_cmd)); if (qxl_cmd == NULL) { return false; } @@ -1288,7 +1287,7 @@ static void red_put_update_cmd(RedUpdateCmd *red_cmd) red_qxl_guest_resources_release(&red_cmd->guest_resources); } -RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr) +RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd_ext) { RedUpdateCmd *cmd; @@ -1296,7 +1295,7 @@ RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int gr cmd->refs = 1; - if (!red_get_update_cmd(qxl, slots, group_id, cmd, addr)) { + if (!red_get_update_cmd(qxl, slots, qxl_cmd_ext, cmd)) { red_update_cmd_unref(cmd); return NULL; } @@ -1319,8 +1318,8 @@ void red_update_cmd_unref(RedUpdateCmd *cmd) g_free(cmd); } -static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id, - RedMessage *red_message, QXLPHYSICAL addr) +static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, + const QXLCommandExt *qxl_cmd, RedMessage *red_message) { QXLMessage *qxl_message; int memslot_id; @@ -1335,14 +1334,14 @@ static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, in */ //qxl_message = (QXLMessage *)memslot_get_virt(slots, addr, sizeof(*qxl_message), group_id, &error); qxl_message = red_qxl_guest_resources_init(&red_message->guest_resources, - qxl_instance, slots, group_id, - addr, sizeof(*qxl_message)); + qxl_instance, slots, qxl_cmd, + sizeof(*qxl_message)); if (qxl_message == NULL) { return false; } red_message->data = qxl_message->data; - memslot_id = memslot_get_id(slots, addr+sizeof(*qxl_message)); - len = memslot_max_size_virt(slots, ((intptr_t) qxl_message)+sizeof(*qxl_message), memslot_id, group_id); + memslot_id = memslot_get_id(slots, qxl_cmd->cmd.data+sizeof(*qxl_message)); + len = memslot_max_size_virt(slots, ((intptr_t) qxl_message)+sizeof(*qxl_message), memslot_id, qxl_cmd->group_id); len = MIN(len, 100000); end = (uint8_t *)memchr(qxl_message->data, 0, len); if (end == NULL) { @@ -1357,7 +1356,7 @@ static void red_put_message(RedMessage *red_message) red_qxl_guest_resources_release(&red_message->guest_resources); } -RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr) +RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd) { RedMessage *message; @@ -1365,7 +1364,7 @@ RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_i message->refs = 1; - if (!red_get_message(qxl, slots, group_id, message, addr)) { + if (!red_get_message(qxl, slots, qxl_cmd, message)) { red_message_unref(message); return NULL; } @@ -1434,17 +1433,16 @@ bool red_validate_surface(uint32_t width, uint32_t height, return true; } -static bool red_get_surface_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id, - RedSurfaceCmd *red_cmd, QXLPHYSICAL addr) - +static bool red_get_surface_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, + const QXLCommandExt *qxl_cmd_ext, RedSurfaceCmd *red_cmd) { QXLSurfaceCmd *qxl_cmd; uint64_t size; int error; qxl_cmd = red_qxl_guest_resources_init(&red_cmd->guest_resources, - qxl_instance, slots, group_id, - addr, sizeof(*qxl_cmd)); + qxl_instance, slots, qxl_cmd_ext, + sizeof(*qxl_cmd)); if (qxl_cmd == NULL) { return false; } @@ -1467,7 +1465,7 @@ static bool red_get_surface_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots size = red_cmd->u.surface_create.height * abs(red_cmd->u.surface_create.stride); red_cmd->u.surface_create.data = - (uint8_t*)memslot_get_virt(slots, qxl_cmd->u.surface_create.data, size, group_id, &error); + (uint8_t*)memslot_get_virt(slots, qxl_cmd->u.surface_create.data, size, qxl_cmd_ext->group_id, &error); if (error) { return false; } @@ -1482,7 +1480,7 @@ static void red_put_surface_cmd(RedSurfaceCmd *red_cmd) } RedSurfaceCmd *red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots, - int group_id, QXLPHYSICAL addr) + const QXLCommandExt *qxl_cmd_ext) { RedSurfaceCmd *cmd; @@ -1490,7 +1488,7 @@ RedSurfaceCmd *red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *sl cmd->refs = 1; - if (!red_get_surface_cmd(qxl_instance, slots, group_id, cmd, addr)) { + if (!red_get_surface_cmd(qxl_instance, slots, qxl_cmd_ext, cmd)) { red_surface_cmd_unref(cmd); return NULL; } @@ -1560,14 +1558,13 @@ static void red_put_cursor(SpiceCursor *red_cmd) } static bool red_get_cursor_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, - int group_id, RedCursorCmd *red_cmd, - QXLPHYSICAL addr) + const QXLCommandExt *qxl_cmd_ext, RedCursorCmd *red_cmd) { QXLCursorCmd *qxl_cmd; qxl_cmd = red_qxl_guest_resources_init(&red_cmd->guest_resources, - qxl_instance, slots, group_id, - addr, sizeof(*qxl_cmd)); + qxl_instance, slots, qxl_cmd_ext, + sizeof(*qxl_cmd)); if (qxl_cmd == NULL) { return false; } @@ -1577,7 +1574,7 @@ static bool red_get_cursor_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, case QXL_CURSOR_SET: red_get_point16_ptr(&red_cmd->u.set.position, &qxl_cmd->u.set.position); red_cmd->u.set.visible = qxl_cmd->u.set.visible; - return red_get_cursor(slots, group_id, &red_cmd->u.set.shape, qxl_cmd->u.set.shape); + return red_get_cursor(slots, qxl_cmd_ext->group_id, &red_cmd->u.set.shape, qxl_cmd->u.set.shape); case QXL_CURSOR_MOVE: red_get_point16_ptr(&red_cmd->u.position, &qxl_cmd->u.position); break; @@ -1590,7 +1587,7 @@ static bool red_get_cursor_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, } RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots, - int group_id, QXLPHYSICAL addr) + const QXLCommandExt *qxl_cmd) { RedCursorCmd *cmd; @@ -1598,7 +1595,7 @@ RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slot cmd->refs = 1; - if (!red_get_cursor_cmd(qxl_instance, slots, group_id, cmd, addr)) { + if (!red_get_cursor_cmd(qxl_instance, slots, qxl_cmd, cmd)) { red_cursor_cmd_unref(cmd); return NULL; } @@ -1647,14 +1644,13 @@ void red_drawable_unref(RedDrawable *red_drawable) } RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots, - int group_id, QXLPHYSICAL addr, - uint32_t flags) + const QXLCommandExt *qxl_cmd, uint32_t flags) { RedDrawable *red = g_new0(RedDrawable, 1); red->refs = 1; - if (!red_get_drawable(qxl, slots, group_id, red, addr, flags)) { + if (!red_get_drawable(qxl, slots, qxl_cmd, red, flags)) { red_drawable_unref(red); return NULL; } diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h index 2f6af584d..624669470 100644 --- a/server/red-parse-qxl.h +++ b/server/red-parse-qxl.h @@ -118,16 +118,15 @@ typedef struct RedCursorCmd { void red_get_rect_ptr(SpiceRect *red, const QXLRect *qxl); RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots, - int group_id, QXLPHYSICAL addr, - uint32_t flags); + const QXLCommandExt *qxl_cmd_ext, uint32_t flags); RedDrawable *red_drawable_ref(RedDrawable *drawable); void red_drawable_unref(RedDrawable *red_drawable); -RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr); +RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd_ext); RedUpdateCmd *red_update_cmd_ref(RedUpdateCmd *red); void red_update_cmd_unref(RedUpdateCmd *red); -RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr); +RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd); RedMessage *red_message_ref(RedMessage *red); void red_message_unref(RedMessage *red); @@ -135,12 +134,11 @@ bool red_validate_surface(uint32_t width, uint32_t height, int32_t stride, uint32_t format); RedSurfaceCmd *red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots, - int group_id, QXLPHYSICAL addr); + const QXLCommandExt *qxl_cmd_ext); RedSurfaceCmd *red_surface_cmd_ref(RedSurfaceCmd *cmd); void red_surface_cmd_unref(RedSurfaceCmd *cmd); -RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, - int group_id, QXLPHYSICAL addr); +RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd_ext); RedCursorCmd *red_cursor_cmd_ref(RedCursorCmd *cmd); void red_cursor_cmd_unref(RedCursorCmd *cmd); diff --git a/server/red-worker.c b/server/red-worker.c index b0273eee1..1a3416d55 100644 --- a/server/red-worker.c +++ b/server/red-worker.c @@ -103,8 +103,7 @@ static gboolean red_process_cursor_cmd(RedWorker *worker, const QXLCommandExt *e { RedCursorCmd *cursor_cmd; - cursor_cmd = red_cursor_cmd_new(worker->qxl, &worker->mem_slots, - ext->group_id, ext->cmd.data); + cursor_cmd = red_cursor_cmd_new(worker->qxl, &worker->mem_slots, ext); if (cursor_cmd == NULL) { return FALSE; } @@ -161,7 +160,7 @@ static gboolean red_process_surface_cmd(RedWorker *worker, QXLCommandExt *ext, g { RedSurfaceCmd *surface_cmd; - surface_cmd = red_surface_cmd_new(worker->qxl, &worker->mem_slots, ext->group_id, ext->cmd.data); + surface_cmd = red_surface_cmd_new(worker->qxl, &worker->mem_slots, ext); if (surface_cmd == NULL) { return false; } @@ -209,8 +208,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty) case QXL_CMD_DRAW: { RedDrawable *red_drawable; red_drawable = red_drawable_new(worker->qxl, &worker->mem_slots, - ext_cmd.group_id, ext_cmd.cmd.data, - ext_cmd.flags); // returns with 1 ref + &ext_cmd, ext_cmd.flags); // returns with 1 ref if (red_drawable != NULL) { display_channel_process_draw(worker->display_channel, red_drawable, @@ -222,7 +220,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty) case QXL_CMD_UPDATE: { RedUpdateCmd *update; - update = red_update_cmd_new(worker->qxl, &worker->mem_slots, ext_cmd.group_id, ext_cmd.cmd.data); + update = red_update_cmd_new(worker->qxl, &worker->mem_slots, &ext_cmd); if (update == NULL) { break; } @@ -238,7 +236,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty) case QXL_CMD_MESSAGE: { RedMessage *message; - message = red_message_new(worker->qxl, &worker->mem_slots, ext_cmd.group_id, ext_cmd.cmd.data); + message = red_message_new(worker->qxl, &worker->mem_slots, &ext_cmd); if (message == NULL) { break; } diff --git a/server/tests/test-qxl-parsing.c b/server/tests/test-qxl-parsing.c index f244379bc..22136a6c9 100644 --- a/server/tests/test-qxl-parsing.c +++ b/server/tests/test-qxl-parsing.c @@ -90,12 +90,15 @@ static void test_no_issues(void) RedMemSlotInfo mem_info; RedSurfaceCmd *cmd; QXLSurfaceCmd qxl; + QXLCommandExt cmd_ext = { 0, }; init_meminfo(&mem_info); init_qxl_surface(&qxl); /* try to create a surface with no issues, should succeed */ - cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl)); + cmd_ext.group_id = 0; + cmd_ext.cmd.data = to_physical(&qxl); + cmd = red_surface_cmd_new(NULL, &mem_info, &cmd_ext); g_assert_nonnull(cmd); red_surface_cmd_unref(cmd); @@ -108,6 +111,7 @@ static void test_stride_too_small(void) RedMemSlotInfo mem_info; RedSurfaceCmd *cmd; QXLSurfaceCmd qxl; + QXLCommandExt cmd_ext = { 0, }; init_meminfo(&mem_info); init_qxl_surface(&qxl); @@ -117,7 +121,9 @@ static void test_stride_too_small(void) * This can be used to cause buffer overflows so refuse it. */ qxl.u.surface_create.stride = 256; - cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl)); + cmd_ext.group_id = 0; + cmd_ext.cmd.data = to_physical(&qxl); + cmd = red_surface_cmd_new(NULL, &mem_info, &cmd_ext); g_assert_null(cmd); deinit_qxl_surface(&qxl); @@ -129,6 +135,7 @@ static void test_too_big_image(void) RedMemSlotInfo mem_info; RedSurfaceCmd *cmd; QXLSurfaceCmd qxl; + QXLCommandExt cmd_ext = { 0, }; init_meminfo(&mem_info); init_qxl_surface(&qxl); @@ -143,7 +150,9 @@ static void test_too_big_image(void) qxl.u.surface_create.stride = 0x08000004 * 4; qxl.u.surface_create.width = 0x08000004; qxl.u.surface_create.height = 0x40000020; - cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl)); + cmd_ext.group_id = 0; + cmd_ext.cmd.data = to_physical(&qxl); + cmd = red_surface_cmd_new(NULL, &mem_info, &cmd_ext); g_assert_null(cmd); deinit_qxl_surface(&qxl); @@ -156,6 +165,7 @@ static void test_cursor_command(void) RedCursorCmd *red_cursor_cmd; QXLCursorCmd cursor_cmd; QXLCursor *cursor; + QXLCommandExt cmd_ext = { 0, }; init_meminfo(&mem_info); @@ -171,7 +181,9 @@ static void test_cursor_command(void) cursor_cmd.u.set.shape = to_physical(cursor); - red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd)); + cmd_ext.group_id = 0; + cmd_ext.cmd.data = to_physical(&cursor_cmd); + red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, &cmd_ext); g_assert_true(red_cursor_cmd != NULL); red_cursor_cmd_unref(red_cursor_cmd); g_free(cursor); @@ -185,6 +197,7 @@ static void test_circular_empty_chunks(void) QXLCursorCmd cursor_cmd; QXLCursor *cursor; QXLDataChunk *chunks[2]; + QXLCommandExt cmd_ext = { 0, }; init_meminfo(&mem_info); g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, @@ -205,7 +218,9 @@ static void test_circular_empty_chunks(void) cursor_cmd.u.set.shape = to_physical(cursor); - red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd)); + cmd_ext.group_id = 0; + cmd_ext.cmd.data = to_physical(&cursor_cmd); + red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, &cmd_ext); if (red_cursor_cmd != NULL) { /* function does not return errors so there should be no data */ g_assert_cmpuint(red_cursor_cmd->type, ==, QXL_CURSOR_SET); @@ -228,11 +243,14 @@ static void test_circular_small_chunks(void) QXLCursorCmd cursor_cmd; QXLCursor *cursor; QXLDataChunk *chunks[2]; + QXLCommandExt cmd_ext; init_meminfo(&mem_info); g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*red_get_data_chunks_ptr: data split in too many chunks, avoiding DoS*"); + memset(&cmd_ext, 0, sizeof(cmd_ext)); + /* a circular list of small chunks should not be a problems */ memset(&cursor_cmd, 0, sizeof(cursor_cmd)); cursor_cmd.type = QXL_CURSOR_SET; @@ -248,7 +266,9 @@ static void test_circular_small_chunks(void) cursor_cmd.u.set.shape = to_physical(cursor); - red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd)); + cmd_ext.group_id = 0; + cmd_ext.cmd.data = to_physical(&cursor_cmd); + red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, &cmd_ext); if (red_cursor_cmd != NULL) { /* function does not return errors so there should be no data */ g_assert_cmpuint(red_cursor_cmd->type, ==, QXL_CURSOR_SET); -- 2.14.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel