fix bugs in ServerGetWinZNodeRegion: must check for possible empty mask rect; bad assignment of maskrect

This commit is contained in:
Vincent Wei
2020-10-12 19:00:54 +08:00
parent 529c78ef90
commit f86fa9d483
2 changed files with 31 additions and 21 deletions
+24 -16
View File
@@ -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;
}
}
}
+7 -5
View File
@@ -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);