From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 480966ECE3; Tue, 21 Jun 2022 14:26:01 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 480966ECE3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1655810761; bh=M7xx4TlRbPejprSvRa6OXquVV3MxI3wn2MPcNv+Qzl4=; h=In-Reply-To:Date:References:To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=e16vMdRe/92e6v1hjdZpQMMHf2YTA+MrCSG6Gwy6fXiEVaRUtw0p7h/bD8aMtnaqI An2ToYruXM6HkG+reFTcv/+ZiCUbYrAJxFQ+FohBmGqIuZLPt4EU36ZBbCec+WRMYX /bvOc3bLeVO1UfunujEgEAMXDaV4L89nbtXtCdnQ= Received: from smtp40.i.mail.ru (smtp40.i.mail.ru [94.100.177.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 76DB86ECE3 for ; Tue, 21 Jun 2022 14:25:59 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 76DB86ECE3 Received: by smtp40.i.mail.ru with esmtpa (envelope-from ) id 1o3c18-0003bM-Po; Tue, 21 Jun 2022 14:25:59 +0300 Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.100.31\)) In-Reply-To: <20211227134237.2942-1-skaplun@tarantool.org> Date: Tue, 21 Jun 2022 14:25:57 +0300 Content-Transfer-Encoding: quoted-printable Message-Id: <02413F18-7955-4D3A-B201-33F177EC68CF@tarantool.org> References: <20211227134237.2942-1-skaplun@tarantool.org> To: Sergey Kaplun X-Mailer: Apple Mail (2.3696.100.31) X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9B458E015651D1EC05F221EC801A65467F3D6C3AFFE8C7635182A05F538085040A48DC9A6045D6116FBFB56C5455761005F23600130EF72F1F6ED019828CE5BF6 X-8FC586DF: 6EFBBC1D9D64D975 X-C1DE0DAB: 9604B64F49C60606AD91A466A1DEF99B296C473AB1E14218399AE6868A3836897866D6147AF826D8AD89E3F9259909E9D9D7399830F157F0F972CCD2F8FE1EF1CFC4036BBF6A4EA9B11811A4A51E3B0915E2725BA614EAEA1EF972C1F679AE1C X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D3473688ED311681BF02313F5588DE53B75F74885C7EB065BE239860276427D50678299F4AE8332C5511D7E09C32AA3244CC8B2C3E92E0449D591932C453E7537ECC3B3ADDA61883BB5FACE5A9C96DEB163 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2bioj+ZQCdndr4HmAYcJh1T+ilg== X-Mailru-Sender: 11C2EC085EDE56FA38FD4C59F7EFE407E5485F44C1DCD0A8BBCF5383059F1FDA21A452A5DC2D61BF19381EE24192DF5555834048F03EF5D4C9A814A92B2E3B1BA4250FC3964EA4964198E0F3ECE9B5443453F38A29522196 X-Mras: OK Subject: Re: [Tarantool-patches] [PATCH luajit] Give expected results for negative non-base-10 numbers in tonumber(). X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: sergos via Tarantool-patches Reply-To: sergos Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Hi! Thanks for the patch! LGTM Sergos > On 27 Dec 2021, at 16:42, Sergey Kaplun wrote: >=20 > From: Mike Pall >=20 > This was undefined in Lua 5.1, but it's defined in 5.2. >=20 > (cherry picked from f3cf0d6e15240098147437fed7bd436ff55fdf8c) >=20 > `strtoul()` considers negative values as a valid input and silently > converts them to the equivalent unsigned long value. As a result = yielded > value is unexpected to the user. >=20 I believe a missing point here is =E2=80=98equivalent=E2=80=99 become an = =E2=80=98unexpected=E2=80=99 after being converted into a number - namely, floating point.=20 > This patch adds reading of a sign (if exists) from argument and = provide > the remaining part of the string as is if it starts with a digit or > alphabetical symbol to be consistent with Lua 5.2. >=20 > Sergey Kaplun: > * added the description and the test for the problem >=20 > Part of tarantool/tarantool#6548 > --- >=20 > Issue: https://github.com/tarantool/tarantool/issues/6548 > Branch: = https://github.com/tarantool/luajit/tree/skaplun/gh-noticket-tonumber-expe= cted-results-full-ci > Tarantool branch: = https://github.com/tarantool/tarantool/tree/skaplun/gh-noticket-tonumber-e= xpected-results-full-ci >=20 > CI is red due to integration tests failes (same as on master) or due = to > connection errors. >=20 > Side note: I suppose that undefinence Mike talking about is the > following lines in the Lua 5.1 Reference manual [1]: >=20 > | In base 10 (the default), the number can have a decimal part, as = well > | as an optional exponent part (see paragraph 2.1). In other bases, = only > | unsigned integers are accepted. >=20 > In the Lua 5.2 Reference manual [2] they are deleted. >=20 > src/lib_base.c | 27 +++++++++++------ > ...onumber-negative-non-decimal-base.test.lua | 29 +++++++++++++++++++ > 2 files changed, 47 insertions(+), 9 deletions(-) > create mode 100644 = test/tarantool-tests/tonumber-negative-non-decimal-base.test.lua >=20 > diff --git a/src/lib_base.c b/src/lib_base.c > index 3a757870..d61e8762 100644 > --- a/src/lib_base.c > +++ b/src/lib_base.c > @@ -287,18 +287,27 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) > } else { > const char *p =3D strdata(lj_lib_checkstr(L, 1)); > char *ep; > + unsigned int neg =3D 0; > unsigned long ul; > if (base < 2 || base > 36) > lj_err_arg(L, 2, LJ_ERR_BASERNG); > - ul =3D strtoul(p, &ep, base); > - if (p !=3D ep) { > - while (lj_char_isspace((unsigned char)(*ep))) ep++; > - if (*ep =3D=3D '\0') { > - if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u)) > - setintV(L->base-1-LJ_FR2, (int32_t)ul); > - else > - setnumV(L->base-1-LJ_FR2, (lua_Number)ul); > - return FFH_RES(1); > + while (lj_char_isspace((unsigned char)(*p))) p++; > + if (*p =3D=3D '-') { p++; neg =3D 1; } else if (*p =3D=3D '+') { = p++; } > + if (lj_char_isalnum((unsigned char)(*p))) { > + ul =3D strtoul(p, &ep, base); > + if (p !=3D ep) { > + while (lj_char_isspace((unsigned char)(*ep))) ep++; > + if (*ep =3D=3D '\0') { > + if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) { > + if (neg) ul =3D -ul; > + setintV(L->base-1-LJ_FR2, (int32_t)ul); > + } else { > + lua_Number n =3D (lua_Number)ul; > + if (neg) n =3D -n; > + setnumV(L->base-1-LJ_FR2, n); > + } > + return FFH_RES(1); > + } > } > } > } > diff --git = a/test/tarantool-tests/tonumber-negative-non-decimal-base.test.lua = b/test/tarantool-tests/tonumber-negative-non-decimal-base.test.lua > new file mode 100644 > index 00000000..94df3b1f > --- /dev/null > +++ b/test/tarantool-tests/tonumber-negative-non-decimal-base.test.lua > @@ -0,0 +1,29 @@ > +local tap =3D require('tap') > + > +local test =3D tap.test('tonumber-negative-non-decimal-base') > +test:plan(18) > + > +-- Test valid tonumber() with +- signs and non-10 base. > +test:ok(tonumber('-010', 2) =3D=3D -2, 'negative base 2') > +test:ok(tonumber('-10', 8) =3D=3D -8, 'negative base 8') > +test:ok(tonumber('-0x10', 16) =3D=3D -16, 'negative base 16') > +test:ok(tonumber(' -1010 ', 2) =3D=3D -10, 'negative base 2 with = spaces') > +test:ok(tonumber(' +1010 ', 2) =3D=3D 10, 'positive base 2 with = spaces') > +test:ok(tonumber(' -012 ', 8) =3D=3D -10, 'negative base 8 with = spaces') > +test:ok(tonumber(' +012 ', 8) =3D=3D 10, 'positive base 8 with = spaces') > +test:ok(tonumber(' -10 ', 16) =3D=3D -16, 'negative base 16 with = spaces') > +test:ok(tonumber(' +10 ', 16) =3D=3D 16, 'positive base 16 with = spaces') > +test:ok(tonumber(' -1Z ', 36) =3D=3D -36 - 35, 'negative base 36 = with spaces') > +test:ok(tonumber(' +1z ', 36) =3D=3D 36 + 35, 'positive base 36 = with spaces') > +test:ok(tonumber('-fF', 16) =3D=3D -(15 + (16 * 15)), 'negative base = 16 mixed case') > +test:ok(tonumber('-0ffffffFFFF', 16) - 1 =3D=3D -2 ^ 40, 'negative = base 16 long') > + > +-- Test invalid tonumber() for non-10 base. > +test:ok(tonumber('-z1010 ', 2) =3D=3D nil, 'incorrect notation in = base 2') > +test:ok(tonumber('--1010 ', 2) =3D=3D nil, 'double minus sign') > +test:ok(tonumber('-+1010 ', 2) =3D=3D nil, 'minus plus sign') > +test:ok(tonumber('- 1010 ', 2) =3D=3D nil, 'space between sign and = value') > +test:ok(tonumber('-_1010 ', 2) =3D=3D nil, > + 'invalid character between sign and value') > + > +os.exit(test:check() and 0 or 1) > --=20 > 2.34.1 >=20 > [1]: http://www.lua.org/manual/5.1/manual.html#pdf-tonumber > [2]: http://www.lua.org/manual/5.2/manual.html#pdf-tonumber