On Thu Sep 29, 2022 at 11:58 PM CEST, Werner LEMBERG wrote: > > Please unpack the attached tarball and call `./zzz.sh`. On my > openSUSE box using a current SVN version of TeXLive, this crashes with > a segfault.
I think I found the issue and have a fix (attached). (Hans CC'd: I believe this also applies to LuaMetaTeX.) The segfaults are in the calls to Lua C API from the function `load_hyphenation`, which gets called as a result of `\hyphenation`. The issue is that before pushing to the Lua stack one has to make sure there is enough free space there (by calling `lua_checkstack`) -- in this case `load_hyphenation` pushes at most 3 values to the stack. Reserving the space on the stack should fix the issue. But I am fairly sure that the stack would (usually) have at least the 3 needed free slots -- after all LuaTeX doesn't reserve stack space too often, and other things work just fine. This unveiled another problem: `load_hyphenation` never pops the table it appends to, so many calls to it slowly exhaust the stack. A call to `lua_pop` is needed at the end. Patch that adds `lua_checkstack` and `lua_pop` is attached. Note that the issue exhibits itself so severely because the file `hyphenation.texi` does `\hyphenation` for each word separately, this is less efficient and unnecessary, when `\hyphenation` can process many words just fine. Michal PS: I performed the analysis on a slightly older version of LuaTeX and in a different build environment, though I think the analysis and conclusions still apply.
diff --git a/source/texk/web2c/luatexdir/lang/texlang.c b/source/texk/web2c/luatexdir/lang/texlang.c index a0d067251..f8c60e548 100644 --- a/source/texk/web2c/luatexdir/lang/texlang.c +++ b/source/texk/web2c/luatexdir/lang/texlang.c @@ -287,6 +287,7 @@ void load_hyphenation(struct tex_language *lang, const unsigned char *buff) int id ; if (lang == NULL) return; + lua_checkstack(Luas, 3); if (lang->exceptions == 0) { lua_newtable(Luas); lang->exceptions = luaL_ref(Luas, LUA_REGISTRYINDEX); @@ -314,6 +315,7 @@ void load_hyphenation(struct tex_language *lang, const unsigned char *buff) } } } + lua_pop(Luas, 1); } void clear_hyphenation(struct tex_language *lang)