From: Serge Petrenko <sergepetrenko@tarantool.org> To: tarantool-patches@freelists.org Cc: Serge Petrenko <sergepetrenko@tarantool.org> Subject: [tarantool-patches] [PATCH] lua: fix tonumber64() for strings containing "ULL" Date: Tue, 20 Nov 2018 16:39:58 +0300 [thread overview] Message-ID: <20181120133958.61719-1-sergepetrenko@tarantool.org> (raw) 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)
next reply other threads:[~2018-11-20 13:40 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-11-20 13:39 Serge Petrenko [this message] 2018-11-28 16:18 ` Vladimir Davydov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20181120133958.61719-1-sergepetrenko@tarantool.org \ --to=sergepetrenko@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH] lua: fix tonumber64() for strings containing "ULL"' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox