[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: LUA fails to parse expression with big and nested lists.
- From: Andrey Dobrovolsky <ken@...>
- Date: Sat, 7 Oct 2023 00:27:52 +0300
Hi,
I want to propose much better solution of the big nested lists parsing
problem.
The circumstances causing register pool exhaustion may be described as
the list part followed by the next level constructor. The solution may
be very simple and efficient - constructor as the list element must
force storing of already processed list items. Such solution is easy and
discards all the limitations on the nesting depth but "C stack overflow".
The patch for lua-5.4.6 attached.
Original
readelf -s liblua.a | grep constructor
59: 000032b0 670 FUNC LOCAL DEFAULT 7 constructor
Patched
readelf -s liblua.a | grep constructor
59: 000032b0 715 FUNC LOCAL DEFAULT 7 constructor
Best regards!
Andrey Dobrovolsky
--- lparser.c.orig 2023-05-02 23:02:30.000000000 +0300
+++ lparser.c 2023-10-06 23:44:27.488798829 +0300
@@ -865,11 +865,11 @@
}
-static void closelistfield (FuncState *fs, ConsControl *cc) {
+static void closelistfield (FuncState *fs, ConsControl *cc, int flush) {
if (cc->v.k == VVOID) return; /* there is no list item */
luaK_exp2nextreg(fs, &cc->v);
cc->v.k = VVOID;
- if (cc->tostore == LFIELDS_PER_FLUSH) {
+ if ((cc->tostore == LFIELDS_PER_FLUSH) || flush){
luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
cc->na += cc->tostore;
cc->tostore = 0; /* no more items pending */
@@ -939,7 +939,7 @@
do {
lua_assert(cc.v.k == VVOID || cc.tostore > 0);
if (ls->t.token == '}') break;
- closelistfield(fs, &cc);
+ closelistfield(fs, &cc, ls->t.token == '{');
field(ls, &cc);
} while (testnext(ls, ',') || testnext(ls, ';'));
check_match(ls, '}', '{', line);