From 4eb4307aa2b847e73924aa67a055294d2533090b Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Wed, 20 Nov 2013 18:06:10 +0900 Subject: [PATCH] evas - table - protect against invalid cell/row values (16bit overflow) --- src/lib/evas/Evas_Legacy.h | 6 ++++++ src/lib/evas/canvas/evas_object_table.c | 34 ++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h index 2e6f449..f2b4b2b 100644 --- a/src/lib/evas/Evas_Legacy.h +++ b/src/lib/evas/Evas_Legacy.h @@ -7707,6 +7707,12 @@ EAPI Eina_Bool evas_object_table_pack_get(const Evas_Ob * @param row relative-vertical position to place child. * @param colspan how many relative-horizontal position to use for this child. * @param rowspan how many relative-vertical position to use for this child. + * + * Note that columns and rows only guarantee 16bit unsigned values at best. + * That means that col + colspan AND row + rowspan must fit inside 16bit + * unsigned values cleanly. You will be warned once values exceed 15bit + * storage, and attempting to use values not able to fit in 16bits will + * result in failure. * * @return 1 on success, 0 on failure. */ diff --git a/src/lib/evas/canvas/evas_object_table.c b/src/lib/evas/canvas/evas_object_table.c index 2377669..3b1f533af 100644 --- a/src/lib/evas/canvas/evas_object_table.c +++ b/src/lib/evas/canvas/evas_object_table.c @@ -650,10 +650,8 @@ _evas_object_table_calculate_hints_regular(Evas_Object *o, Evas_Object_Table_Dat _evas_object_table_cache_reset(priv); /* cache interesting data */ - memset(c->expands.h, 1, priv->size.cols); - memset(c->expands.v, 1, priv->size.rows); - memset(c->weights.h, 0, priv->size.cols); - memset(c->weights.v, 0, priv->size.rows); + memset(c->expands.h, 1, priv->size.cols * sizeof(Eina_Bool)); + memset(c->expands.v, 1, priv->size.rows * sizeof(Eina_Bool)); EINA_LIST_FOREACH(priv->children, l, opt) { Evas_Object *child = opt->obj; @@ -692,14 +690,14 @@ _evas_object_table_calculate_hints_regular(Evas_Object *o, Evas_Object_Table_Dat } if (!opt->expand_h) - memset(c->expands.h + opt->col, 0, opt->colspan); + memset(c->expands.h + opt->col, 0, opt->colspan * sizeof(Eina_Bool)); else { for (i = opt->col; i < opt->col + opt->colspan; i++) c->weights.h[i] += (weightw / (double)opt->colspan); } if (!opt->expand_v) - memset(c->expands.v + opt->row, 0, opt->rowspan); + memset(c->expands.v + opt->row, 0, opt->rowspan * sizeof(Eina_Bool)); else { for (i = opt->row; i < opt->row + opt->rowspan; i++) @@ -1173,17 +1171,35 @@ _pack(Eo *o, void *_pd, va_list *list) Evas_Object_Table_Data *priv = _pd; + if (colspan < 1) + { + ERR("colspan < 1"); + return; + } + if ((0xffff - col) < colspan) + { + ERR("col + colspan > 0xffff"); + return; + } + if ((col + colspan) >= 0x7ffff) + { + WRN("col + colspan getting rather large (>32767)"); + } if (rowspan < 1) { ERR("rowspan < 1"); return; } - if (colspan < 1) + if ((0xffff - row) < rowspan) { - ERR("colspan < 1"); + ERR("row + rowspan > 0xffff"); return; } - + if ((row + rowspan) >= 0x7ffff) + { + WRN("row + rowspan getting rather large (>32767)"); + } + opt = _evas_object_table_option_get(child); if (!opt) { -- 2.7.4