feat(stdlib): implement the os standard library#289
Conversation
Add a sandbox-safe `os` library so Lua code that calls os.clock, os.time, os.date and friends no longer raises a runtime type error on a nil `os` global. Functions: os.time (current epoch or from a date table), os.clock, os.difftime, os.date (strftime-style formats plus *t / !*t broken-down tables, ! selecting UTC), os.getenv, os.setlocale (no-op reporting the C locale), os.tmpname, and os.exit. The high-level Lua API already listed os.getenv/os.exit/os.tmpname/os.execute/os.remove/os.rename in its default sandbox, so those stay blocked unless explicitly allowed. This unblocks the os section of the all.lua suite harness; the remaining harness body (dofile/loadfile/string.dump/coroutine.wrap and io.open post-run summary) stays skipped via narrowed line ranges. Plan: A21a Closes #259
Review: feat(stdlib): implement the os standard librarySolid, well-scoped PR. Conventions are clean: subsystem scope ( A few things to address: Major —
|
os.clock computed monotonic_time - boot_offset(), but BEAM evaluates the left operand first while boot_offset() lazily seeds the origin a few ns later, producing a small negative value on the first call. Read the offset before the current time and clamp the elapsed value at zero. Pin the non-negative contract in the os.clock regression test, document that local time equals UTC in the timezone-less sandbox, and align the plan frontmatter issue with the issue this PR closes. Closes #280
| name = Path.join(System.tmp_dir() || "/tmp", "lua_#{:erlang.unique_integer([:positive])}") | ||
| {[name], state} |
There was a problem hiding this comment.
Noting that in the future we don't want this as we will rely on VFS for this behavior. Let's leave a comment here to notate future improvement. We also want a VFS tracking ticket for milestone 1.0.0
|
All review points are resolved on the branch:
Branch is mergeable/clean against current main. |
os.tmpname currently resolves against the host filesystem via System.tmp_dir/0. Once the VFS layer lands it should resolve against the sandboxed virtual filesystem so the VM never touches host paths.
|
Addressed the On the VFS tracking ticket for milestone 1.0.0: I have not created it (that is outside what I can action here) — flagging so it can be opened separately. The four earlier review points (negative |
Merge main and rebuild the constructs.lua triage on top of it. The os stdlib (#289) and debug.getinfo name resolution (#290) both landed, so the debug.getinfo block (line 226), the os.time assignment (line 237), and the GLOB1 concat (line 248) all pass now and no longer need skipping. Empirically re-triaged constructs.lua against the current tree: the only remaining failures are the short-circuit harness (284..299, level=4 combination explosion exceeds the test timeout) and the checkload block (302..311, load() error messages do not contain the expected 'expected'/'too long' substrings). Replace the single 232..313 entry with these two narrowed, disjoint ranges. Drops the duplicate A43-os-stdlib.md plan (the os work shipped via A43-os-library.md / #289) and the debug.getinfo name pinning test (superseded by the tests #290 shipped on main). Plan: A26
Goal
Implement a sandbox-safe Lua 5.3
osstandard library so code that callsos.clock,os.time,os.date, etc. no longer raises a runtime type error on a nilosglobal.Plan:
.agents/plans/A43-os-library.md(renamed from A21a during workflow recovery). Adds the side-effect-freeosstandard library (os.time/os.date/os.clock/os.difftime+ safeos.getenvstub).Triage of the cluster (#259)
utf8.lua— already passes; no work needed.math.lua— first runtime failure under suite config isload()being sandboxed at line 277; aload/sandbox concern, out of scope here.coroutine.lua—coroutineglobal is nil; the whole coroutine subsystem is unimplemented, too large for this PR.all.lua— first runtime failure wasattempt to call a nil value (field 'clock' on global 'os')at line 57. Theoslibrary did not exist. This is the single most tractable concrete fix, so it is what this PR ships.Success criteria
Lua.VM.Stdlib.Osmodule installed into the global env.os.time,os.clock,os.difftime,os.date,os.getenv,os.setlocale,os.tmpname,os.exitimplemented per Lua 5.3.test/lua/vm/stdlib/os_test.exs.all.luaskip narrowed to its new (post-os) failure with a precise reason.mix testandmix test test/lua53_suite_test.exs --only lua53both green.Changes
lib/lua/vm/stdlib/os.ex— new os library (time/date/env helpers; filesystem & subprocess functions stay sandboxed by the existing high-level API list).lib/lua/vm/stdlib.ex— install the os library alongside the others.test/lua/vm/stdlib/os_test.exs— regression coverage, including thatos.getenvstays sandboxed by default.test/lua53_skips.exs— narrowall.luafrom:allto two ranges (137..208, 211..263): the harness body that drives every other suite file viadofile/loadfile/string.dump/coroutine.wrapand the post-runio.opensummary, none supported in the sandbox.Verification
lua53 suite delta:
all.luaflips from a fully-skipped file to a passing file (lines 1-136 and 209-210 now run clean).Out of scope
coroutine.luaand the coroutine subsystem.math.luaload()sandbox behaviour.all.luafully pass — it is the suite harness and loads other suite files via mechanisms the sandbox does not support.Closes #280