Download the PHP package developgravity/lua-ext without Composer

On this page you can find all versions of the php package developgravity/lua-ext. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package lua-ext

LuaExt

CI Lint Packagist

A PHP extension that embeds a vendored, patched Lua 5.5.1 interpreter to run untrusted, user-supplied Lua code safely: portable CPU/wall-clock/memory limits enforced inside the interpreter itself, and capability-based trust configuration.

Package: developgravity/lua-ext · extension name luaext · namespace DevelopGravity\LuaExt · license MIT · PHP 8.5+.

Status: a young package — please report anything you hit. Every capability the extension defines is implemented, and the .phpt suite (162 tests and counting — make test prints the live figure) covers compilation, the PHP↔Lua boundary, the CPU/wall-clock/memory/output budgets, the capability-gated standard library, coroutines, the virtual filesystem, require(), the profiler, Lua language conformance, and the adversarial cases where a script tries to catch its own limit breach.

What it has not had is age: no external security audit, and not yet the variety of real workloads that shakes out the last defects in an extension like this. If something misbehaves — a wrong answer, a crash, a limit that did not hold — open an issue. For anything that looks like a sandbox escape, please use the private channel in SECURITY.md instead.

Why this exists

Credit first

LuaSandbox has been running untrusted, user-submitted Lua in front of one of the busiest sites on the internet since 2012. Every Wikipedia infobox, citation and navbox is a Scribunto module executing inside it. That is a decade of adversarial exposure at a scale no new project can claim, and the ideas it proved are the ones this extension is built on: that the sandbox belongs inside the interpreter rather than wrapped around it, that limits have to be enforced where the instructions actually execute, and that a host has to assemble the standard library it wants rather than subtract from the one it got. LuaExt is downstream of that thinking in every way that matters. Its authors solved the hard part first, and they solved it in public.

So why not contribute this there?

Two reasons, and neither is a criticism of the work.

These changes would not be good for that project's users. Moving Lua 5.1 → 5.5 changes the language under every Scribunto module on every wiki running it. Adding a virtual filesystem hands a capability to an environment that has deliberately spent a decade having none. What is a feature here would be a compatibility event and a wider attack surface there. A project is allowed to have a narrower mandate than the thing you want to build, and LuaSandbox's mandate is MediaWiki — correctly so.

And the contribution path is built for a different kind of change. LuaSandbox is developed on Wikimedia Gerrit, not GitHub; the GitHub presence is a read-only mirror. Contributing means a Wikimedia developer account, the Gerrit patchset workflow, and review by maintainers whose priority is — rightly — what serves the wikis. That is a reasonable amount of process for a bug fix. For a rewrite that swaps the vendored interpreter, replaces the limit architecture and changes the entire public API, it is the wrong shape of contribution, aimed at the wrong project, sent through a pipeline meant for something else. The realistic outcome of proposing it upstream is a long conversation ending in "this is a different extension" — so it starts as one.

Hence: a separate extension, MIT-licensed, developed on GitHub, owing no wiki a compatibility promise.

What that freedom bought

  1. Limits that are enforced on every platform, or say they aren't. LuaSandbox's setCPULimit() is built on Linux-only POSIX timers; on macOS and Windows it compiles to a stub, so the call succeeds and the limit is never enforced. That is a defensible trade for an extension whose production target is Linux, and a trap for anyone else. LuaExt enforces CPU and wall-clock budgets on all three platforms, and Sandbox::features() reports the real per-platform enforcement level and clock resolution, so a host is never silently unprotected — see platform support.
  2. A current Lua, vendored and patched in-tree. LuaSandbox targets Lua 5.1. LuaExt vendors and patches Lua 5.5.1 directly — never the system liblua — so the sandboxing checks live in the interpreter's hot loops instead of being bolted on from outside, which is why they cost 0–5% rather than +55%.
  3. Coroutines and a filesystem, because the interrupt can follow them. LuaSandbox removed coroutines entirely because its timeout hook could not span them. LuaExt exposes them by default, capped and strictly call-scoped — the interrupt follows whichever coroutine is running, so work cannot be hidden in one. It also adds a host-implemented virtual filesystem so scripts can do io-style work against storage the host controls, with every path canonicalised and every quota enforced before a backend is called.

This is a from-scratch rewrite, not a fork, and there is no compatibility shim — see migrating from LuaSandbox.

Requirements

Install

Via PIE:

The version suffix is required, and while the releases are still release candidates it has to name one explicitly — a bare pie install developgravity/lua-ext looks for a stable version and finds none. Linux and macOS build from source; Windows x64 installs the prebuilt DLL attached to that release. Building from a checkout (phpize && ./configure && make) works too and is what CI exercises.

dev-develop tracks the branch tip and is there for trying unreleased work — pin a commit (dev-develop#<sha>) if you deploy it, or you will silently move with the branch.

For IDE autocomplete and static analysis without loading the extension, add the stub package as a dev dependency:

It carries the same two stub files this repository generates its C arginfo from, so the signatures it describes cannot drift from the compiled binary. Autoloading is deliberately absent — the files declare real classes, and loading them alongside the installed extension is a fatal redeclare. PhpStorm needs no configuration; PHPStan and Psalm want the files listed as stubs, which the package's README spells out.

Versioning

Semantic versioning, with plain tags and no v prefix (1.2.0, not v1.2.0).

The promise that matters for a sandbox is what a non-major upgrade is allowed to do, so it is worth stating precisely:

Two things are deliberately outside the guarantee, because pinning them would freeze the sandbox rather than the API:

Anything the API does that this file, docs/configuration.md or the stubs do not describe is unspecified, not promised — internal struct layouts, message wording, SandboxStats field values, and the order of anything not documented as ordered.

Quick start

Exposing an existing object uses registerObject() with the #[LuaMethod] attribute — only methods explicitly marked (or explicitly allowlisted) become callable from Lua:

Wrapping host objects

When instances themselves should cross, registerClass() turns them into unforgeable userdata proxies: scripts hold many independent objects, call marked methods with Lua's colon syntax, construct through marked statics or .new, chain fluently, and use mapped operators — with no Lua-side glue at all. A #[LuaClass] attribute carries the configuration on a wrapper class you author (PHP attributes cannot attach to inherited methods, which is exactly what the class-level maps are for), and SandboxConfig::$classes grants it at construction, written once for every sandbox built from that config:

Three things wrapper authors should know. Subclass matching walks the instance's own parent chain, so a plain vendor instance made elsewhere in host code is not an instance of your wrapper and will not wrap under its registration — construct the wrapper class at the boundary, or register the vendor class directly with the array parameters. Operator validation checks arity, never parameter types — map methods that genuinely accept the registered instance. And the wrapped objects' memory is host memory: it is deliberately not charged to Limits::$memoryBytes (PHP's own memory_limit is the bound, since object allocation goes through ZendMM), with stats()->liveObjectProxies as the observability hook for a script hoarding instances.

new Sandbox() with no arguments is the untrusted baseline — every capability closed except coroutines, os.time, debug.traceback and utf8, and every limit at its default. There is no separate "safe mode" flag to forget. Object identity never crosses the boundary uninvited: registerObject() hands Lua bound method callables, and only classes explicitly registered with registerClass() cross as proxies — unforgeable userdata whose reachable surface is exactly the methods you marked.

Documentation

Using it

Choosing how to run it

Working on it

Trusting it

License

MIT. See LICENSE. The vendored Lua interpreter under third_party/lua-5.5.1/ keeps its own upstream MIT license file — Lua is Copyright © Lua.org, PUC-Rio, distributed under the same MIT terms as this project.


All versions of lua-ext with dependencies

PHP Build Version
Package Version
Requires php Version >=8.5
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package developgravity/lua-ext contains the following files

Loading the files please wait ...