Repository navigation
fix: reject redis pub/sub commands, auto-seed math.random, flua CLI exit code - #31
Merged
Merged
Conversation
Fixes three issues from the FakeLua Phase 16 integration report (docs/fakelua-bugs-phase16.md, based on dafdac7). redis (high-value safety fix): SUBSCRIBE/PSUBSCRIBE/UNSUBSCRIBE/ PUNSUBSCRIBE issued via the one-shot conn:command() channel left hiredis holding a dangling CmdOp* as privdata after the first ack popped and destroyed it; every subsequent published message wrote through the freed pointer (use-after-free/heap corruption). Full pub/sub needs a dedicated long-lived subscription context, so for now the command verbs are rejected case-insensitively before the readiness check with a clear error (pcall-catchable, works without a live server), and both native READMEs document the limitation plus the polling workaround. math.random: std::rand() defaulted to seed 1, so without an explicit math.randomseed every process start produced the identical sequence. The math library now auto-seeds once per process on first state init (time + std::random_device + stack-address entropy), matching Lua 5.4; explicit math.randomseed(x) still overrides. flua CLI: an uncaught FakeluaException propagated to libc++abi and killed the process with SIGABRT (exit 134). main() now catches std::exception around compile/run, prints "flua: <msg>" to stderr and exits 1, per standard Lua interpreter convention. The report's Bug 1 (math-specialization entry guard aborting on non-numeric args) is addressed by the independent PR #30. Tests: new test_redis.subscribe_rejected (all backends, no server required); full suite passes except the 8 test_mysql integration tests that need a live MySQL server.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #31 +/- ##
==========================================
+ Coverage 87.99% 88.00% +0.01%
==========================================
Files 124 124
Lines 25388 25406 +18
==========================================
+ Hits 22339 22358 +19
+ Misses 3049 3048 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Three issues from the FakeLua Phase 16 integration report (
docs/fakelua-bugs-phase16.md, found 2026-10-11 againstdafdac7while wiring event/sqlite/http/net.udp/crypto/random/utf8/url/csv/redis into a game server demo). The report's Bug 1 (math-specialization entry guard aborting processes on non-numeric arguments) is addressed independently by #30; this PR fixes Bugs 2/3/4.Bug 2 — redis SUBSCRIBE use-after-free (safety)
conn:command()is a one-shot RPC channel: each command allocates aCmdOp, queues it, and passes its raw pointer to hiredis asprivdata. ForSUBSCRIBE, hiredis invokes the same callback for every pushed message. After the subscribe ack is dispatched inTick(), theCmdOpis popped and destroyed — so the second push writesop->done = true/ clones a reply through a dangling pointer: heap corruption, guaranteed crash, and messages never reach Lua.Full Pub/Sub requires a dedicated long-lived subscription context (a larger feature needing a live server to validate). This PR applies the report's minimum safe fix:
SUBSCRIBE/PSUBSCRIBE/UNSUBSCRIBE/PUNSUBSCRIBE(case-insensitive) are rejected inRedisConnection::Command()before the readiness check, with a clear pcall-catchable error — no UAF reachable, error even before connect completes.src/native/README*.mddocument that Pub/Sub is unsupported and show the polling workaround (LPUSH+LRANGE,ZADD+ZREVRANGE).test_redis.subscribe_rejectedruns on TCC/GCC/INTERP viaCallAll.Bug 3 — math.random not auto-seeded
std::rand()defaults to seed 1, so without an explicitmath.randomseedevery process restart produced the identical sequence (819122 956267 764553). The math library now auto-seeds once per process on first state init usingtime + std::random_device + stack-address entropy(same-second launches still differ), matching Lua 5.4's automatic seeding. Explicitmath.randomseed(x)continues to override; all existing math tests seed explicitly, and the three callers that don't only assert ranges/boundaries. Verified across three separate flua processes and three backends.Bug 4 — uncaught errors abort with SIGABRT
An uncaught
FakeluaExceptionpropagated tolibc++abiand terminated the CLI with exit code 134 instead of the Lua-conventional exit 1.cmd/main.cppnow wraps compile/run intry/catch (std::exception), printsflua: <msg>to stderr and returns 1. Verified for runtime errors on all three backends and for compile-time syntax errors.Tests
test_redis.subscribe_rejected(all backends, no redis-server needed).test_mysql.integration_*tests fail (require a live MySQL server — pre-existing environment baseline); zero redis failures.