lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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);