From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 7D10F22071 for ; Wed, 20 Feb 2019 06:57:46 -0500 (EST) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vJOGcr1H_Wib for ; Wed, 20 Feb 2019 06:57:46 -0500 (EST) Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 0C38F212ED for ; Wed, 20 Feb 2019 06:57:46 -0500 (EST) From: Nikita Pettik Subject: [tarantool-patches] [PATCH 2/4] sql: raise an integer overflow error during CAST Date: Wed, 20 Feb 2019 14:57:38 +0300 Message-Id: <4d0d34db733fd778d4aa9c4128df95b5fdc917de.1550663540.git.korablev@tarantool.org> In-Reply-To: References: In-Reply-To: References: Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: tarantool-patches@freelists.org Cc: v.shpilevoy@tarantool.org, Nikita Pettik Before this patch, if integer overflow occurred during casting to integer, it was simply ignored. As a result, wrong results might take place. Lets check possible overflows before CAST conversion, and if it happens, raise an appropriate error. Part of #3735 --- src/box/sql/vdbemem.c | 4 +++- test/sql/integer-overflow.result | 16 ++++++++++++++++ test/sql/integer-overflow.test.lua | 10 ++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c index e9ace33d2..a816936f0 100644 --- a/src/box/sql/vdbemem.c +++ b/src/box/sql/vdbemem.c @@ -532,7 +532,9 @@ sqlVdbeMemIntegerify(Mem * pMem, bool is_forced) MemSetTypeFlag(pMem, MEM_Int); return 0; } else if ((pMem->flags & MEM_Real) != 0 && is_forced) { - pMem->u.i = (int) pMem->u.r; + if (pMem->u.r >= INT64_MAX || pMem->u.r < INT64_MIN) + return -1; + pMem->u.i = (int64_t) pMem->u.r; MemSetTypeFlag(pMem, MEM_Int); return 0; } diff --git a/test/sql/integer-overflow.result b/test/sql/integer-overflow.result index fedcd4290..762ebbf29 100644 --- a/test/sql/integer-overflow.result +++ b/test/sql/integer-overflow.result @@ -40,3 +40,19 @@ box.sql.execute('SELECT 9223372036854775808 - 1;') --- - error: 'oversized integer: 9223372036854775808' ... +-- Test that CAST may also leads to overflow. +-- +box.sql.execute('SELECT CAST(\'9223372036854775808\' AS INTEGER);') +--- +- error: 'Type mismatch: can not convert 9223372036854775808 to integer' +... +-- Due to inexact represantation of large integers in terms of +-- floating point numbers, numerics with value < INT64_MAX +-- have INT64_MAX + 1 value in integer representation: +-- float 9223372036854775800 -> int (9223372036854775808), +-- with error due to conversion = 8. +-- +box.sql.execute('SELECT CAST(9223372036854775807.0 AS INTEGER);') +--- +- error: 'Type mismatch: can not convert 9.22337203685478e+18 to integer' +... diff --git a/test/sql/integer-overflow.test.lua b/test/sql/integer-overflow.test.lua index 49ba5cd8f..ec7eb433e 100644 --- a/test/sql/integer-overflow.test.lua +++ b/test/sql/integer-overflow.test.lua @@ -14,3 +14,13 @@ box.sql.execute('SELECT (9223372036854775807 + 1);') box.sql.execute('SELECT 9223372036854775808;') box.sql.execute('SELECT -9223372036854775809;') box.sql.execute('SELECT 9223372036854775808 - 1;') +-- Test that CAST may also leads to overflow. +-- +box.sql.execute('SELECT CAST(\'9223372036854775808\' AS INTEGER);') +-- Due to inexact represantation of large integers in terms of +-- floating point numbers, numerics with value < INT64_MAX +-- have INT64_MAX + 1 value in integer representation: +-- float 9223372036854775800 -> int (9223372036854775808), +-- with error due to conversion = 8. +-- +box.sql.execute('SELECT CAST(9223372036854775807.0 AS INTEGER);') -- 2.15.1