TinyMUX 2.14.0.9 ALPHA

1 view
Skip to first unread message

Brazil

unread,
Jul 14, 2026, 8:37:51 PM (8 days ago) Jul 14
to tinymux
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Subject: [ANNOUNCE] TinyMUX 2.14.0.9 ALPHA released

TinyMUX 2.14.0.9 ALPHA is now available. This release is a stability
and hardening follow-up to 2.14.0.8. The main items are a fixed
file-descriptor leak in the GANL networking stack and a connect-time
crash loop, a second memory-safety pass over the database load paths,
a migration of the @mail and mail-alias subsystems to RAII/STL
storage, and full cross-server (PennMUSH, RhostMUSH, TinyMUSH) color
interoperability in the Omega flatfile converter. It also carries a
round of JIT/interpreter parity and performance work and a large
expansion of the smoke-test suite.

Changes since 2.14.0.8 ALPHA
- ------------------------------

Networking:

- - A file-descriptor leak in the epoll engine is fixed. The
  abnormal-disconnect path (a client RST or hangup) emitted a close
  event but, unlike the graceful and outbound-failure paths, never
  closed the socket or removed it from the engine, so every abrupt
  disconnect leaked one descriptor. A busy game accumulated tens of
  thousands of orphaned sockets over its uptime. Verified live: 40
  RST disconnects leaked 40 descriptors before the fix, 0 after.
- - When a connection fails to associate its context during setup, the
  accepted socket is now closed rather than leaked.
- - A rate-limited NET/STAT socket-accounting log line (logical DESCs
  vs. the adapter's connection maps vs. the OS descriptor count, plus
  accept/close churn) was added to localize where sockets accumulate.
- - GANL console shutdown now handles a Windows logoff cleanly.

Reliability and Restart:

- - A connect-time crash loop is fixed. A player whose A_LOGINDATA was
  truncated or malformed made decrypt_logindata() dereference a null
  field pointer and crash on connect; and, separately, unset_signals()
  spun forever on a missing loop increment instead of restoring the
  default handlers, so a caught crash pinned the process at 100% CPU
  in the signal handler and defeated crash-driven @restart recovery.
  Field reads now return an empty string rather than null, and the
  signal-reset loop is fixed, so a bad A_LOGINDATA fails safe and a
  crash restarts as intended.
- - Connection, idle, and server-start times now survive @restart past
  2038. They are 64-bit Unix-second counts but were round-tripped
  through the 32-bit dbref channel in restart.db, truncating after
  2038-01-19 and corrupting the WHO "On For" column for any session
  spanning a restart. They are now serialized as 64-bit; restart.db
  is bumped to version 5 (older versions still read).

Database Load Hardening:

A second memory-safety pass over the database load paths (flatfile
reader, @mail/mail-alias loader, SQLite bulk attribute load) under
the corrupt-or-crafted-database threat model, covering code the June
pass (#806/#808/#841/#843) did not reach:

- - getstring_noalloc no longer overflows its static buffer. Both the
  escaped-string refill path (a mis-accumulated byte count) and the
  legacy continued-line path (no capacity guard) could march past the
  buffer on a crafted >64KB quoted string.
- - The mail-alias loader (malias_read) now clamps the recipient count
  it reads from the file, and make_numlist bounds its copies, so a
  crafted mail.db alias can no longer overflow the fixed recipient
  stack array. The mail-alias table also resets its count and
  capacity when an allocation fails.
- - The SQLite bulk-load paths now clamp attribute value lengths to
  LBUF_SIZE, closing a heap overflow on the first read of an over-long
  value written directly into the database file.
- - get_list now stops at end-of-file instead of spinning forever on a
  flatfile truncated mid-attribute-list, and the v2 lock parser frees
  its partial subtree on each malformed-input error path.

@mail and Mail Aliases:

The @mail and mail-alias subsystems were migrated from manual C-style
arrays and hand-managed string lifetimes to RAII/STL storage,
eliminating the class of leaks, allocation-failure state corruption,
and out-of-bounds accesses that motivated the hardening above.

- - Two regressions introduced by the migration were caught and fixed:
  the SQLite write-through insert for newly sent mail was restored (it
  had become dead code, risking a lost message on a crash before the
  next full sync), and a mailbox-full off-by-one that cut the
  effective per-player limit by one was corrected.

Omega Flatfile Converter:

The Omega cross-server flatfile converter gained full color
interoperability across PennMUSH, RhostMUSH, and TinyMUSH, plus
current-format support and a memory-safety pass.

- - Current (v5, 2.14) flatfiles are now supported, and the per-channel
  delta PUA color codec was restored so 2.13 (v3/v4) flatfiles
  round-trip byte-exact.
- - Color is now carried across every conversion direction: import from
  and export to PennMUSH inline markup and RhostMUSH %c codes, and
  256- and 24-bit color preserved across TinyMUSH (raw-ANSI)
  conversion and across the v4->v3 TinyMUX downgrade (previously
  reduced to 16 colors). Latin-1 text is also preserved on the
  TinyMUX->TinyMUSH path (accented characters had been turned into ?).
- - The @decomp extraction helpers no longer silently truncate large
  attributes, and a latent PennMUSH markup buffer overflow on
  color-heavy values was fixed.
- - AddressSanitizer over the full conversion matrix found and fixed
  five latent memory-safety bugs; an ASan harness, a color-stress
  fixture, and a converter test pool were added.
- - The -v version selector was replaced with a self-describing
  per-family registry (canonical ids, aliases, latest/oldest/same,
  and an "omega --list").

JIT / DBT Engine:

- - The JIT now declines cleanly when its Tier-2 blob (softlib.rv64) is
  missing. The blob-presence check sat inside a once-only init block,
  so only the first call declined and every later call ran the JIT
  without the blob, producing silently wrong results for some compiled
  shapes. (#875)
- - member() now compares color-stripped words, matching the compiled
  co_member and the rest of the word-comparison family; a colored list
  or target previously never matched in the interpreter.
- - The Tier-2 left/right wrappers are now grapheme-cluster-aware and
  range-check negative counts, and left() is now a first-class
  function (with strtrunc() as its documented synonym) rather than a
  config-file alias.
- - #$ no longer leaks into switch()/switchall() pattern evaluation on
  the AST fast path, which had diverged from the interpreted path.
  (#857)
- - A cand()/cor() chain that bails to the interpreter mid-chain no
  longer crashes or emits garbage; the partial fast-path lowering is
  now rolled back cleanly before the fallback. (#858)
- - ljust()/rjust()/center() now range-check the requested width before
  narrowing it, so a large width reports an out-of-range error instead
  of silently wrapping to a bogus column count; the interpreter and
  Tier-2 paths now agree.
- - fmod() on non-IEEE-SNaN portability builds now guards the divisor
  rather than the dividend (they were inverted).
- - A muxscript death mid-run is now reported as a crash by the smoke
  harness instead of being silently swallowed, and the HIR compiler
  poisons and abandons a compile that overflows its capacity. (#859)

Performance:

- - NearestPretty gained an integer fast-path that skips the 9x
  shortest-decimal search for whole-number results -- the common case
  for integer list math -- measured at roughly -35% on
  iter(lnum(100),mul(%i0,%i0)).
- - run_cached_program now populates only the substitution and argument
  slots a compiled program actually reads instead of all ~45 every
  call, dropping the per-call floor of a cached eval from ~0.40 to
  ~0.15 us.
- - co_find_delim -- the shared delimiter scanner under first/rest/
  extract/words/iter -- gained a memchr fast path for ASCII
  delimiters, measured at roughly -24% on list-walk benchmarks.

Console and Memory Safety:

- - The console input line and cursor are now clipped to the window
  width in redraw_input(), so long input no longer wraps onto the
  status bar and the cursor stays on-screen on narrow terminals.
- - The atr_get/alloc_lbuf RAII migration continued: create_player's
  trimmed-password buffer is now an owning LBuf. (#717)

Build, Tests, and Documentation:

- - A top-level LICENSE file (Artistic-1.0 plus the revised TinyMUD
  notice) and a CONTRIBUTING.md were added, and AGENTS.md was
  corrected to the 2.14 build workflow.
- - The smoke-test suite was substantially expanded with error-path and
  boundary coverage across many softcode functions (argument-count and
  width boundaries, divide-by-zero, no-match switch/case, Unicode and
  RTL handling, permission and malformed-syntax paths, and more).

Download:

Full source (tar.gz):
mux-2.14.0.9.unix.tar.gz
SHA256: ad9fe6ff09f052c9351f8409a4941392d1fcb66d2c9802afc542dcbe8885cb94

Full source (tar.bz2):
mux-2.14.0.9.unix.tar.bz2
SHA256: 0103c577f6ce49fd7e59ce341763792fc60586ed4ca54f31ddf8eb91b2bc65cf

Patch from 2.14.0.8:
mux-2.14.0.8-2.14.0.9.unix.patch.gz
SHA256: ab6299771b01c7a5fdb3ad0f62496aa3ce4c4d5c4772059f183e72008fb26a68

Companion binary blob (apply alongside the patch):
mux-2.14.0.8-2.14.0.9.unix.blobs.tar.gz
SHA256: 2747c2551d4a8c594269d3a4a2aa4f0fb10594c0b00b682ea22ee7461e3233a9

This is the first release to ship a prebuilt binary artifact
(rv64/softlib.rv64) in the source distribution. A text patch cannot
carry binary content reliably, so the upgrade patch is text-only and
the blob is delivered whole in the companion archive above. To upgrade
an existing 2.14.0.8 tree, apply the patch and then unpack the blobs
archive over it:

    gunzip -c mux-2.14.0.8-2.14.0.9.unix.patch.gz | patch -p0
    tar xzf mux-2.14.0.8-2.14.0.9.unix.blobs.tar.gz

See mux-2.14.0.8-2.14.0.9.unix.APPLY.txt for the full instructions. A
fresh install from either full-source tarball needs neither step.

All files are GPG-signed (.asc).

This is ALPHA software. Make backups. Report bugs to
brazi...@gmail.com.

- -- Brazil

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEE8GWFNwJrhRGk25uvF80K5PxQP7EFAmpW1f8ACgkQF80K5PxQ
P7FALA/8DYvCztYX+77mnPfM4rAE07LgqsaHjUBnNvPAqcXu+oiN6MU8srK0nUqU
K1VN4xjfH9yyUF5RBSr5mRzLfpOc43T407n2SRxHl8koVFN5eoINCkd9oD4HPe6A
TuITqnFNAfdxerDBz/k2wHmGj0dNrEa8JHA3/vujN5zV9QphO+YxFZnZHgiEZcy3
aaIWqtJG2SYv4s3F71QBFig0l/IZcBvKxEBVHh2+VM5TUgQpHgMhF9MXZYQmDoRI
mAGDVIBVBFBVegUpUHzx2fyGF2/IpyOo6Jq1nbXJ8MmNEYU7K24QtK85GMeZoZu2
2mOynmLJqpdPfzBya5MVQalvw01e5LSJWMFttecc9fj0dt6/dMU6/cAepeG/rKr0
Zlm3rUBNnUicU0nrqvQ+Wg/fYObWkdhWotraNGMhlNaj7xvXQuUWeU9qAyM44hSU
oTaeAFaxNOpM7I4eSOXsVEEWOSDofiQnKPUhwxRmAdRtB26el4FyYMzWYv9SIgzY
DitASnBOkb0CLMJOgUQB/Obkr819WzMyMnRz46NN1KwSGkZqRa4EMw2ZajBmcDPg
9Yy38CqzGAik5e1WkEEbx9HZX3O4GlRN6wEjZw0owIGTUhYpZGb2jG6rGXdG5P6p
8quYC9nJb/G4610I5WAFGirX7AG8J2HOs3sbI3Trj3K3L7L0ZCI=
=sGhJ
-----END PGP SIGNATURE-----

Reply all
Reply to author
Forward
0 new messages