mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-23 21:08:23 +00:00
bf78cd3514
Lua's LNUM patch currently doesn't parse properly certain numbers as
it's visible from the following simple tests.
On x86_64 host (stock Lua 5.1.5, expected output):
$ /usr/bin/lua -e 'print(0x80000000); print(0x80000000000); print(0x100000000)'
2147483648
8796093022208
4294967296
On x86_64 host:
$ staging_dir/hostpkg/bin/lua -e 'print(0x80000000); print(0x80000000000); print(0x100000000)'
-2147483648
0
0
On x86_64 target:
$ lua -e 'print(0x80000000); print(0x80000000000); print(0x100000000)'
-2147483648
0
0
On ath79 target:
$ lua -e 'print(0x80000000); print(0x80000000000); print(0x100000000)'
-2147483648
8796093022208
4294967296
It's caused by two issues fixed in this patch, first issue is caused by
unhadled strtoul overflow and second one is caused by the cast of
unsigned to signed Lua integer when parsing from hex literal.
Run tested on:
* Zidoo Z9S with RTD1296 CPU (aarch64_cortex-a53)
* qemu/x86_64
* qemu/armvirt_64
* ath79
Signed-off-by: Liangbin Lian <jjm2473@gmail.com>
[commit subject/message touches, fixed From to match SOB, fixed another
unhandled case in luaO_str2i, host Lua, package bump]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
(cherry picked from commit 4bb9af48ca
)
42 lines
1.2 KiB
Diff
42 lines
1.2 KiB
Diff
--- a/src/lnum.c
|
|
+++ b/src/lnum.c
|
|
@@ -127,6 +127,8 @@ static int luaO_str2i (const char *s, lu
|
|
#else
|
|
return 0; /* Reject the number */
|
|
#endif
|
|
+ } else if (v > LUA_INTEGER_MAX) {
|
|
+ return TK_NUMBER;
|
|
}
|
|
} else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
|
|
return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */
|
|
@@ -310,3 +312,13 @@ int try_unmint( lua_Integer *r, lua_Inte
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef LONG_OVERFLOW_LUA_INTEGER
|
|
+unsigned LUA_INTEGER lua_str2ul( const char *str, char **endptr, int base ) {
|
|
+ unsigned long v= strtoul(str, endptr, base);
|
|
+ if ( v > LUA_INTEGER_MAX ) {
|
|
+ errno= ERANGE;
|
|
+ v= ULONG_MAX;
|
|
+ }
|
|
+ return (unsigned LUA_INTEGER)v;
|
|
+}
|
|
+#endif
|
|
--- a/src/lnum_config.h
|
|
+++ b/src/lnum_config.h
|
|
@@ -141,7 +141,12 @@
|
|
#endif
|
|
|
|
#ifndef lua_str2ul
|
|
-# define lua_str2ul (unsigned LUA_INTEGER)strtoul
|
|
+# if LONG_MAX > LUA_INTEGER_MAX
|
|
+# define LONG_OVERFLOW_LUA_INTEGER
|
|
+ unsigned LUA_INTEGER lua_str2ul( const char *str, char **endptr, int base );
|
|
+# else
|
|
+# define lua_str2ul (unsigned LUA_INTEGER)strtoul
|
|
+# endif
|
|
#endif
|
|
#ifndef LUA_INTEGER_MIN
|
|
# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
|