* [tarantool-patches] [PATCH] lua: fix tonumber64() for strings containing "ULL"
@ 2018-11-20 13:39 Serge Petrenko
2018-11-28 16:18 ` Vladimir Davydov
0 siblings, 1 reply; 2+ messages in thread
From: Serge Petrenko @ 2018-11-20 13:39 UTC (permalink / raw)
To: tarantool-patches; +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)
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-11-28 16:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-20 13:39 [tarantool-patches] [PATCH] lua: fix tonumber64() for strings containing "ULL" Serge Petrenko
2018-11-28 16:18 ` Vladimir Davydov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox