[Tarantool-patches] [PATCH v4 02/16] sql: fix possible undefined behavior during cast

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Tue Oct 5 00:52:18 MSK 2021


Thanks for the fixes!

On 01.10.2021 14:48, imeevma at tarantool.org wrote:
> This patch fixes possible undefined behavior during the implicit cast of
> INTEGER to DOUBLE. The problem is, if the INTEGER is close enough to
> 2^64, it will be cast to 2^64 when it is cast to DOUBLE. Since we have a
> check for loss of precision, this will cause this DOUBLE to be cast to
> an INTEGER, which will result in undefined behavior since this DOUBLE is
> outside the range of INTEGER.
> ---
>  src/box/sql/mem.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c
> index 24d6d7dbf..079083fa1 100644
> --- a/src/box/sql/mem.c
> +++ b/src/box/sql/mem.c
> @@ -682,7 +682,7 @@ uint_to_double_precise(struct Mem *mem)
>  	assert(mem->type == MEM_TYPE_UINT);
>  	double d;
>  	d = (double)mem->u.u;
> -	if (mem->u.u != (uint64_t)d)
> +	if (d == (double)UINT64_MAX || mem->u.u != (uint64_t)d)

What if uint really was UINT64_MAX? Then you treat its conversion
into UINT64_MAX double as an error?

Maybe we could simply refuse to convert all ints > 2^53 and <-2^53
(or whatever is the precise int limit in double). All ints above
these values will convert 'from time to time' depending on exact
values, which does not look reliable anyway.


More information about the Tarantool-patches mailing list