forked from enlightenment/efl
Evas masking: Fix potential invalid access to mask image
After clip_image_get, the old mask may be replaced by a new one, and unref'ed, but it is later on set back as the context mask image. Maybe it's possible that there was 0 reference and the image got freed in between. No idea how to test this. @fix
This commit is contained in:
parent
b6abbf1277
commit
d69f9e0b84
|
@ -1559,6 +1559,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
|
|||
e->engine.func->context_clip_unset(e->engine.data.output, context);
|
||||
e->engine.func->context_clip_image_set
|
||||
(e->engine.data.output, context, oldm_sfc, oldm_x, oldm_y, e, do_async);
|
||||
/* unref image since clip_image_get refs it */
|
||||
if (oldm_sfc) e->engine.func->image_free(e->engine.data.output, oldm_sfc);
|
||||
}
|
||||
|
||||
// FIXME: needs to cache these maps and
|
||||
|
@ -1694,6 +1696,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
|
|||
e->engine.func->context_clip_unset(e->engine.data.output, ctx);
|
||||
e->engine.func->context_clip_image_set
|
||||
(e->engine.data.output, ctx, oldm_sfc, oldm_x, oldm_y, e, do_async);
|
||||
/* unref image since clip_image_get refs it */
|
||||
if (oldm_sfc) e->engine.func->image_free(e->engine.data.output, oldm_sfc);
|
||||
}
|
||||
if (!use_mapped_ctx)
|
||||
e->engine.func->context_free(e->engine.data.output, ctx);
|
||||
|
|
|
@ -263,6 +263,9 @@ evas_filter_context_destroy(Evas_Filter_Context *ctx)
|
|||
EINA_INLIST_FREE(ctx->commands, cmd)
|
||||
_command_del(ctx, cmd);
|
||||
|
||||
if (ctx->target.mask)
|
||||
ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
|
@ -1497,6 +1500,8 @@ Eina_Bool
|
|||
evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
|
||||
void *surface, int x, int y)
|
||||
{
|
||||
void *mask = NULL;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
|
||||
|
||||
ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface);
|
||||
|
@ -1513,7 +1518,10 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
|
|||
ctx->target.color_use = EINA_FALSE;
|
||||
|
||||
ENFN->context_clip_image_get
|
||||
(ENDT, draw_context, &ctx->target.mask, &ctx->target.mask_x, &ctx->target.mask_y);
|
||||
(ENDT, draw_context, &mask, &ctx->target.mask_x, &ctx->target.mask_y);
|
||||
if (ctx->target.mask)
|
||||
ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask);
|
||||
ctx->target.mask = mask;
|
||||
|
||||
if (ctx->gl_engine)
|
||||
{
|
||||
|
|
|
@ -1268,7 +1268,7 @@ struct _Evas_Func
|
|||
void (*context_clip_set) (void *data, void *context, int x, int y, int w, int h);
|
||||
void (*context_clip_image_set) (void *data, void *context, void *surface, int x, int y, Evas_Public_Data *evas, Eina_Bool do_async);
|
||||
void (*context_clip_image_unset) (void *data, void *context);
|
||||
void (*context_clip_image_get) (void *data, void *context, void **surface, int *x, int *y);
|
||||
void (*context_clip_image_get) (void *data, void *context, void **surface, int *x, int *y); /* incref surface if not NULL */
|
||||
void (*context_clip_clip) (void *data, void *context, int x, int y, int w, int h);
|
||||
void (*context_clip_unset) (void *data, void *context);
|
||||
int (*context_clip_get) (void *data, void *context, int *x, int *y, int *w, int *h);
|
||||
|
|
|
@ -2160,7 +2160,13 @@ eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int
|
|||
{
|
||||
RGBA_Draw_Context *ctx = context;
|
||||
|
||||
if (ie) *ie = ctx->clip.mask;
|
||||
if (ie)
|
||||
{
|
||||
Evas_GL_Image *im = ctx->clip.mask;
|
||||
|
||||
*ie = im;
|
||||
if (im) evas_gl_common_image_ref(im);
|
||||
}
|
||||
if (x) *x = ctx->clip.mask_x;
|
||||
if (y) *y = ctx->clip.mask_y;
|
||||
}
|
||||
|
|
|
@ -511,7 +511,21 @@ eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int
|
|||
{
|
||||
RGBA_Draw_Context *ctx = context;
|
||||
|
||||
if (ie) *ie = ctx->clip.mask;
|
||||
if (ie)
|
||||
{
|
||||
Image_Entry *im = ctx->clip.mask;
|
||||
|
||||
*ie = im;
|
||||
if (im)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
evas_cache2_image_ref(im);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_ref(im);
|
||||
}
|
||||
}
|
||||
if (x) *x = ctx->clip.mask_x;
|
||||
if (y) *y = ctx->clip.mask_y;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue