forked from pool/lua54
- Update to 5.4.5:
- this is a bug-fix release. - Lua 5.4.5 also contains several internal improvements and includes a revised reference manual - Remove upstreamed patches: - luabugs1.patch - luabugs10.patch - luabugs11.patch - luabugs2.patch - luabugs6.patch - luabugs7.patch - luabugs8.patch - luabugs9.patch OBS-URL: https://build.opensuse.org/package/show/devel:languages:lua/lua54?expand=0&rev=72
This commit is contained in:
parent
cc801642b3
commit
ce441f7720
@ -1,7 +1,9 @@
|
|||||||
Index: lua/files.lua
|
---
|
||||||
===================================================================
|
testes/files.lua | 12 +++++++++---
|
||||||
--- lua.orig/testes/files.lua
|
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||||
+++ lua/testes/files.lua
|
|
||||||
|
--- a/testes/files.lua
|
||||||
|
+++ b/testes/files.lua
|
||||||
@@ -81,7 +81,7 @@ assert(io.output() ~= io.stdout)
|
@@ -81,7 +81,7 @@ assert(io.output() ~= io.stdout)
|
||||||
|
|
||||||
if not _port then -- invalid seek
|
if not _port then -- invalid seek
|
||||||
@ -11,7 +13,7 @@ Index: lua/files.lua
|
|||||||
end
|
end
|
||||||
|
|
||||||
assert(io.output():seek() == 0)
|
assert(io.output():seek() == 0)
|
||||||
@@ -744,7 +744,7 @@ if not _port then
|
@@ -746,7 +746,7 @@ if not _port then
|
||||||
{"exit 129", "exit", 129},
|
{"exit 129", "exit", 129},
|
||||||
{"kill -s HUP $$", "signal", 1},
|
{"kill -s HUP $$", "signal", 1},
|
||||||
{"kill -s KILL $$", "signal", 9},
|
{"kill -s KILL $$", "signal", 9},
|
||||||
@ -20,7 +22,7 @@ Index: lua/files.lua
|
|||||||
{progname .. ' -e " "', "ok"},
|
{progname .. ' -e " "', "ok"},
|
||||||
{progname .. ' -e "os.exit(0, true)"', "ok"},
|
{progname .. ' -e "os.exit(0, true)"', "ok"},
|
||||||
{progname .. ' -e "os.exit(20, true)"', "exit", 20},
|
{progname .. ' -e "os.exit(20, true)"', "exit", 20},
|
||||||
@@ -757,6 +757,9 @@ if not _port then
|
@@ -759,6 +759,9 @@ if not _port then
|
||||||
if v[2] == "ok" then
|
if v[2] == "ok" then
|
||||||
assert(x and y == 'exit' and z == 0)
|
assert(x and y == 'exit' and z == 0)
|
||||||
else
|
else
|
||||||
@ -30,7 +32,7 @@ Index: lua/files.lua
|
|||||||
assert(not x and y == v[2]) -- correct status and 'what'
|
assert(not x and y == v[2]) -- correct status and 'what'
|
||||||
-- correct code if known (but always different from 0)
|
-- correct code if known (but always different from 0)
|
||||||
assert((v[3] == nil and z > 0) or v[3] == z)
|
assert((v[3] == nil and z > 0) or v[3] == z)
|
||||||
@@ -791,6 +791,7 @@ assert(os.date(string.rep("%d", 1000), t
|
@@ -793,6 +796,7 @@ assert(os.date(string.rep("%d", 1000), t
|
||||||
assert(os.date(string.rep("%", 200)) == string.rep("%", 100))
|
assert(os.date(string.rep("%", 200)) == string.rep("%", 100))
|
||||||
|
|
||||||
local function checkDateTable (t)
|
local function checkDateTable (t)
|
||||||
@ -38,7 +40,7 @@ Index: lua/files.lua
|
|||||||
_G.D = os.date("*t", t)
|
_G.D = os.date("*t", t)
|
||||||
assert(os.time(D) == t)
|
assert(os.time(D) == t)
|
||||||
load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and
|
load(os.date([[assert(D.year==%Y and D.month==%m and D.day==%d and
|
||||||
@@ -806,7 +806,9 @@ if not _port then
|
@@ -808,7 +812,9 @@ if not _port then
|
||||||
checkDateTable(1)
|
checkDateTable(1)
|
||||||
checkDateTable(1000)
|
checkDateTable(1000)
|
||||||
checkDateTable(0x7fffffff)
|
checkDateTable(0x7fffffff)
|
||||||
|
BIN
lua-5.4.4-tests.tar.gz
(Stored with Git LFS)
BIN
lua-5.4.4-tests.tar.gz
(Stored with Git LFS)
Binary file not shown.
BIN
lua-5.4.4.tar.gz
(Stored with Git LFS)
BIN
lua-5.4.4.tar.gz
(Stored with Git LFS)
Binary file not shown.
3
lua-5.4.5-tests.tar.gz
Normal file
3
lua-5.4.5-tests.tar.gz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:856103e7298d354d870010b4966ce21281cbf3373abafd50231a98561bca793d
|
||||||
|
size 136198
|
3
lua-5.4.5.tar.gz
Normal file
3
lua-5.4.5.tar.gz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:59df426a3d50ea535a460a452315c4c0d4e1121ba72ff0bdde58c2ef31d6f444
|
||||||
|
size 363316
|
@ -2,9 +2,15 @@ From: Enrico Tassi <gareuselesinge@debian.org>, Sergei Golovan <sgolovan@debian.
|
|||||||
Date: Wed, 06 May 2020 10:31:53 +0300
|
Date: Wed, 06 May 2020 10:31:53 +0300
|
||||||
Subject: build system
|
Subject: build system
|
||||||
|
|
||||||
|
---
|
||||||
|
Makefile | 22 +++++++++++-----------
|
||||||
|
src/Makefile | 42 ++++++++++++++++++++++++------------------
|
||||||
|
src/luaconf.h | 2 +-
|
||||||
|
3 files changed, 36 insertions(+), 30 deletions(-)
|
||||||
|
|
||||||
--- a/Makefile
|
--- a/Makefile
|
||||||
+++ b/Makefile
|
+++ b/Makefile
|
||||||
@@ -10,19 +12,19 @@
|
@@ -10,18 +10,18 @@ PLAT= guess
|
||||||
# so take care if INSTALL_TOP is not an absolute path. See the local target.
|
# so take care if INSTALL_TOP is not an absolute path. See the local target.
|
||||||
# You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with
|
# You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with
|
||||||
# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h.
|
# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h.
|
||||||
@ -29,9 +35,8 @@ Subject: build system
|
|||||||
INSTALL_DATA= $(INSTALL) -m 0644
|
INSTALL_DATA= $(INSTALL) -m 0644
|
||||||
#
|
#
|
||||||
# If you don't have "install" you can use "cp" instead.
|
# If you don't have "install" you can use "cp" instead.
|
||||||
# INSTALL= cp -p
|
@@ -39,10 +39,10 @@ RM= rm -f
|
||||||
@@ -39,10 +42,10 @@
|
PLATS= guess aix bsd c89 freebsd generic ios linux linux-readline macosx mingw posix solaris
|
||||||
PLATS= guess aix bsd c89 freebsd generic linux linux-readline macosx mingw posix solaris
|
|
||||||
|
|
||||||
# What to install.
|
# What to install.
|
||||||
-TO_BIN= lua luac
|
-TO_BIN= lua luac
|
||||||
@ -44,7 +49,7 @@ Subject: build system
|
|||||||
|
|
||||||
# Lua version and release.
|
# Lua version and release.
|
||||||
V= 5.4
|
V= 5.4
|
||||||
@@ -52,13 +55,13 @@
|
@@ -52,13 +52,13 @@ R= $V.5
|
||||||
all: $(PLAT)
|
all: $(PLAT)
|
||||||
|
|
||||||
$(PLATS) help test clean:
|
$(PLATS) help test clean:
|
||||||
@ -60,7 +65,6 @@ Subject: build system
|
|||||||
cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
|
cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
|
|
||||||
--- a/src/Makefile
|
--- a/src/Makefile
|
||||||
+++ b/src/Makefile
|
+++ b/src/Makefile
|
||||||
@@ -7,7 +7,7 @@
|
@@ -7,7 +7,7 @@
|
||||||
@ -72,7 +76,7 @@ Subject: build system
|
|||||||
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
|
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
|
||||||
LIBS= -lm $(SYSLIBS) $(MYLIBS)
|
LIBS= -lm $(SYSLIBS) $(MYLIBS)
|
||||||
|
|
||||||
@@ -22,25 +22,40 @@
|
@@ -22,25 +22,40 @@ SYSLIBS=
|
||||||
|
|
||||||
MYCFLAGS=
|
MYCFLAGS=
|
||||||
MYLDFLAGS=
|
MYLDFLAGS=
|
||||||
@ -100,10 +104,10 @@ Subject: build system
|
|||||||
+
|
+
|
||||||
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
|
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
|
||||||
|
|
||||||
PLATS= guess aix bsd c89 freebsd generic linux linux-readline macosx mingw posix solaris
|
PLATS= guess aix bsd c89 freebsd generic ios linux linux-readline macosx mingw posix solaris
|
||||||
|
|
||||||
-LUA_A= liblua.a
|
-LUA_A= liblua.a
|
||||||
+LUA_A= liblua$(V).la
|
+LUA_A= liblua$(V).a
|
||||||
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o
|
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o
|
||||||
LIB_O= lauxlib.o lbaselib.o lcorolib.o ldblib.o liolib.o lmathlib.o loadlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o linit.o
|
LIB_O= lauxlib.o lbaselib.o lcorolib.o ldblib.o liolib.o lmathlib.o loadlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o linit.o
|
||||||
BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
|
BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
|
||||||
@ -117,7 +121,7 @@ Subject: build system
|
|||||||
LUAC_O= luac.o
|
LUAC_O= luac.o
|
||||||
|
|
||||||
ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
|
ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
|
||||||
@@ -57,17 +72,16 @@
|
@@ -57,17 +72,16 @@ o: $(ALL_O)
|
||||||
a: $(ALL_A)
|
a: $(ALL_A)
|
||||||
|
|
||||||
$(LUA_A): $(BASE_O)
|
$(LUA_A): $(BASE_O)
|
||||||
@ -138,8 +142,8 @@ Subject: build system
|
|||||||
+ $(LIBTOOL) --mode=execute -dlopen ./$(LUA_A) ./$(LUA_T) -v
|
+ $(LIBTOOL) --mode=execute -dlopen ./$(LUA_A) ./$(LUA_T) -v
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) $(ALL_T) $(ALL_O)
|
$(RM) $(ALL_T) $(ALL_O)
|
||||||
@@ -144,14 +159,6 @@
|
@@ -147,14 +161,6 @@ SunOS solaris:
|
||||||
.PHONY: all $(PLATS) help test clean default o a depend echo
|
.PHONY: all $(PLATS) help test clean default o a depend echo
|
||||||
|
|
||||||
# Compiler modules may use special flags.
|
# Compiler modules may use special flags.
|
||||||
@ -154,10 +158,9 @@ Subject: build system
|
|||||||
|
|
||||||
# DO NOT DELETE
|
# DO NOT DELETE
|
||||||
|
|
||||||
|
|
||||||
--- a/src/luaconf.h
|
--- a/src/luaconf.h
|
||||||
+++ b/src/luaconf.h
|
+++ b/src/luaconf.h
|
||||||
@@ -217,7 +217,7 @@
|
@@ -223,7 +223,7 @@
|
||||||
|
|
||||||
#else /* }{ */
|
#else /* }{ */
|
||||||
|
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Sun Apr 30 12:22:03 UTC 2023 - Matej Cepl <mcepl@suse.com>
|
||||||
|
|
||||||
|
- Update to 5.4.5:
|
||||||
|
- this is a bug-fix release.
|
||||||
|
- Lua 5.4.5 also contains several internal improvements and
|
||||||
|
includes a revised reference manual
|
||||||
|
- Remove upstreamed patches:
|
||||||
|
- luabugs1.patch
|
||||||
|
- luabugs10.patch
|
||||||
|
- luabugs11.patch
|
||||||
|
- luabugs2.patch
|
||||||
|
- luabugs6.patch
|
||||||
|
- luabugs7.patch
|
||||||
|
- luabugs8.patch
|
||||||
|
- luabugs9.patch
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Tue Apr 4 11:58:56 UTC 2023 - Callum Farmer <gmbr3@opensuse.org>
|
Tue Apr 4 11:58:56 UTC 2023 - Callum Farmer <gmbr3@opensuse.org>
|
||||||
|
|
||||||
|
23
lua54.spec
23
lua54.spec
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# spec file for package lua54
|
# spec file
|
||||||
#
|
#
|
||||||
# Copyright (c) 2023 SUSE LLC
|
# Copyright (c) 2023 SUSE LLC
|
||||||
#
|
#
|
||||||
@ -15,6 +15,7 @@
|
|||||||
# Please submit bugfixes or comments via https://bugs.opensuse.org/
|
# Please submit bugfixes or comments via https://bugs.opensuse.org/
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
%global flavor @BUILD_FLAVOR@%{nil}
|
%global flavor @BUILD_FLAVOR@%{nil}
|
||||||
%if "%{flavor}" == "test"
|
%if "%{flavor}" == "test"
|
||||||
%define name_ext -test
|
%define name_ext -test
|
||||||
@ -26,7 +27,7 @@
|
|||||||
%define libname liblua5_4-5
|
%define libname liblua5_4-5
|
||||||
|
|
||||||
Name: lua54%{name_ext}
|
Name: lua54%{name_ext}
|
||||||
Version: 5.4.4
|
Version: 5.4.5
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: Small Embeddable Language with Procedural Syntax
|
Summary: Small Embeddable Language with Procedural Syntax
|
||||||
License: GPL-3.0-or-later
|
License: GPL-3.0-or-later
|
||||||
@ -44,17 +45,9 @@ Patch2: files_test.patch
|
|||||||
Patch3: main_test.patch
|
Patch3: main_test.patch
|
||||||
Patch6: shared_link.patch
|
Patch6: shared_link.patch
|
||||||
# PATCH-FIX-UPSTREAM luabugsX.patch https://www.lua.org/bugs.html#5.4.4-X
|
# PATCH-FIX-UPSTREAM luabugsX.patch https://www.lua.org/bugs.html#5.4.4-X
|
||||||
Patch7: luabugs1.patch
|
|
||||||
Patch8: luabugs2.patch
|
|
||||||
Patch9: luabugs3.patch
|
Patch9: luabugs3.patch
|
||||||
Patch10: luabugs4.patch
|
Patch10: luabugs4.patch
|
||||||
Patch11: luabugs5.patch
|
Patch11: luabugs5.patch
|
||||||
Patch12: luabugs6.patch
|
|
||||||
Patch13: luabugs7.patch
|
|
||||||
Patch14: luabugs8.patch
|
|
||||||
Patch15: luabugs9.patch
|
|
||||||
Patch16: luabugs10.patch
|
|
||||||
Patch17: luabugs11.patch
|
|
||||||
#
|
#
|
||||||
%if "%{flavor}" == "test"
|
%if "%{flavor}" == "test"
|
||||||
BuildRequires: lua54
|
BuildRequires: lua54
|
||||||
@ -65,7 +58,7 @@ BuildRequires: pkgconfig
|
|||||||
BuildRequires: readline-devel
|
BuildRequires: readline-devel
|
||||||
%endif
|
%endif
|
||||||
Requires(post): update-alternatives
|
Requires(post): update-alternatives
|
||||||
Requires(postun): update-alternatives
|
Requires(postun):update-alternatives
|
||||||
Provides: lua = %{version}
|
Provides: lua = %{version}
|
||||||
Obsoletes: lua < %{version}
|
Obsoletes: lua < %{version}
|
||||||
Provides: Lua(API) = %{major_version}
|
Provides: Lua(API) = %{major_version}
|
||||||
@ -90,7 +83,7 @@ Requires: %{libname} = %{version}
|
|||||||
Requires: %{name} = %{version}
|
Requires: %{name} = %{version}
|
||||||
Requires: lua-macros
|
Requires: lua-macros
|
||||||
Requires(post): update-alternatives
|
Requires(post): update-alternatives
|
||||||
Requires(postun): update-alternatives
|
Requires(postun):update-alternatives
|
||||||
Provides: lua-devel = %{version}
|
Provides: lua-devel = %{version}
|
||||||
Provides: Lua(devel) = %{major_version}
|
Provides: Lua(devel) = %{major_version}
|
||||||
Provides: pkgconfig(lua) = %{version}
|
Provides: pkgconfig(lua) = %{version}
|
||||||
@ -186,9 +179,9 @@ includedir=%{_includedir}/lua%{major_version}
|
|||||||
INSTALL_LMOD=%{_datadir}/lua/%{major_version}
|
INSTALL_LMOD=%{_datadir}/lua/%{major_version}
|
||||||
INSTALL_CMOD=%{_libdir}/lua/%{major_version}
|
INSTALL_CMOD=%{_libdir}/lua/%{major_version}
|
||||||
|
|
||||||
Name: Lua %{major_version}
|
Name: Lua %{major_version}
|
||||||
Description: An Extensible Extension Language
|
Description: An Extensible Extension Language
|
||||||
Version: %{version}
|
Version: %{version}
|
||||||
Libs: -llua%{major_version} -lm
|
Libs: -llua%{major_version} -lm
|
||||||
Cflags: -I\${includedir}
|
Cflags: -I\${includedir}
|
||||||
EOF
|
EOF
|
||||||
@ -213,6 +206,7 @@ ln -sf %{_sysconfdir}/alternatives/liblua.so %{buildroot}%{_libdir}/liblua.so
|
|||||||
touch %{buildroot}%{_sysconfdir}/alternatives/lua.pc
|
touch %{buildroot}%{_sysconfdir}/alternatives/lua.pc
|
||||||
ln -sf %{_sysconfdir}/alternatives/lua.pc %{buildroot}%{_libdir}/pkgconfig/lua.pc
|
ln -sf %{_sysconfdir}/alternatives/lua.pc %{buildroot}%{_libdir}/pkgconfig/lua.pc
|
||||||
%else
|
%else
|
||||||
|
|
||||||
%check
|
%check
|
||||||
cd testes
|
cd testes
|
||||||
LD_LIBRARY_PATH=%{_libdir} %{_bindir}/lua%{major_version} all.lua
|
LD_LIBRARY_PATH=%{_libdir} %{_bindir}/lua%{major_version} all.lua
|
||||||
@ -286,4 +280,5 @@ fi
|
|||||||
%doc doc/*
|
%doc doc/*
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
From 25b143dd34fb587d1e35290c4b25bc08954800e2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
||||||
Date: Mon, 7 Feb 2022 10:16:35 -0300
|
|
||||||
Subject: [PATCH] Bug: lua.c assumes that argv has at least one element
|
|
||||||
|
|
||||||
---
|
|
||||||
lua.c | 35 +++++++++++++++++++++++------------
|
|
||||||
1 file changed, 23 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lua.c b/lua.c
|
|
||||||
index 0f1900444..7f7dc2b22 100644
|
|
||||||
--- a/src/lua.c
|
|
||||||
+++ b/src/lua.c
|
|
||||||
@@ -177,10 +177,11 @@ static void print_version (void) {
|
|
||||||
** to the script (everything after 'script') go to positive indices;
|
|
||||||
** other arguments (before the script name) go to negative indices.
|
|
||||||
** If there is no script name, assume interpreter's name as base.
|
|
||||||
+** (If there is no interpreter's name either, 'script' is -1, so
|
|
||||||
+** table sizes are zero.)
|
|
||||||
*/
|
|
||||||
static void createargtable (lua_State *L, char **argv, int argc, int script) {
|
|
||||||
int i, narg;
|
|
||||||
- if (script == argc) script = 0; /* no script name? */
|
|
||||||
narg = argc - (script + 1); /* number of positive indices */
|
|
||||||
lua_createtable(L, narg, script + 1);
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
@@ -268,14 +269,23 @@ static int handle_script (lua_State *L, char **argv) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Traverses all arguments from 'argv', returning a mask with those
|
|
||||||
-** needed before running any Lua code (or an error code if it finds
|
|
||||||
-** any invalid argument). 'first' returns the first not-handled argument
|
|
||||||
-** (either the script name or a bad argument in case of error).
|
|
||||||
+** needed before running any Lua code or an error code if it finds any
|
|
||||||
+** invalid argument. In case of error, 'first' is the index of the bad
|
|
||||||
+** argument. Otherwise, 'first' is -1 if there is no program name,
|
|
||||||
+** 0 if there is no script name, or the index of the script name.
|
|
||||||
*/
|
|
||||||
static int collectargs (char **argv, int *first) {
|
|
||||||
int args = 0;
|
|
||||||
int i;
|
|
||||||
- for (i = 1; argv[i] != NULL; i++) {
|
|
||||||
+ if (argv[0] != NULL) { /* is there a program name? */
|
|
||||||
+ if (argv[0][0]) /* not empty? */
|
|
||||||
+ progname = argv[0]; /* save it */
|
|
||||||
+ }
|
|
||||||
+ else { /* no program name */
|
|
||||||
+ *first = -1;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ for (i = 1; argv[i] != NULL; i++) { /* handle arguments */
|
|
||||||
*first = i;
|
|
||||||
if (argv[i][0] != '-') /* not an option? */
|
|
||||||
return args; /* stop handling options */
|
|
||||||
@@ -316,7 +326,7 @@ static int collectargs (char **argv, int *first) {
|
|
||||||
return has_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- *first = i; /* no script name */
|
|
||||||
+ *first = 0; /* no script name */
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -609,8 +619,8 @@ static int pmain (lua_State *L) {
|
|
||||||
char **argv = (char **)lua_touserdata(L, 2);
|
|
||||||
int script;
|
|
||||||
int args = collectargs(argv, &script);
|
|
||||||
+ int optlim = (script > 0) ? script : argc; /* first argv not an option */
|
|
||||||
luaL_checkversion(L); /* check that interpreter has correct version */
|
|
||||||
- if (argv[0] && argv[0][0]) progname = argv[0];
|
|
||||||
if (args == has_error) { /* bad arg? */
|
|
||||||
print_usage(argv[script]); /* 'script' has index of bad arg. */
|
|
||||||
return 0;
|
|
||||||
@@ -628,14 +638,15 @@ static int pmain (lua_State *L) {
|
|
||||||
if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */
|
|
||||||
return 0; /* error running LUA_INIT */
|
|
||||||
}
|
|
||||||
- if (!runargs(L, argv, script)) /* execute arguments -e and -l */
|
|
||||||
+ if (!runargs(L, argv, optlim)) /* execute arguments -e and -l */
|
|
||||||
return 0; /* something failed */
|
|
||||||
- if (script < argc && /* execute main script (if there is one) */
|
|
||||||
- handle_script(L, argv + script) != LUA_OK)
|
|
||||||
- return 0;
|
|
||||||
+ if (script > 0) { /* execute main script (if there is one) */
|
|
||||||
+ if (handle_script(L, argv + script) != LUA_OK)
|
|
||||||
+ return 0; /* interrupt in case of error */
|
|
||||||
+ }
|
|
||||||
if (args & has_i) /* -i option? */
|
|
||||||
doREPL(L); /* do read-eval-print loop */
|
|
||||||
- else if (script == argc && !(args & (has_e | has_v))) { /* no arguments? */
|
|
||||||
+ else if (script < 1 && !(args & (has_e | has_v))) { /* no active option? */
|
|
||||||
if (lua_stdin_is_tty()) { /* running in interactive mode? */
|
|
||||||
print_version();
|
|
||||||
doREPL(L); /* do read-eval-print loop */
|
|
@ -1,67 +0,0 @@
|
|||||||
From 02bab9fc258fe1cbc6088b1bd61193499d058eff Mon Sep 17 00:00:00 2001
|
|
||||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
||||||
Date: Wed, 8 Feb 2023 14:15:41 -0300
|
|
||||||
Subject: [PATCH] Bug: Wrong line in error message for arith. errors
|
|
||||||
|
|
||||||
It also causes 'L->top' to be wrong when the error happens,
|
|
||||||
triggering an 'assert'.
|
|
||||||
---
|
|
||||||
lvm.c | 4 ++++
|
|
||||||
testes/errors.lua | 8 ++++++++
|
|
||||||
2 files changed, 12 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/lvm.c b/lvm.c
|
|
||||||
index 2e84dc63c..8493a770c 100644
|
|
||||||
--- a/src/lvm.c
|
|
||||||
+++ b/src/lvm.c
|
|
||||||
@@ -1410,6 +1410,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|
||||||
vmbreak;
|
|
||||||
}
|
|
||||||
vmcase(OP_MODK) {
|
|
||||||
+ savestate(L, ci); /* in case of division by 0 */
|
|
||||||
op_arithK(L, luaV_mod, luaV_modf);
|
|
||||||
vmbreak;
|
|
||||||
}
|
|
||||||
@@ -1422,6 +1423,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|
||||||
vmbreak;
|
|
||||||
}
|
|
||||||
vmcase(OP_IDIVK) {
|
|
||||||
+ savestate(L, ci); /* in case of division by 0 */
|
|
||||||
op_arithK(L, luaV_idiv, luai_numidiv);
|
|
||||||
vmbreak;
|
|
||||||
}
|
|
||||||
@@ -1470,6 +1472,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|
||||||
vmbreak;
|
|
||||||
}
|
|
||||||
vmcase(OP_MOD) {
|
|
||||||
+ savestate(L, ci); /* in case of division by 0 */
|
|
||||||
op_arith(L, luaV_mod, luaV_modf);
|
|
||||||
vmbreak;
|
|
||||||
}
|
|
||||||
@@ -1482,6 +1485,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|
||||||
vmbreak;
|
|
||||||
}
|
|
||||||
vmcase(OP_IDIV) { /* floor division */
|
|
||||||
+ savestate(L, ci); /* in case of division by 0 */
|
|
||||||
op_arith(L, luaV_idiv, luai_numidiv);
|
|
||||||
vmbreak;
|
|
||||||
}
|
|
||||||
diff --git a/testes/errors.lua b/testes/errors.lua
|
|
||||||
index cf0ab5265..bf6f389d2 100644
|
|
||||||
--- a/testes/errors.lua
|
|
||||||
+++ b/testes/errors.lua
|
|
||||||
@@ -444,6 +444,14 @@ if not b then
|
|
||||||
end
|
|
||||||
end]], 5)
|
|
||||||
|
|
||||||
+
|
|
||||||
+-- bug in 5.4.0
|
|
||||||
+lineerror([[
|
|
||||||
+ local a = 0
|
|
||||||
+ local b = 1
|
|
||||||
+ local c = b % a
|
|
||||||
+]], 3)
|
|
||||||
+
|
|
||||||
do
|
|
||||||
-- Force a negative estimate for base line. Error in instruction 2
|
|
||||||
-- (after VARARGPREP, GETGLOBAL), with first absolute line information
|
|
@ -1,77 +0,0 @@
|
|||||||
From ab859fe59b464a038a45552921cb2b23892343af Mon Sep 17 00:00:00 2001
|
|
||||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
||||||
Date: Fri, 17 Mar 2023 15:52:09 -0300
|
|
||||||
Subject: [PATCH] Bug: Loading a corrupted binary file can segfault
|
|
||||||
|
|
||||||
The size of the list of upvalue names are stored separated from the
|
|
||||||
size of the list of upvalues, but they share the same array.
|
|
||||||
---
|
|
||||||
ldump.c | 8 ++++++--
|
|
||||||
lundump.c | 2 ++
|
|
||||||
testes/calls.lua | 14 ++++++++++++++
|
|
||||||
3 files changed, 22 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ldump.c b/ldump.c
|
|
||||||
index f848b669c..f231691b7 100644
|
|
||||||
--- a/src/ldump.c
|
|
||||||
+++ b/src/ldump.c
|
|
||||||
@@ -10,6 +10,7 @@
|
|
||||||
#include "lprefix.h"
|
|
||||||
|
|
||||||
|
|
||||||
+#include <limits.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "lua.h"
|
|
||||||
@@ -55,8 +56,11 @@ static void dumpByte (DumpState *D, int y) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-/* dumpInt Buff Size */
|
|
||||||
-#define DIBS ((sizeof(size_t) * 8 / 7) + 1)
|
|
||||||
+/*
|
|
||||||
+** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6"
|
|
||||||
+** rounds up the division.)
|
|
||||||
+*/
|
|
||||||
+#define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7)
|
|
||||||
|
|
||||||
static void dumpSize (DumpState *D, size_t x) {
|
|
||||||
lu_byte buff[DIBS];
|
|
||||||
diff --git a/lundump.c b/lundump.c
|
|
||||||
index aba93f828..02aed64fb 100644
|
|
||||||
--- a/src/lundump.c
|
|
||||||
+++ b/src/lundump.c
|
|
||||||
@@ -248,6 +248,8 @@ static void loadDebug (LoadState *S, Proto *f) {
|
|
||||||
f->locvars[i].endpc = loadInt(S);
|
|
||||||
}
|
|
||||||
n = loadInt(S);
|
|
||||||
+ if (n != 0) /* does it have debug information? */
|
|
||||||
+ n = f->sizeupvalues; /* must be this many */
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
f->upvalues[i].name = loadStringN(S, f);
|
|
||||||
}
|
|
||||||
diff --git a/testes/calls.lua b/testes/calls.lua
|
|
||||||
index a19385843..2d562a24a 100644
|
|
||||||
--- a/testes/calls.lua
|
|
||||||
+++ b/testes/calls.lua
|
|
||||||
@@ -342,6 +342,20 @@ do -- another bug (in 5.4.0)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
+do -- another bug (since 5.2)
|
|
||||||
+ -- corrupted binary dump: list of upvalue names is larger than number
|
|
||||||
+ -- of upvalues, overflowing the array of upvalues.
|
|
||||||
+ local code =
|
|
||||||
+ "\x1b\x4c\x75\x61\x54\x00\x19\x93\x0d\x0a\x1a\x0a\x04\x08\x08\x78\x56\z
|
|
||||||
+ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x77\x40\x00\x86\x40\z
|
|
||||||
+ \x74\x65\x6d\x70\x81\x81\x01\x00\x02\x82\x48\x00\x02\x00\xc7\x00\x01\z
|
|
||||||
+ \x00\x80\x80\x80\x82\x00\x00\x80\x81\x82\x78\x80\x82\x81\x86\x40\x74\z
|
|
||||||
+ \x65\x6d\x70"
|
|
||||||
+
|
|
||||||
+ assert(load(code)) -- segfaults in previous versions
|
|
||||||
+end
|
|
||||||
+
|
|
||||||
+
|
|
||||||
x = string.dump(load("x = 1; return x"))
|
|
||||||
a = assert(load(read1(x), nil, "b"))
|
|
||||||
assert(a() == 1 and _G.x == 1)
|
|
@ -1,43 +0,0 @@
|
|||||||
From 1f3c6f4534c6411313361697d98d1145a1f030fa Mon Sep 17 00:00:00 2001
|
|
||||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
||||||
Date: Tue, 15 Feb 2022 12:28:46 -0300
|
|
||||||
Subject: [PATCH] Bug: Lua can generate wrong code when _ENV is <const>
|
|
||||||
|
|
||||||
---
|
|
||||||
lparser.c | 1 +
|
|
||||||
testes/attrib.lua | 10 ++++++++++
|
|
||||||
2 files changed, 11 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/lparser.c b/lparser.c
|
|
||||||
index 3abe3d751..a5cd55257 100644
|
|
||||||
--- a/src/lparser.c
|
|
||||||
+++ b/src/lparser.c
|
|
||||||
@@ -468,6 +468,7 @@ static void singlevar (LexState *ls, expdesc *var) {
|
|
||||||
expdesc key;
|
|
||||||
singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
|
|
||||||
lua_assert(var->k != VVOID); /* this one must exist */
|
|
||||||
+ luaK_exp2anyregup(fs, var); /* but could be a constant */
|
|
||||||
codestring(&key, varname); /* key is variable name */
|
|
||||||
luaK_indexed(fs, var, &key); /* env[varname] */
|
|
||||||
}
|
|
||||||
diff --git a/testes/attrib.lua b/testes/attrib.lua
|
|
||||||
index b1076c768..83821c069 100644
|
|
||||||
--- a/testes/attrib.lua
|
|
||||||
+++ b/testes/attrib.lua
|
|
||||||
@@ -434,6 +434,16 @@ a.aVeryLongName012345678901234567890123456789012345678901234567890123456789 ==
|
|
||||||
10)
|
|
||||||
|
|
||||||
|
|
||||||
+do
|
|
||||||
+ -- _ENV constant
|
|
||||||
+ local function foo ()
|
|
||||||
+ local _ENV <const> = 11
|
|
||||||
+ X = "hi"
|
|
||||||
+ end
|
|
||||||
+ local st, msg = pcall(foo)
|
|
||||||
+ assert(not st and string.find(msg, "number"))
|
|
||||||
+end
|
|
||||||
+
|
|
||||||
|
|
||||||
-- test of large float/integer indices
|
|
||||||
|
|
113
luabugs3.patch
113
luabugs3.patch
@ -4,120 +4,17 @@ Date: Mon, 25 Apr 2022 14:42:51 -0300
|
|||||||
Subject: [PATCH] Bug: Wrong code generation in bitwise operations
|
Subject: [PATCH] Bug: Wrong code generation in bitwise operations
|
||||||
|
|
||||||
---
|
---
|
||||||
lcode.c | 16 ++++++++++------
|
src/lcode.c | 2 +-
|
||||||
ltests.h | 7 +++++++
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
testes/constructs.lua | 25 +++++++++++++++++++++++++
|
|
||||||
3 files changed, 42 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lcode.c b/lcode.c
|
|
||||||
index 06425a1db..cb724a090 100644
|
|
||||||
--- a/src/lcode.c
|
--- a/src/lcode.c
|
||||||
+++ b/src/lcode.c
|
+++ b/src/lcode.c
|
||||||
@@ -1391,7 +1391,10 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
|
@@ -1531,7 +1531,7 @@ static void codecommutative (FuncState *
|
||||||
*/
|
|
||||||
static void codebinexpval (FuncState *fs, OpCode op,
|
|
||||||
expdesc *e1, expdesc *e2, int line) {
|
|
||||||
- int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */
|
|
||||||
+ int v2 = luaK_exp2anyreg(fs, e2); /* make sure 'e2' is in a register */
|
|
||||||
+ /* 'e1' must be already in a register or it is a constant */
|
|
||||||
+ lua_assert((VNIL <= e1->k && e1->k <= VKSTR) ||
|
|
||||||
+ e1->k == VNONRELOC || e1->k == VRELOC);
|
|
||||||
lua_assert(OP_ADD <= op && op <= OP_SHR);
|
|
||||||
finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN,
|
|
||||||
cast(TMS, (op - OP_ADD) + TM_ADD));
|
|
||||||
@@ -1478,7 +1481,7 @@ static void codecommutative (FuncState *fs, BinOpr op,
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
-** Code bitwise operations; they are all associative, so the function
|
|
||||||
+** Code bitwise operations; they are all commutative, so the function
|
|
||||||
** tries to put an integer constant as the 2nd operand (a K operand).
|
|
||||||
*/
|
|
||||||
static void codebitwise (FuncState *fs, BinOpr opr,
|
static void codebitwise (FuncState *fs, BinOpr opr,
|
||||||
@@ -1486,11 +1489,11 @@ static void codebitwise (FuncState *fs, BinOpr opr,
|
expdesc *e1, expdesc *e2, int line) {
|
||||||
int flip = 0;
|
int flip = 0;
|
||||||
int v2;
|
- if (e1->k == VKINT) {
|
||||||
OpCode op;
|
|
||||||
- if (e1->k == VKINT && luaK_exp2RK(fs, e1)) {
|
|
||||||
+ if (e1->k == VKINT && luaK_exp2K(fs, e1)) {
|
+ if (e1->k == VKINT && luaK_exp2K(fs, e1)) {
|
||||||
swapexps(e1, e2); /* 'e2' will be the constant operand */
|
swapexps(e1, e2); /* 'e2' will be the constant operand */
|
||||||
flip = 1;
|
flip = 1;
|
||||||
}
|
}
|
||||||
- else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */
|
|
||||||
+ else if (!(e2->k == VKINT && luaK_exp2K(fs, e2))) { /* no constants? */
|
|
||||||
op = cast(OpCode, opr + OP_ADD);
|
|
||||||
codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */
|
|
||||||
return;
|
|
||||||
@@ -1551,7 +1554,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
|
|
||||||
op = OP_EQI;
|
|
||||||
r2 = im; /* immediate operand */
|
|
||||||
}
|
|
||||||
- else if (luaK_exp2RK(fs, e2)) { /* 1st expression is constant? */
|
|
||||||
+ else if (luaK_exp2RK(fs, e2)) { /* 2nd expression is constant? */
|
|
||||||
op = OP_EQK;
|
|
||||||
r2 = e2->u.info; /* constant index */
|
|
||||||
}
|
|
||||||
@@ -1611,7 +1614,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
|
|
||||||
case OPR_SHL: case OPR_SHR: {
|
|
||||||
if (!tonumeral(v, NULL))
|
|
||||||
luaK_exp2anyreg(fs, v);
|
|
||||||
- /* else keep numeral, which may be folded with 2nd operand */
|
|
||||||
+ /* else keep numeral, which may be folded or used as an immediate
|
|
||||||
+ operand */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OPR_EQ: case OPR_NE: {
|
|
||||||
diff --git a/ltests.h b/ltests.h
|
|
||||||
index cb3a0b480..ec520498b 100644
|
|
||||||
--- a/testes/ltests/ltests.h
|
|
||||||
+++ b/testes/ltests/ltests.h
|
|
||||||
@@ -125,6 +125,13 @@ LUA_API void *debug_realloc (void *ud, void *block,
|
|
||||||
#define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; }
|
|
||||||
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+** This one is not compatible with tests for opcode optimizations,
|
|
||||||
+** as it blocks some optimizations
|
|
||||||
+#define MAXINDEXRK 0
|
|
||||||
+*/
|
|
||||||
+
|
|
||||||
+
|
|
||||||
/* make stack-overflow tests run faster */
|
|
||||||
#undef LUAI_MAXSTACK
|
|
||||||
#define LUAI_MAXSTACK 50000
|
|
||||||
diff --git a/testes/constructs.lua b/testes/constructs.lua
|
|
||||||
index a74a8c041..0d9ec92d7 100644
|
|
||||||
--- a/testes/constructs.lua
|
|
||||||
+++ b/testes/constructs.lua
|
|
||||||
@@ -103,6 +103,31 @@ do -- test old bug (first name could not be an `upvalue')
|
|
||||||
local a; function f(x) x={a=1}; x={x=1}; x={G=1} end
|
|
||||||
end
|
|
||||||
|
|
||||||
+
|
|
||||||
+do -- bug since 5.4.0
|
|
||||||
+ -- create code with a table using more than 256 constants
|
|
||||||
+ local code = {"local x = {"}
|
|
||||||
+ for i = 1, 257 do
|
|
||||||
+ code[#code + 1] = i .. ".1,"
|
|
||||||
+ end
|
|
||||||
+ code[#code + 1] = "};"
|
|
||||||
+ code = table.concat(code)
|
|
||||||
+
|
|
||||||
+ -- add "ret" to the end of that code and checks that
|
|
||||||
+ -- it produces the expected value "val"
|
|
||||||
+ local function check (ret, val)
|
|
||||||
+ local code = code .. ret
|
|
||||||
+ code = load(code)
|
|
||||||
+ assert(code() == val)
|
|
||||||
+ end
|
|
||||||
+
|
|
||||||
+ check("return (1 ~ (2 or 3))", 1 ~ 2)
|
|
||||||
+ check("return (1 | (2 or 3))", 1 | 2)
|
|
||||||
+ check("return (1 + (2 or 3))", 1 + 2)
|
|
||||||
+ check("return (1 << (2 or 3))", 1 << 2)
|
|
||||||
+end
|
|
||||||
+
|
|
||||||
+
|
|
||||||
function f (i)
|
|
||||||
if type(i) ~= 'number' then return i,'jojo'; end;
|
|
||||||
if i > 0 then return i, f(i-1); end;
|
|
||||||
|
@ -11,48 +11,16 @@ the message handler), the code should use stack slots with parsimony.
|
|||||||
This commit fixes the bug "Lua-stack overflow when C stack overflows
|
This commit fixes the bug "Lua-stack overflow when C stack overflows
|
||||||
while handling an error".
|
while handling an error".
|
||||||
---
|
---
|
||||||
ldebug.c | 5 ++++-
|
src/lvm.c | 2 +-
|
||||||
lvm.c | 6 ++++--
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
2 files changed, 8 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ldebug.c b/ldebug.c
|
|
||||||
index a716d95e2..fa15eaf68 100644
|
|
||||||
--- a/src/ldebug.c
|
|
||||||
+++ b/src/ldebug.c
|
|
||||||
@@ -824,8 +824,11 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
|
||||||
va_start(argp, fmt);
|
|
||||||
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
|
||||||
va_end(argp);
|
|
||||||
- if (isLua(ci)) /* if Lua function, add source:line information */
|
|
||||||
+ if (isLua(ci)) { /* if Lua function, add source:line information */
|
|
||||||
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
|
||||||
+ setobjs2s(L, L->top - 2, L->top - 1); /* remove 'msg' from the stack */
|
|
||||||
+ L->top--;
|
|
||||||
+ }
|
|
||||||
luaG_errormsg(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/lvm.c b/lvm.c
|
|
||||||
index e8c2e9627..cd992aada 100644
|
|
||||||
--- a/src/lvm.c
|
--- a/src/lvm.c
|
||||||
+++ b/src/lvm.c
|
+++ b/src/lvm.c
|
||||||
@@ -656,8 +656,10 @@ void luaV_concat (lua_State *L, int total) {
|
@@ -674,7 +674,7 @@ void luaV_concat (lua_State *L, int tota
|
||||||
/* collect total length and number of strings */
|
|
||||||
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
|
|
||||||
size_t l = vslen(s2v(top - n - 1));
|
|
||||||
- if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl))
|
|
||||||
+ if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) {
|
|
||||||
+ L->top = top - total; /* pop strings to avoid wasting stack */
|
|
||||||
luaG_runerror(L, "string length overflow");
|
|
||||||
+ }
|
|
||||||
tl += l;
|
|
||||||
}
|
|
||||||
if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */
|
|
||||||
@@ -672,7 +674,7 @@ void luaV_concat (lua_State *L, int total) {
|
|
||||||
setsvalue2s(L, top - n, ts); /* create result */
|
setsvalue2s(L, top - n, ts); /* create result */
|
||||||
}
|
}
|
||||||
total -= n-1; /* got 'n' strings to create 1 new */
|
total -= n - 1; /* got 'n' strings to create one new */
|
||||||
- L->top -= n-1; /* popped 'n' strings and pushed one */
|
- L->top.p -= n - 1; /* popped 'n' strings and pushed one */
|
||||||
+ L->top = top - (n - 1); /* popped 'n' strings and pushed one */
|
+ L->top = top - (n - 1); /* popped 'n' strings and pushed one */
|
||||||
} while (total > 1); /* repeat until only 1 result left */
|
} while (total > 1); /* repeat until only 1 result left */
|
||||||
}
|
}
|
||||||
|
131
luabugs5.patch
131
luabugs5.patch
@ -4,137 +4,16 @@ Date: Wed, 25 May 2022 17:41:39 -0300
|
|||||||
Subject: [PATCH] Bug: 'lua_settop' may use an invalid pointer to stack
|
Subject: [PATCH] Bug: 'lua_settop' may use an invalid pointer to stack
|
||||||
|
|
||||||
---
|
---
|
||||||
lapi.c | 5 ++---
|
src/lfunc.c | 1 +
|
||||||
ldo.c | 12 ++++++------
|
1 file changed, 1 insertion(+)
|
||||||
lfunc.c | 5 +++--
|
|
||||||
lfunc.h | 2 +-
|
|
||||||
testes/locals.lua | 22 ++++++++++++++++++++++
|
|
||||||
5 files changed, 34 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lapi.c b/lapi.c
|
|
||||||
index 352a385a3..5833c7b0a 100644
|
|
||||||
--- a/src/lapi.c
|
|
||||||
+++ b/src/lapi.c
|
|
||||||
@@ -197,7 +197,7 @@ LUA_API void lua_settop (lua_State *L, int idx) {
|
|
||||||
newtop = L->top + diff;
|
|
||||||
if (diff < 0 && L->tbclist >= newtop) {
|
|
||||||
lua_assert(hastocloseCfunc(ci->nresults));
|
|
||||||
- luaF_close(L, newtop, CLOSEKTOP, 0);
|
|
||||||
+ newtop = luaF_close(L, newtop, CLOSEKTOP, 0);
|
|
||||||
}
|
|
||||||
L->top = newtop; /* correct top only after closing any upvalue */
|
|
||||||
lua_unlock(L);
|
|
||||||
@@ -210,8 +210,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) {
|
|
||||||
level = index2stack(L, idx);
|
|
||||||
api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist == level,
|
|
||||||
"no variable to close at given level");
|
|
||||||
- luaF_close(L, level, CLOSEKTOP, 0);
|
|
||||||
- level = index2stack(L, idx); /* stack may be moved */
|
|
||||||
+ level = luaF_close(L, level, CLOSEKTOP, 0);
|
|
||||||
setnilvalue(s2v(level));
|
|
||||||
lua_unlock(L);
|
|
||||||
}
|
|
||||||
diff --git a/ldo.c b/ldo.c
|
|
||||||
index 5aa6d59d4..13498905f 100644
|
|
||||||
--- a/src/ldo.c
|
|
||||||
+++ b/src/ldo.c
|
|
||||||
@@ -430,14 +430,15 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
|
||||||
break;
|
|
||||||
default: /* two/more results and/or to-be-closed variables */
|
|
||||||
if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */
|
|
||||||
- ptrdiff_t savedres = savestack(L, res);
|
|
||||||
L->ci->callstatus |= CIST_CLSRET; /* in case of yields */
|
|
||||||
L->ci->u2.nres = nres;
|
|
||||||
- luaF_close(L, res, CLOSEKTOP, 1);
|
|
||||||
+ res = luaF_close(L, res, CLOSEKTOP, 1);
|
|
||||||
L->ci->callstatus &= ~CIST_CLSRET;
|
|
||||||
- if (L->hookmask) /* if needed, call hook after '__close's */
|
|
||||||
+ if (L->hookmask) { /* if needed, call hook after '__close's */
|
|
||||||
+ ptrdiff_t savedres = savestack(L, res);
|
|
||||||
rethook(L, L->ci, nres);
|
|
||||||
- res = restorestack(L, savedres); /* close and hook can move stack */
|
|
||||||
+ res = restorestack(L, savedres); /* hook can move stack */
|
|
||||||
+ }
|
|
||||||
wanted = decodeNresults(wanted);
|
|
||||||
if (wanted == LUA_MULTRET)
|
|
||||||
wanted = nres; /* we want all results */
|
|
||||||
@@ -654,8 +655,7 @@ static int finishpcallk (lua_State *L, CallInfo *ci) {
|
|
||||||
else { /* error */
|
|
||||||
StkId func = restorestack(L, ci->u2.funcidx);
|
|
||||||
L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */
|
|
||||||
- luaF_close(L, func, status, 1); /* can yield or raise an error */
|
|
||||||
- func = restorestack(L, ci->u2.funcidx); /* stack may be moved */
|
|
||||||
+ func = luaF_close(L, func, status, 1); /* can yield or raise an error */
|
|
||||||
luaD_seterrorobj(L, status, func);
|
|
||||||
luaD_shrinkstack(L); /* restore stack size in case of overflow */
|
|
||||||
setcistrecst(ci, LUA_OK); /* clear original status */
|
|
||||||
diff --git a/lfunc.c b/lfunc.c
|
|
||||||
index f5889a21d..3ed65de2b 100644
|
|
||||||
--- a/src/lfunc.c
|
--- a/src/lfunc.c
|
||||||
+++ b/src/lfunc.c
|
+++ b/src/lfunc.c
|
||||||
@@ -223,9 +223,9 @@ static void poptbclist (lua_State *L) {
|
@@ -204,6 +204,7 @@ void luaF_closeupval (lua_State *L, StkI
|
||||||
|
luaC_barrier(L, uv, slot);
|
||||||
/*
|
}
|
||||||
** Close all upvalues and to-be-closed variables up to the given stack
|
|
||||||
-** level.
|
|
||||||
+** level. Return restored 'level'.
|
|
||||||
*/
|
|
||||||
-void luaF_close (lua_State *L, StkId level, int status, int yy) {
|
|
||||||
+StkId luaF_close (lua_State *L, StkId level, int status, int yy) {
|
|
||||||
ptrdiff_t levelrel = savestack(L, level);
|
|
||||||
luaF_closeupval(L, level); /* first, close the upvalues */
|
|
||||||
while (L->tbclist >= level) { /* traverse tbc's down to that level */
|
|
||||||
@@ -234,6 +234,7 @@ void luaF_close (lua_State *L, StkId level, int status, int yy) {
|
|
||||||
prepcallclosemth(L, tbc, status, yy); /* close variable */
|
|
||||||
level = restorestack(L, levelrel);
|
|
||||||
}
|
}
|
||||||
+ return level;
|
+ return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
diff --git a/lfunc.h b/lfunc.h
|
|
||||||
index dc1cebccd..3d296971e 100644
|
|
||||||
--- a/src/lfunc.h
|
|
||||||
+++ b/src/lfunc.h
|
|
||||||
@@ -54,7 +54,7 @@ LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
|
|
||||||
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
|
|
||||||
LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level);
|
|
||||||
LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level);
|
|
||||||
-LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy);
|
|
||||||
+LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy);
|
|
||||||
LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
|
|
||||||
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
|
|
||||||
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
|
|
||||||
diff --git a/testes/locals.lua b/testes/locals.lua
|
|
||||||
index 62a88df57..ddb75054f 100644
|
|
||||||
--- a/testes/locals.lua
|
|
||||||
+++ b/testes/locals.lua
|
|
||||||
@@ -592,6 +592,28 @@ end
|
|
||||||
|
|
||||||
if rawget(_G, "T") then
|
|
||||||
|
|
||||||
+ do
|
|
||||||
+ -- bug in 5.4.3
|
|
||||||
+ -- 'lua_settop' may use a pointer to stack invalidated by 'luaF_close'
|
|
||||||
+
|
|
||||||
+ -- reduce stack size
|
|
||||||
+ collectgarbage(); collectgarbage(); collectgarbage()
|
|
||||||
+
|
|
||||||
+ -- force a stack reallocation
|
|
||||||
+ local function loop (n)
|
|
||||||
+ if n < 400 then loop(n + 1) end
|
|
||||||
+ end
|
|
||||||
+
|
|
||||||
+ -- close metamethod will reallocate the stack
|
|
||||||
+ local o = setmetatable({}, {__close = function () loop(0) end})
|
|
||||||
+
|
|
||||||
+ local script = [[toclose 2; settop 1; return 1]]
|
|
||||||
+
|
|
||||||
+ assert(T.testC(script, o) == script)
|
|
||||||
+
|
|
||||||
+ end
|
|
||||||
+
|
|
||||||
+
|
|
||||||
-- memory error inside closing function
|
|
||||||
local function foo ()
|
|
||||||
local y <close> = func2close(function () T.alloccount() end)
|
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
From 997f11f54322883c3181225f29d101a597f31730 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
||||||
Date: Wed, 24 Aug 2022 17:36:47 -0300
|
|
||||||
Subject: [PATCH] Bug: 'break' may not properly close variable in a 'for' loop
|
|
||||||
|
|
||||||
Function 'leaveblock' was generating "break" label before removing
|
|
||||||
variables from the closing block. If 'createlabel' created a 'close'
|
|
||||||
instruction (which it did when matching a goto/break that exited
|
|
||||||
the scope of an upvalue), that instruction would use the wrong level.
|
|
||||||
---
|
|
||||||
lparser.c | 16 ++++++++--------
|
|
||||||
testes/locals.lua | 20 ++++++++++++++++++++
|
|
||||||
2 files changed, 28 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lparser.c b/lparser.c
|
|
||||||
index a5cd55257..fe693b571 100644
|
|
||||||
--- a/src/lparser.c
|
|
||||||
+++ b/src/lparser.c
|
|
||||||
@@ -674,19 +674,19 @@ static void leaveblock (FuncState *fs) {
|
|
||||||
LexState *ls = fs->ls;
|
|
||||||
int hasclose = 0;
|
|
||||||
int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */
|
|
||||||
- if (bl->isloop) /* fix pending breaks? */
|
|
||||||
+ removevars(fs, bl->nactvar); /* remove block locals */
|
|
||||||
+ lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */
|
|
||||||
+ if (bl->isloop) /* has to fix pending breaks? */
|
|
||||||
hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0);
|
|
||||||
- if (!hasclose && bl->previous && bl->upval)
|
|
||||||
+ if (!hasclose && bl->previous && bl->upval) /* still need a 'close'? */
|
|
||||||
luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0);
|
|
||||||
- fs->bl = bl->previous;
|
|
||||||
- removevars(fs, bl->nactvar);
|
|
||||||
- lua_assert(bl->nactvar == fs->nactvar);
|
|
||||||
fs->freereg = stklevel; /* free registers */
|
|
||||||
ls->dyd->label.n = bl->firstlabel; /* remove local labels */
|
|
||||||
- if (bl->previous) /* inner block? */
|
|
||||||
- movegotosout(fs, bl); /* update pending gotos to outer block */
|
|
||||||
+ fs->bl = bl->previous; /* current block now is previous one */
|
|
||||||
+ if (bl->previous) /* was it a nested block? */
|
|
||||||
+ movegotosout(fs, bl); /* update pending gotos to enclosing block */
|
|
||||||
else {
|
|
||||||
- if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */
|
|
||||||
+ if (bl->firstgoto < ls->dyd->gt.n) /* still pending gotos? */
|
|
||||||
undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/testes/locals.lua b/testes/locals.lua
|
|
||||||
index ddb75054f..d50beaa52 100644
|
|
||||||
--- a/testes/locals.lua
|
|
||||||
+++ b/testes/locals.lua
|
|
||||||
@@ -360,6 +360,26 @@ do
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
+do
|
|
||||||
+ -- bug in 5.4.4: 'break' may generate wrong 'close' instruction when
|
|
||||||
+ -- leaving a loop block.
|
|
||||||
+
|
|
||||||
+ local closed = false
|
|
||||||
+
|
|
||||||
+ local o1 = setmetatable({}, {__close=function() closed = true end})
|
|
||||||
+
|
|
||||||
+ local function test()
|
|
||||||
+ for k, v in next, {}, nil, o1 do
|
|
||||||
+ local function f() return k end -- create an upvalue
|
|
||||||
+ break
|
|
||||||
+ end
|
|
||||||
+ assert(closed)
|
|
||||||
+ end
|
|
||||||
+
|
|
||||||
+ test()
|
|
||||||
+end
|
|
||||||
+
|
|
||||||
+
|
|
||||||
do print("testing errors in __close")
|
|
||||||
|
|
||||||
-- original error is in __close
|
|
118
luabugs7.patch
118
luabugs7.patch
@ -1,118 +0,0 @@
|
|||||||
From a1f77a234a053da46b06d5d4be00ffb30d3eb45b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
||||||
Date: Tue, 23 Aug 2022 16:06:23 -0300
|
|
||||||
Subject: [PATCH] Bug: set correct pause when (re)entering gen. collection.
|
|
||||||
|
|
||||||
---
|
|
||||||
lgc.c | 63 +++++++++++++++++++++++++++++------------------------------
|
|
||||||
1 file changed, 31 insertions(+), 32 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lgc.c b/lgc.c
|
|
||||||
index 42a73d813..317ea4508 100644
|
|
||||||
--- a/src/lgc.c
|
|
||||||
+++ b/src/lgc.c
|
|
||||||
@@ -1041,7 +1041,25 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
|
|
||||||
** =======================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
-static void setpause (global_State *g);
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+** Set the "time" to wait before starting a new GC cycle; cycle will
|
|
||||||
+** start when memory use hits the threshold of ('estimate' * pause /
|
|
||||||
+** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero,
|
|
||||||
+** because Lua cannot even start with less than PAUSEADJ bytes).
|
|
||||||
+*/
|
|
||||||
+static void setpause (global_State *g) {
|
|
||||||
+ l_mem threshold, debt;
|
|
||||||
+ int pause = getgcparam(g->gcpause);
|
|
||||||
+ l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */
|
|
||||||
+ lua_assert(estimate > 0);
|
|
||||||
+ threshold = (pause < MAX_LMEM / estimate) /* overflow? */
|
|
||||||
+ ? estimate * pause /* no overflow */
|
|
||||||
+ : MAX_LMEM; /* overflow; truncate to maximum */
|
|
||||||
+ debt = gettotalbytes(g) - threshold;
|
|
||||||
+ if (debt > 0) debt = 0;
|
|
||||||
+ luaE_setdebt(g, debt);
|
|
||||||
+}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -1285,6 +1303,15 @@ static void atomic2gen (lua_State *L, global_State *g) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+** Set debt for the next minor collection, which will happen when
|
|
||||||
+** memory grows 'genminormul'%.
|
|
||||||
+*/
|
|
||||||
+static void setminordebt (global_State *g) {
|
|
||||||
+ luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
** Enter generational mode. Must go until the end of an atomic cycle
|
|
||||||
** to ensure that all objects are correctly marked and weak tables
|
|
||||||
@@ -1297,6 +1324,7 @@ static lu_mem entergen (lua_State *L, global_State *g) {
|
|
||||||
luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
|
|
||||||
numobjs = atomic(L); /* propagates all and then do the atomic stuff */
|
|
||||||
atomic2gen(L, g);
|
|
||||||
+ setminordebt(g); /* set debt assuming next cycle will be minor */
|
|
||||||
return numobjs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1342,15 +1370,6 @@ static lu_mem fullgen (lua_State *L, global_State *g) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-/*
|
|
||||||
-** Set debt for the next minor collection, which will happen when
|
|
||||||
-** memory grows 'genminormul'%.
|
|
||||||
-*/
|
|
||||||
-static void setminordebt (global_State *g) {
|
|
||||||
- luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul));
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
** Does a major collection after last collection was a "bad collection".
|
|
||||||
**
|
|
||||||
@@ -1422,8 +1441,8 @@ static void genstep (lua_State *L, global_State *g) {
|
|
||||||
lu_mem numobjs = fullgen(L, g); /* do a major collection */
|
|
||||||
if (gettotalbytes(g) < majorbase + (majorinc / 2)) {
|
|
||||||
/* collected at least half of memory growth since last major
|
|
||||||
- collection; keep doing minor collections */
|
|
||||||
- setminordebt(g);
|
|
||||||
+ collection; keep doing minor collections. */
|
|
||||||
+ lua_assert(g->lastatomic == 0);
|
|
||||||
}
|
|
||||||
else { /* bad collection */
|
|
||||||
g->lastatomic = numobjs; /* signal that last collection was bad */
|
|
||||||
@@ -1449,26 +1468,6 @@ static void genstep (lua_State *L, global_State *g) {
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
-/*
|
|
||||||
-** Set the "time" to wait before starting a new GC cycle; cycle will
|
|
||||||
-** start when memory use hits the threshold of ('estimate' * pause /
|
|
||||||
-** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero,
|
|
||||||
-** because Lua cannot even start with less than PAUSEADJ bytes).
|
|
||||||
-*/
|
|
||||||
-static void setpause (global_State *g) {
|
|
||||||
- l_mem threshold, debt;
|
|
||||||
- int pause = getgcparam(g->gcpause);
|
|
||||||
- l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */
|
|
||||||
- lua_assert(estimate > 0);
|
|
||||||
- threshold = (pause < MAX_LMEM / estimate) /* overflow? */
|
|
||||||
- ? estimate * pause /* no overflow */
|
|
||||||
- : MAX_LMEM; /* overflow; truncate to maximum */
|
|
||||||
- debt = gettotalbytes(g) - threshold;
|
|
||||||
- if (debt > 0) debt = 0;
|
|
||||||
- luaE_setdebt(g, debt);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
** Enter first sweep phase.
|
|
||||||
** The call to 'sweeptolive' makes the pointer point to an object
|
|
148
luabugs8.patch
148
luabugs8.patch
@ -1,148 +0,0 @@
|
|||||||
From a1089b415a3f5c753aa1b40758ffdaf28d5701b0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
||||||
Date: Fri, 23 Sep 2022 10:41:16 -0300
|
|
||||||
Subject: [PATCH] Bug: 'utf8.codes' accepts spurious continuation bytes
|
|
||||||
|
|
||||||
---
|
|
||||||
lutf8lib.c | 27 ++++++++++++++++-----------
|
|
||||||
testes/utf8.lua | 12 +++++++++++-
|
|
||||||
2 files changed, 27 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lutf8lib.c b/lutf8lib.c
|
|
||||||
index e7bf098f6..3a5b9bc38 100644
|
|
||||||
--- a/src/lutf8lib.c
|
|
||||||
+++ b/src/lutf8lib.c
|
|
||||||
@@ -25,6 +25,9 @@
|
|
||||||
|
|
||||||
#define MAXUTF 0x7FFFFFFFu
|
|
||||||
|
|
||||||
+
|
|
||||||
+#define MSGInvalid "invalid UTF-8 code"
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits.
|
|
||||||
*/
|
|
||||||
@@ -35,7 +38,8 @@ typedef unsigned long utfint;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-#define iscont(p) ((*(p) & 0xC0) == 0x80)
|
|
||||||
+#define iscont(c) (((c) & 0xC0) == 0x80)
|
|
||||||
+#define iscontp(p) iscont(*(p))
|
|
||||||
|
|
||||||
|
|
||||||
/* from strlib */
|
|
||||||
@@ -65,7 +69,7 @@ static const char *utf8_decode (const char *s, utfint *val, int strict) {
|
|
||||||
int count = 0; /* to count number of continuation bytes */
|
|
||||||
for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */
|
|
||||||
unsigned int cc = (unsigned char)s[++count]; /* read next byte */
|
|
||||||
- if ((cc & 0xC0) != 0x80) /* not a continuation byte? */
|
|
||||||
+ if (!iscont(cc)) /* not a continuation byte? */
|
|
||||||
return NULL; /* invalid byte sequence */
|
|
||||||
res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
|
|
||||||
}
|
|
||||||
@@ -140,7 +144,7 @@ static int codepoint (lua_State *L) {
|
|
||||||
utfint code;
|
|
||||||
s = utf8_decode(s, &code, !lax);
|
|
||||||
if (s == NULL)
|
|
||||||
- return luaL_error(L, "invalid UTF-8 code");
|
|
||||||
+ return luaL_error(L, MSGInvalid);
|
|
||||||
lua_pushinteger(L, code);
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
@@ -190,16 +194,16 @@ static int byteoffset (lua_State *L) {
|
|
||||||
"position out of bounds");
|
|
||||||
if (n == 0) {
|
|
||||||
/* find beginning of current byte sequence */
|
|
||||||
- while (posi > 0 && iscont(s + posi)) posi--;
|
|
||||||
+ while (posi > 0 && iscontp(s + posi)) posi--;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
- if (iscont(s + posi))
|
|
||||||
+ if (iscontp(s + posi))
|
|
||||||
return luaL_error(L, "initial position is a continuation byte");
|
|
||||||
if (n < 0) {
|
|
||||||
while (n < 0 && posi > 0) { /* move back */
|
|
||||||
do { /* find beginning of previous character */
|
|
||||||
posi--;
|
|
||||||
- } while (posi > 0 && iscont(s + posi));
|
|
||||||
+ } while (posi > 0 && iscontp(s + posi));
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -208,7 +212,7 @@ static int byteoffset (lua_State *L) {
|
|
||||||
while (n > 0 && posi < (lua_Integer)len) {
|
|
||||||
do { /* find beginning of next character */
|
|
||||||
posi++;
|
|
||||||
- } while (iscont(s + posi)); /* (cannot pass final '\0') */
|
|
||||||
+ } while (iscontp(s + posi)); /* (cannot pass final '\0') */
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -226,15 +230,15 @@ static int iter_aux (lua_State *L, int strict) {
|
|
||||||
const char *s = luaL_checklstring(L, 1, &len);
|
|
||||||
lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2);
|
|
||||||
if (n < len) {
|
|
||||||
- while (iscont(s + n)) n++; /* skip continuation bytes */
|
|
||||||
+ while (iscontp(s + n)) n++; /* go to next character */
|
|
||||||
}
|
|
||||||
if (n >= len) /* (also handles original 'n' being negative) */
|
|
||||||
return 0; /* no more codepoints */
|
|
||||||
else {
|
|
||||||
utfint code;
|
|
||||||
const char *next = utf8_decode(s + n, &code, strict);
|
|
||||||
- if (next == NULL)
|
|
||||||
- return luaL_error(L, "invalid UTF-8 code");
|
|
||||||
+ if (next == NULL || iscontp(next))
|
|
||||||
+ return luaL_error(L, MSGInvalid);
|
|
||||||
lua_pushinteger(L, n + 1);
|
|
||||||
lua_pushinteger(L, code);
|
|
||||||
return 2;
|
|
||||||
@@ -253,7 +257,8 @@ static int iter_auxlax (lua_State *L) {
|
|
||||||
|
|
||||||
static int iter_codes (lua_State *L) {
|
|
||||||
int lax = lua_toboolean(L, 2);
|
|
||||||
- luaL_checkstring(L, 1);
|
|
||||||
+ const char *s = luaL_checkstring(L, 1);
|
|
||||||
+ luaL_argcheck(L, !iscontp(s), 1, MSGInvalid);
|
|
||||||
lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict);
|
|
||||||
lua_pushvalue(L, 1);
|
|
||||||
lua_pushinteger(L, 0);
|
|
||||||
diff --git a/testes/utf8.lua b/testes/utf8.lua
|
|
||||||
index 461e223c7..7472cfd05 100644
|
|
||||||
--- a/testes/utf8.lua
|
|
||||||
+++ b/testes/utf8.lua
|
|
||||||
@@ -97,9 +97,15 @@ do -- error indication in utf8.len
|
|
||||||
assert(not a and b == p)
|
|
||||||
end
|
|
||||||
check("abc\xE3def", 4)
|
|
||||||
- check("汉字\x80", #("汉字") + 1)
|
|
||||||
check("\xF4\x9F\xBF", 1)
|
|
||||||
check("\xF4\x9F\xBF\xBF", 1)
|
|
||||||
+ -- spurious continuation bytes
|
|
||||||
+ check("汉字\x80", #("汉字") + 1)
|
|
||||||
+ check("\x80hello", 1)
|
|
||||||
+ check("hel\x80lo", 4)
|
|
||||||
+ check("汉字\xBF", #("汉字") + 1)
|
|
||||||
+ check("\xBFhello", 1)
|
|
||||||
+ check("hel\xBFlo", 4)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- errors in utf8.codes
|
|
||||||
@@ -112,12 +118,16 @@ do
|
|
||||||
end
|
|
||||||
errorcodes("ab\xff")
|
|
||||||
errorcodes("\u{110000}")
|
|
||||||
+ errorcodes("in\x80valid")
|
|
||||||
+ errorcodes("\xbfinvalid")
|
|
||||||
+ errorcodes("αλφ\xBFα")
|
|
||||||
|
|
||||||
-- calling interation function with invalid arguments
|
|
||||||
local f = utf8.codes("")
|
|
||||||
assert(f("", 2) == nil)
|
|
||||||
assert(f("", -1) == nil)
|
|
||||||
assert(f("", math.mininteger) == nil)
|
|
||||||
+
|
|
||||||
end
|
|
||||||
|
|
||||||
-- error in initial position for offset
|
|
102
luabugs9.patch
102
luabugs9.patch
@ -1,102 +0,0 @@
|
|||||||
From 1e64c1391f9a14115b5cc82066dbf545ae73ee27 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
||||||
Date: Tue, 25 Oct 2022 16:44:06 -0300
|
|
||||||
Subject: [PATCH] Bug: stack overflow with nesting of coroutine.close
|
|
||||||
|
|
||||||
---
|
|
||||||
lcorolib.c | 4 ++--
|
|
||||||
lstate.c | 3 ++-
|
|
||||||
ltests.c | 2 +-
|
|
||||||
lua.h | 2 +-
|
|
||||||
manual/manual.of | 7 ++++++-
|
|
||||||
testes/cstack.lua | 26 ++++++++++++++++++++++++++
|
|
||||||
6 files changed, 38 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/lcorolib.c b/lcorolib.c
|
|
||||||
index 785a1e81a..40b880b14 100644
|
|
||||||
--- a/src/lcorolib.c
|
|
||||||
+++ b/src/lcorolib.c
|
|
||||||
@@ -76,7 +76,7 @@ static int luaB_auxwrap (lua_State *L) {
|
|
||||||
if (l_unlikely(r < 0)) { /* error? */
|
|
||||||
int stat = lua_status(co);
|
|
||||||
if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */
|
|
||||||
- stat = lua_resetthread(co); /* close its tbc variables */
|
|
||||||
+ stat = lua_resetthread(co, L); /* close its tbc variables */
|
|
||||||
lua_assert(stat != LUA_OK);
|
|
||||||
lua_xmove(co, L, 1); /* move error message to the caller */
|
|
||||||
}
|
|
||||||
@@ -172,7 +172,7 @@ static int luaB_close (lua_State *L) {
|
|
||||||
int status = auxstatus(L, co);
|
|
||||||
switch (status) {
|
|
||||||
case COS_DEAD: case COS_YIELD: {
|
|
||||||
- status = lua_resetthread(co);
|
|
||||||
+ status = lua_resetthread(co, L);
|
|
||||||
if (status == LUA_OK) {
|
|
||||||
lua_pushboolean(L, 1);
|
|
||||||
return 1;
|
|
||||||
diff --git a/lstate.c b/lstate.c
|
|
||||||
index 1ffe1a0f7..4b5c10008 100644
|
|
||||||
--- a/src/lstate.c
|
|
||||||
+++ b/src/lstate.c
|
|
||||||
@@ -343,9 +343,10 @@ int luaE_resetthread (lua_State *L, int status) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
-LUA_API int lua_resetthread (lua_State *L) {
|
|
||||||
+LUA_API int lua_resetthread (lua_State *L, lua_State *from) {
|
|
||||||
int status;
|
|
||||||
lua_lock(L);
|
|
||||||
+ L->nCcalls = (from) ? getCcalls(from) : 0;
|
|
||||||
status = luaE_resetthread(L, L->status);
|
|
||||||
lua_unlock(L);
|
|
||||||
return status;
|
|
||||||
diff --git a/lua.h b/lua.h
|
|
||||||
index 219784cc0..bfba4d1e1 100644
|
|
||||||
--- a/src/lua.h
|
|
||||||
+++ b/src/lua.h
|
|
||||||
@@ -153,7 +153,7 @@ extern const char lua_ident[];
|
|
||||||
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
|
|
||||||
LUA_API void (lua_close) (lua_State *L);
|
|
||||||
LUA_API lua_State *(lua_newthread) (lua_State *L);
|
|
||||||
-LUA_API int (lua_resetthread) (lua_State *L);
|
|
||||||
+LUA_API int (lua_resetthread) (lua_State *L, lua_State *from);
|
|
||||||
|
|
||||||
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
|
|
||||||
|
|
||||||
diff --git a/testes/cstack.lua b/testes/cstack.lua
|
|
||||||
index ca76c8729..97afe9fd0 100644
|
|
||||||
--- a/testes/cstack.lua
|
|
||||||
+++ b/testes/cstack.lua
|
|
||||||
@@ -84,6 +84,32 @@ do -- bug in 5.4.0
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
+do -- bug since 5.4.0
|
|
||||||
+ local count = 0
|
|
||||||
+ print("chain of 'coroutine.close'")
|
|
||||||
+ -- create N coroutines forming a list so that each one, when closed,
|
|
||||||
+ -- closes the previous one. (With a large enough N, previous Lua
|
|
||||||
+ -- versions crash in this test.)
|
|
||||||
+ local coro = false
|
|
||||||
+ for i = 1, 1000 do
|
|
||||||
+ local previous = coro
|
|
||||||
+ coro = coroutine.create(function()
|
|
||||||
+ local cc <close> = setmetatable({}, {__close=function()
|
|
||||||
+ count = count + 1
|
|
||||||
+ if previous then
|
|
||||||
+ assert(coroutine.close(previous))
|
|
||||||
+ end
|
|
||||||
+ end})
|
|
||||||
+ coroutine.yield() -- leaves 'cc' pending to be closed
|
|
||||||
+ end)
|
|
||||||
+ assert(coroutine.resume(coro)) -- start it and run until it yields
|
|
||||||
+ end
|
|
||||||
+ local st, msg = coroutine.close(coro)
|
|
||||||
+ assert(not st and string.find(msg, "C stack overflow"))
|
|
||||||
+ print("final count: ", count)
|
|
||||||
+end
|
|
||||||
+
|
|
||||||
+
|
|
||||||
do
|
|
||||||
print("nesting of resuming yielded coroutines")
|
|
||||||
local count = 0
|
|
@ -1,6 +1,10 @@
|
|||||||
|
---
|
||||||
|
testes/main.lua | 12 ++++++------
|
||||||
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
--- a/testes/main.lua
|
--- a/testes/main.lua
|
||||||
+++ b/testes/main.lua
|
+++ b/testes/main.lua
|
||||||
@@ -47,7 +47,7 @@
|
@@ -47,7 +47,7 @@ local function checkprogout (s)
|
||||||
assert(string.sub(s, -1) == "\n")
|
assert(string.sub(s, -1) == "\n")
|
||||||
local t = getoutput()
|
local t = getoutput()
|
||||||
for line in string.gmatch(s, ".-\n") do
|
for line in string.gmatch(s, ".-\n") do
|
||||||
@ -9,7 +13,7 @@
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -307,11 +307,11 @@
|
@@ -367,11 +367,11 @@ a = 2
|
||||||
]]
|
]]
|
||||||
RUN([[lua -e "%s" -i < %s > %s]], prompt, prog, out)
|
RUN([[lua -e "%s" -i < %s > %s]], prompt, prog, out)
|
||||||
local t = getoutput()
|
local t = getoutput()
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
---
|
||||||
|
src/ldebug.h | 2 +-
|
||||||
|
src/lmem.h | 2 +-
|
||||||
|
src/lundump.h | 2 +-
|
||||||
|
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
--- a/src/ldebug.h
|
--- a/src/ldebug.h
|
||||||
+++ b/src/ldebug.h
|
+++ b/src/ldebug.h
|
||||||
@@ -36,7 +36,7 @@
|
@@ -36,7 +36,7 @@
|
||||||
@ -9,6 +15,17 @@
|
|||||||
LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n,
|
LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n,
|
||||||
StkId *pos);
|
StkId *pos);
|
||||||
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
|
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
|
||||||
|
--- a/src/lmem.h
|
||||||
|
+++ b/src/lmem.h
|
||||||
|
@@ -81,7 +81,7 @@ LUAI_FUNC void *luaM_realloc_ (lua_State
|
||||||
|
size_t size);
|
||||||
|
LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize,
|
||||||
|
size_t size);
|
||||||
|
-LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize);
|
||||||
|
+LUA_API void luaM_free_ (lua_State *L, void *block, size_t osize);
|
||||||
|
LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems,
|
||||||
|
int *size, int size_elem, int limit,
|
||||||
|
const char *what);
|
||||||
--- a/src/lundump.h
|
--- a/src/lundump.h
|
||||||
+++ b/src/lundump.h
|
+++ b/src/lundump.h
|
||||||
@@ -30,7 +30,7 @@
|
@@ -30,7 +30,7 @@
|
||||||
@ -20,14 +37,3 @@
|
|||||||
void* data, int strip);
|
void* data, int strip);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
--- a/src/lmem.h
|
|
||||||
+++ b/src/lmem.h
|
|
||||||
@@ -81,7 +81,7 @@
|
|
||||||
size_t size);
|
|
||||||
LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize,
|
|
||||||
size_t size);
|
|
||||||
-LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize);
|
|
||||||
+LUA_API void luaM_free_ (lua_State *L, void *block, size_t osize);
|
|
||||||
LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems,
|
|
||||||
int *size, int size_elem, int limit,
|
|
||||||
const char *what);
|
|
||||||
|
Loading…
Reference in New Issue
Block a user