From f86fa9d483f4d5066a1ce14050f7395d2a1c8811 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Mon, 12 Oct 2020 19:00:54 +0800 Subject: [PATCH] fix bugs in ServerGetWinZNodeRegion: must check for possible empty mask rect; bad assignment of maskrect --- src/kernel/desktop-procs.c | 40 +++++++++++++++++++++++--------------- src/kernel/desktop.c | 12 +++++++----- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/kernel/desktop-procs.c b/src/kernel/desktop-procs.c index 149ea407..c4b67be2 100644 --- a/src/kernel/desktop-procs.c +++ b/src/kernel/desktop-procs.c @@ -1356,6 +1356,10 @@ intptr_t __mg_do_zorder_maskrect_operation (int cli, get_layer_from_client (cli), info->idx_znode, &rc_org_bound); #endif } + else { + _ERR_PRINTF("KERNEL: failed in __mg_do_zorder_maskrect_operation\n"); + } + return ret; } @@ -4536,7 +4540,7 @@ BOOL GUIAPI ServerGetWinZNodeRegion (MG_Layer* layer, int idx_znode, DWORD rgn_ops, CLIPRGN* dst_rgn) { RECT rc; - MASKRECT *maskrect; + MASKRECT *firstmaskrect = NULL, *maskrect; ZORDERNODE* nodes; ZORDERINFO* zi; int idx, nr_mask_rects; @@ -4568,28 +4572,32 @@ BOOL GUIAPI ServerGetWinZNodeRegion (MG_Layer* layer, int idx_znode, nr_mask_rects = 0; nodes = GET_ZORDERNODE(zi); - maskrect = GET_MASKRECT(zi); + firstmaskrect = GET_MASKRECT(zi); idx = nodes [idx_znode].idx_mask_rect; + while (idx) { + maskrect = firstmaskrect + idx; rc.left = maskrect->left; rc.top = maskrect->top; - rc.right = maskrect->left; + rc.right = maskrect->right; rc.bottom = maskrect->bottom; - if (rgn_ops & RGN_OP_FLAG_ABS) { - OffsetRect (&rc, nodes[idx_znode].rc.left, nodes[idx_znode].rc.top); - } - - if ((rgn_ops & RGN_OP_MASK) == RGN_OP_EXCLUDE) { - if (!SubtractClipRect (dst_rgn, &rc)) { - nr_mask_rects = -1; - goto __mg_err_ret; + if (!IsRectEmpty (&rc)) { + if (rgn_ops & RGN_OP_FLAG_ABS) { + OffsetRect (&rc, nodes[idx_znode].rc.left, nodes[idx_znode].rc.top); } - } - else { - if (!AddClipRect (dst_rgn, &rc)) { - nr_mask_rects = -1; - goto __mg_err_ret; + + if ((rgn_ops & RGN_OP_MASK) == RGN_OP_EXCLUDE) { + if (!SubtractClipRect (dst_rgn, &rc)) { + nr_mask_rects = -1; + goto __mg_err_ret; + } + } + else { + if (!AddClipRect (dst_rgn, &rc)) { + nr_mask_rects = -1; + goto __mg_err_ret; + } } } diff --git a/src/kernel/desktop.c b/src/kernel/desktop.c index 1fb1d86c..f79a16f0 100644 --- a/src/kernel/desktop.c +++ b/src/kernel/desktop.c @@ -2578,6 +2578,8 @@ static DWORD get_znode_flags_from_style (PMAINWIN pWin) return zt_type; } +/* TODO: this function should be optimized to avoid allocating space for + invalid (empty) mask rectangles */ static int AllocZOrderMaskRect (int cli, int idx_znode, int flags, const RECT4MASK *rc, const int nr_rc) { @@ -2599,24 +2601,24 @@ static int AllocZOrderMaskRect (int cli, int idx_znode, /*get mask rect number*/ idx = nodes[idx_znode].idx_mask_rect; - while(idx) { + while (idx) { old_num++; - idx = ((MASKRECT *)(firstmaskrect+idx))->next; + idx = ((MASKRECT *)(firstmaskrect + idx))->next; } if (nr_rc > old_num) { /* check the number of mask rect if enough */ int idle = - __mg_get_nr_idle_slots((unsigned char*)GET_MASKRECT_USAGEBMP(zi), + __mg_get_nr_idle_slots ((unsigned char*)GET_MASKRECT_USAGEBMP(zi), zi->size_maskrect_usage_bmp); - if (idle < nr_rc-old_num) { + if (idle < nr_rc - old_num) { unlock_zi_for_change (zi); return -1; } /*add new space to Znode*/ idx = nodes[idx_znode].idx_mask_rect; - for(i = 0; i < nr_rc-old_num; i++) { + for (i = 0; i < nr_rc - old_num; i++) { free_slot = __mg_lookfor_unused_slot ( (unsigned char*)GET_MASKRECT_USAGEBMP(zi), zi->size_maskrect_usage_bmp, 1);