lua: drop compatibility to 5.1 to allow for luajit

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1192>
This commit is contained in:
Peter Hutterer 2025-07-15 14:39:30 +10:00
parent 9e37bc0cfa
commit 2723cadaeb
6 changed files with 58 additions and 48 deletions

View file

@ -98,11 +98,11 @@ variables:
# See the documentation here: #
# https://wayland.freedesktop.org/libinput/doc/latest/building.html #
###############################################################################
FEDORA_PACKAGES: 'git-core gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx_rtd_theme python3-pytest-xdist libwacom-devel cairo-devel gtk4-devel glib2-devel mtdev-devel diffutils wayland-protocols-devel black clang clang-tools-extra jq rpmdevtools valgrind systemd-udev qemu-img qemu-system-x86-core qemu-system-aarch64-core jq python3-click python3-rich virtme-ng lua-devel'
DEBIAN_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev curl lua5.4-dev'
UBUNTU_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev lua5.4-dev'
ARCH_PACKAGES: 'git gcc pkgconfig meson check libsystemd libevdev python-pytest-xdist libwacom gtk4 mtdev diffutils lua'
ALPINE_PACKAGES: 'git gcc build-base pkgconfig meson check-dev eudev-dev libevdev-dev libwacom-dev cairo-dev gtk4.0-dev mtdev-dev bash lua5.4-dev'
FEDORA_PACKAGES: 'git-core gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx_rtd_theme python3-pytest-xdist libwacom-devel cairo-devel gtk4-devel glib2-devel mtdev-devel diffutils wayland-protocols-devel black clang clang-tools-extra jq rpmdevtools valgrind systemd-udev qemu-img qemu-system-x86-core qemu-system-aarch64-core jq python3-click python3-rich virtme-ng luajit-devel'
DEBIAN_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev curl libluajit-5.1-dev'
UBUNTU_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev libluajit-5.1-dev'
ARCH_PACKAGES: 'git gcc pkgconfig meson check libsystemd libevdev python-pytest-xdist libwacom gtk4 mtdev diffutils luajit'
ALPINE_PACKAGES: 'git gcc build-base pkgconfig meson check-dev eudev-dev libevdev-dev libwacom-dev cairo-dev gtk4.0-dev mtdev-dev bash luajit-dev'
FREEBSD_PACKAGES: 'git pkgconf meson libepoll-shim libudev-devd libevdev libwacom gtk3 libmtdev bash wayland'
############################ end of package lists #############################
@ -110,12 +110,12 @@ variables:
# changing these will force rebuilding the associated image
# Note: these tags have no meaning and are not tied to a particular
# libinput version
FEDORA_TAG: '2025-05-20.0'
DEBIAN_TAG: '2025-05-20.0'
UBUNTU_TAG: '2025-05-20.0'
ARCH_TAG: '2025-05-20.0'
ALPINE_TAG: '2025-05-20.0'
FREEBSD_TAG: '2025-05-20.0'
FEDORA_TAG: '2025-08-01.0'
DEBIAN_TAG: '2025-08-01.0'
UBUNTU_TAG: '2025-08-01.0'
ARCH_TAG: '2025-08-01.0'
ALPINE_TAG: '2025-08-01.0'
FREEBSD_TAG: '2025-08-01.0'
FDO_UPSTREAM_REPO: libinput/libinput

View file

@ -3,7 +3,7 @@
#
# We're happy to rebuild all containers when one changes.
.default_tag: &default_tag '2025-05-20.0'
.default_tag: &default_tag '2025-08-01.0'
distributions:
- name: fedora
@ -50,7 +50,7 @@ distributions:
- python3-click
- python3-rich
- virtme-ng
- lua-devel
- luajit-devel
- name: debian
tag: *default_tag
versions:
@ -76,7 +76,7 @@ distributions:
- libglib2.0-dev
- libmtdev-dev
- curl # for the coverity job
- lua5.4-dev
- libluajit-5.1-dev
- name: ubuntu
tag: *default_tag
versions:
@ -101,7 +101,7 @@ distributions:
- libgtk-3-dev
- libglib2.0-dev
- libmtdev-dev
- lua5.4-dev
- libluajit-5.1-dev
- name: arch
tag: *default_tag
versions:
@ -119,7 +119,7 @@ distributions:
- gtk4
- mtdev
- diffutils
- lua
- luajit
build:
extra_variables:
- "MESON_ARGS: '-Ddocumentation=false'" # python-recommonmark is no longer in the repos
@ -140,7 +140,7 @@ distributions:
- gtk4.0-dev
- mtdev-dev
- bash
- lua5.4-dev
- luajit-dev
build:
extra_variables:
- "MESON_ARGS: '-Ddocumentation=false' # alpine does not have python-recommonmark"

View file

@ -9,7 +9,7 @@ of devices. For example, a plugin may add or remove axes and/or buttons on a
device and/or modify the event stream seen by this device before it is passed
to libinput.
Plugins are implemented in `Lua <https://www.lua.org/>`_ (version 5.4 or later)
Plugins are implemented in `Lua <https://www.lua.org/>`_ (version 5.1)
and are typically loaded from ``/usr/lib{64}/libinput/plugins`` and
``/etc/libinput/plugins``. Plugins are loaded in alphabetical order and where
multiple plugins share the same file name, the one in the highest precedence
@ -20,7 +20,7 @@ Plugins are run sequentially in ascending sort-order (i.e. ``00-foo.lua`` runs
before ``10-bar.lua``) and each plugin sees the state left by any previous
plugins.
See the `Lua Reference manual <https://www.lua.org/manual/5.4/manual.html>`_ for
See the `Lua Reference manual <https://www.lua.org/manual/5.1/manual.html>`_ for
details on the Lua language.
.. note:: Plugins are **not** loaded by default, it is up to the compositor

View file

@ -168,8 +168,7 @@ dep_libevdev = dependency('libevdev', version: '>= 1.10.0')
dep_lm = cc.find_library('m', required : false)
dep_rt = cc.find_library('rt', required : false)
dep_lua = dependency('lua-5.4', 'lua5.4', 'lua',
version : '>= 5.4',
dep_lua = dependency(get_option('lua-interpreter'),
required : get_option('lua-plugins'))
have_lua = dep_lua.found()
config_h.set10('HAVE_LUA', have_lua)
@ -184,6 +183,11 @@ summary({
section : 'Plugins',
bool_yn : true)
if have_lua
summary({'Lua Interpreter' : get_option('lua-interpreter')},
section : 'Plugins')
endif
# Include directories
includes_include = include_directories('include')
includes_src = include_directories('src')

View file

@ -46,3 +46,7 @@ option('lua-plugins',
type: 'feature',
value: 'auto',
description: 'Enable support for Lua plugins')
option('lua-interpreter',
type: 'string',
value: 'luajit',
description: 'The Lua interpreter to use (pkgconfig name)')

View file

@ -284,7 +284,18 @@ libinput_lua_pcall(struct libinput_lua_plugin *plugin, int narg, int nres)
{
lua_State *L = plugin->L;
int rc = lua_pcall(L, narg, nres, 0);
lua_pushvalue(L, -(narg + 1)); /* Copy the function */
lua_pushvalue(L, plugin->sandbox_table_idx);
/* Now set the sandbox environment for the function we're about to call */
int rc = lua_setfenv(L, -2) == 1 ? LUA_OK : LUA_ERRRUN;
if (rc == LUA_OK) {
/* Replace original function with sandboxed one */
lua_replace(L, -(narg + 2));
/* Now call the function */
rc = lua_pcall(L, narg, nres, 0);
} else {
lua_pushstring(L, "Failed to set up sandbox");
}
if (rc != LUA_OK) {
auto libinput_plugin = plugin->parent;
const char *errormsg = lua_tostring(L, -1);
@ -1114,20 +1125,6 @@ libinput_lua_plugin_run(struct libinput_plugin *libinput_plugin)
{
struct libinput_lua_plugin *plugin =
libinput_plugin_get_user_data(libinput_plugin);
struct lua_State *L = plugin->L;
/* Main entry point into the plugin, so we need to push our sandbox
* as _ENV. This only needs to be done here because all other entry
* points into the Lua script are callbacks that are set up during
* this run (and thus share the _ENV)
*/
lua_pushvalue(L, plugin->sandbox_table_idx);
const char *upval = lua_setupvalue(L, -2, 1);
if (!upval || !streq(upval, "_ENV")) {
plugin_log_bug_libinput(libinput_plugin, "Failed to set up sandbox\n");
libinput_plugin_unregister(libinput_plugin);
return;
}
if (libinput_lua_pcall(plugin, 0, 0) && !plugin->register_called) {
plugin_log_bug(libinput_plugin,
@ -1214,7 +1211,7 @@ libinput_lua_plugin_init_lua(struct libinput *libinput,
if (!L)
return NULL;
/* This will be our _ENV later, see libinput_lua_pcall */
/* This will be our our global env later, see libinput_lua_pcall() */
lua_newtable(L);
int sandbox_table_idx = lua_gettop(L);
plugin->sandbox_table_idx = sandbox_table_idx;
@ -1227,32 +1224,36 @@ libinput_lua_plugin_init_lua(struct libinput *libinput,
* all have their own individual sandbox.
*/
luaL_requiref(L, LUA_GNAME, luaopen_base, 0);
luaopen_base(L);
static const char *allowed_funcs[] = {
"assert", "error", "ipairs", "next", "pcall", "pairs", "pairs",
"print", "warn", "tonumber", "tostring", "type", "xpcall",
"assert", "error", "ipairs", "next", "pcall", "pairs",
"print", "tonumber", "tostring", "type", "unpack", "xpcall",
};
ARRAY_FOR_EACH(allowed_funcs, func) {
lua_getfield(L, -1, *func);
lua_getglobal(L, *func);
lua_setfield(L, sandbox_table_idx, *func);
}
/* Math is fine as a whole */
luaL_requiref(L, LUA_MATHLIBNAME, luaopen_math, 0);
luaopen_math(L);
lua_getglobal(L, "math");
lua_setfield(L, sandbox_table_idx, "math");
/* Table is fine as a whole */
luaL_requiref(L, LUA_TABLIBNAME, luaopen_table, 0);
luaopen_table(L);
lua_getglobal(L, "table");
lua_setfield(L, sandbox_table_idx, "table");
/* Table is fine as a whole */
luaL_requiref(L, LUA_STRLIBNAME, luaopen_table, 0);
/* String is fine as a whole */
luaopen_string(L);
lua_getglobal(L, "string");
lua_setfield(L, sandbox_table_idx, "string");
/* Override metatable to prevent access to unregistered globals */
lua_pushvalue(L, sandbox_table_idx);
lua_newtable(L);
lua_setfield(L, -2, "__index");
lua_pushstring(L, "__index");
lua_pushnil(L);
lua_settable(L, -3);
lua_setmetatable(L, sandbox_table_idx);
/* Our objects */
@ -1260,7 +1261,8 @@ libinput_lua_plugin_init_lua(struct libinput *libinput,
evdevdevice_init(L);
/* Our globals */
luaL_newlib(L, log_funcs);
lua_newtable(L);
luaL_register(L, "log", log_funcs);
lua_setfield(L, sandbox_table_idx, "log");
libinput_lua_init_evdev_global(L, sandbox_table_idx);