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 62E642C080 for ; Tue, 20 Nov 2018 08:40:13 -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 xKLiZEG-zROI for ; Tue, 20 Nov 2018 08:40:13 -0500 (EST) Received: from smtp41.i.mail.ru (smtp41.i.mail.ru [94.100.177.101]) (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 A110A2C05C for ; Tue, 20 Nov 2018 08:40:12 -0500 (EST) From: Serge Petrenko Subject: [tarantool-patches] [PATCH] lua: fix tonumber64() for strings containing "ULL" Date: Tue, 20 Nov 2018 16:39:58 +0300 Message-Id: <20181120133958.61719-1-sergepetrenko@tarantool.org> 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: Serge Petrenko tonumber64() doesn't understand strings with "ULL" like "123ULL". The expected output for tonumber64("123ULL") is 123, since 123ULL is a correct number notation in lua. However, our function returns null. This happens because suffix isn't trimmed in tonumber64. Trim ULL/LLU, LL suffixes, but only when no base is specified or base is equal to either 2, 10 or 16. Part of #3431 --- https://github.com/tarantool/tarantool/tree/sp/gh-3431-tonumber-with-ull https://github.com/tarantool/tarantool/issues/3431 src/lua/init.c | 29 +++++++++++++++++++++++++++-- test/box/misc.result | 19 +++++++++++++++++++ test/box/misc.test.lua | 8 ++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/lua/init.c b/src/lua/init.c index 07bcca1b9..ae5bb4ba7 100644 --- a/src/lua/init.c +++ b/src/lua/init.c @@ -199,6 +199,10 @@ lbox_tonumber64(struct lua_State *L) * 1) '0x' or '0X' trim in case of base == 16 or base == -1 * 2) '0b' or '0B' trim in case of base == 2 or base == -1 * 3) '-' for negative numbers + * 4) LL, ULL, LLU - trim, but only for base == 2 or + * base == 16 or base == -1. For consistency do not bother + * with any non-common bases, since user may have specified + * base >= 22, in which case 'L' will be a digit. */ char negative = 0; if (arg[0] == '-') { @@ -214,7 +218,26 @@ lbox_tonumber64(struct lua_State *L) base = 2; arg += 2; argl -= 2; } } - base = (base == -1 ? 10 : base); + bool ull = false; + if (argl > 2 && (base == 2 || base == 16 || base == -1)) { + if (arg[argl - 1] == 'u' || arg[argl - 1] == 'U') { + ull = true; + --argl; + } + if ((arg[argl - 1] == 'l' || arg[argl - 1] == 'L') && + (arg[argl - 2] == 'l' || arg[argl - 2] == 'L')) + argl -= 2; + else { + ull = false; + goto skip; + } + if (!ull && (arg[argl - 1] == 'u' || + arg[argl - 1] == 'U')) { + ull = true; + --argl; + } + } +skip: base = (base == -1 ? 10 : base); errno = 0; char *arge; unsigned long long result = strtoull(arg, &arge, base); @@ -231,7 +254,9 @@ lbox_tonumber64(struct lua_State *L) * Finally, * result - 1 > INT64_MAX; */ - if (result != 0 && result - 1 > INT64_MAX) + if (ull) + luaL_pushuint64(L, (UINT64_MAX - result) + 1); + else if (result != 0 && result - 1 > INT64_MAX) lua_pushnil(L); else luaL_pushint64(L, -result); diff --git a/test/box/misc.result b/test/box/misc.result index 4ee4797d0..19554b62d 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -655,6 +655,25 @@ tostring(tonumber64('0')) == '0' --- - true ... +-- +-- gh-3431: tonumber of strings with ULL. +-- +tonumber64('-1ULL') == -1ULL +--- +- true +... +tonumber64('-1LL') == -1LL +--- +- true +... +tonumber64('12345678910ULL') == 12345678910ULL +--- +- true +... +tonumber64(tostring(tonumber64('1234567890123456'))) == 1234567890123456ULL +--- +- true +... tonumber64('0x12') == 18 --- - true diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua index ee81c7be1..d799088d2 100644 --- a/test/box/misc.test.lua +++ b/test/box/misc.test.lua @@ -173,6 +173,14 @@ tostring(tonumber64('-9223372036854775808')) == '-9223372036854775808LL' tonumber64('-9223372036854775809') == nil tostring(tonumber64('0')) == '0' +-- +-- gh-3431: tonumber of strings with ULL. +-- +tonumber64('-1ULL') == -1ULL +tonumber64('-1LL') == -1LL +tonumber64('12345678910ULL') == 12345678910ULL +tonumber64(tostring(tonumber64('1234567890123456'))) == 1234567890123456ULL + tonumber64('0x12') == 18 tonumber64('0x12', 16) == 18 tonumber64('0x12', 17) == nil -- 2.17.2 (Apple Git-113)