Recording prompts is of marginal value, and it's in the next commit's
way.
If you need better logs after a crash, consider enabling the journal
log file.
copy_utf8_to_ascii_no_funny() eats the character following a replaced
non-ASCII character. Buffer overrun possible when the terminating
zero gets eaten. Broken in commit b5ff7e3b, v4.2.21.
Affected commands:
* players column "last command" in ASCII sessions: struct player
member combuf is UTF-8, uprnf() filters to ASCII.
* read in ASCII sessions: telegram chunks are UTF-8, uprnf() filters
to ASCII.
* flash and wall with message argument in ASCII sessions: argument is
used raw, i.e. UTF-8, pr_flash() filters to ASCII. Safe as long as
we have input filtering sanitizing the raw argument. command() does
that, but execute() doesn't (bug, to be fixed in a later commit).
* execute prompting for its argument in UTF-8 sessions: prmptrd()
receives user text, and filters to ASCII.
Unaffected:
* dispatch() argument redir is UTF-8, uprnf() can filter to ASCII.
Safe as long as we have input filtering sanitizing the raw argument.
command() does that. execute() doesn't, but rejects redirections
before calling dispatch().
* getele() buffer is UTF-8, uprnf() can filter to ASCII. Safe,
because its contents comes from uprmptrd(), which filters input.
When getcommand() reads an empty string, it prints another prompt and
reads another line, without running status(). That's bad:
* nat_timeused is not updated. Affects the player's prompt, deities'
nat selector timeused, and commands edit, players, xdump nat.
* Mortal player isn't logged off for game hours, game down, and time
limit.
* Notifications are delayed: going broke, becoming solvent, new
telegrams (toggle inform off only), new announcements, capital lost.
Fix by removing the loop. Callers handle empty input just fine since
4.2.2.
Side effect: empty commands are now recorded in player_commands[].
That's okay.
The check applies to selectors with flag NSC_CONST set. It permits
initializing them in new objects, but prevents changing them in
existing objects. For split tables, initialization worked only in the
first part, because new objects were considered old in later parts.
For instance, in a custom config sect-chr with mnem in the second
part's field 2, new sector types were rejected with `Value for field 2
must be ""'.
"version" is a normal table since commit da8a1dae, v4.3.12. xdump.pl
wasn't updated for that, and queried the version table twice. When
the deprecated special "xdump ver" was removed in commit 78b3af20
(v4.3.27), the extra query broke. Remove it.
pln_zap_transient_flags() fixes up planes stuck in the air (commit
7ca4f412, v4.3.12). Since commit 4e9e58bf (v4.3.14), it writes back
the fixed planes. This is wrong for empdump.
empdump should touch data only on successful import. When it fails
because ef_verify() fails, and any planes are found stuck in the air,
the plane file gets rewritten.
Make parameter ef_verify() take parameter may_put to let empdump
suppress the plane write-back. The plane file still get written out
on successful import, along with the other imported game state.
Table elements reference other table elements. Bad things happen when
references dangle. ef_verify() already checks whether the referenced
table elements exist. This commit makes it check whether the elements
are "in use". This catches stuff like living planes on dead carriers.
verify_row() refrains from rejecting zero uids, because some tables
may contain blank entries, with zero uid.
Change it to check only header sanity for entries that are not in use.
This filters out all legitimately blank entries. Tighten up the uid
check.
For computing "in use", factor empobj_in_use() out of xdvisible().
Note that xdvisible()'s case EF_COUNTRY doesn't bother to check
nat_stat, because that's implied by what it does check. It's not
implied in empobj_in_use(), so add it there.
Spy units are now enabled when a land unit type with capability spy
exists. To disable them, deities have to customize table land-chr.
Before, spy units types were ignored when option LANDSPIES was
disabled. Except for xdump land-chr, which happily dumped unusable
spy unit types.
Trade ships are now enabled when a ship type with capability trade
exists. No such type exists by default; to enable trade ships,
deities have to customize table ship-chr.
Before, trade ship types were ignored when option TRADESHIPS was
disabled. Except for xdump ship-chr, which happily dumped unusable
trade ship types.
Only trade ships can be auto-scuttled. orde() rejects scuttle orders
for other ships. scuttle_it() double-checks, but gets the test wrong:
it rejects only when opt_TRADESHIPS is enabled. Fix that. While
there, make it oops on inadmissible ships.
Change xundump to blank out omitted rows. Before, they were left
alone. Impact:
* No change for reading builtin tables.
* Reading custom tables now replaces the builtin tables instead of
sort-of-merging them. Wasn't a real merge, because it dropped
builtin entries after the last custom entry, except for
non-truncatable tables item, sect-chr and infrastructure.
* empdump -i now replaces the old state instead of sort-of-merging the
dump into the old state. Wasn't a real merge, because it dropped
old state entries after the last entry in the dump, except for the
fixed-size tables sect, nat, realm and game.
Configuration table entries not defined by builtin and custom
configuration files remain blank. They get misinterpreted as sentinel
in tables that use one. Affected are tables product, ship-chr,
plane-chr, land-chr and nuke-chr. Tables item, sect-chr and
infrastructure are immune despite using a sentinel, because omitting
entries is not permitted there.
Code relying on the sentinel fails to pick up entries after the first
blank one. They don't get set up correctly, they're invisible to
build and show, and not recognized as symbolic selector values (the
frg in ship ?type=frg). xdump is fine, because it doesn't rely on
sentinels. It dumps blank entries normally.
The bugs don't bite in the stock game, because the builtin
configuration files are all dense.
The sentinels are all null strings. Set them to "" in the affected
tables' oninit callback. Fix up code iterating over the tables to
ignore such entries. This is precisely the code relying on sentinels,
plus xdump's xdvisible().
Before, it also recognized "" (since commit 844b654d, v4.2.14), but
no caller depends on that.
While there, back out the macro cleverness added in commit 844b654d.
When not enough rows are supplied for a table with fixed size, treat
the rows missing at the end just like rows omitted elsewhere: make
them blank if the omission is permitted (tables nat and game), else
fail (tables sect and realm; no change).
Forbid omitting rows for tables with const fields: item and sect-chr.
This is consistent with the rule for truncation.
The server expects certain entries in these two tables, and
malfunctions when they're blank. Omitting them in the builtin tables
has always left them blank, but deities are not supposed to edit them,
and maintainers are supposed to know what they're doing, so the issue
was deemed unimportant and ignored. However, I plan to blank out
omitted rows in custom tables as well, and then the issue isn't
unimportant anymore.
Truncating is actually fine for table product. It's forbidden because
selector sname has flag NSC_CONST set. I don't remember why sname was
made const in commit 445dfec9 along with item selector mnem, sect-chr
selector mnem and infrastructure selector name. Unlike the other
tables, no code depends on product's builtin values. Clear the flag.
Factor tracking of cur_type, cur_obj, cur_id and cur_is_blank into a
set of functions. They replace getobj(). While there, improve some
error messages.
They set up invariants, and thus should be always active, not just in
the server. Since ef_blank() isn't used for these files outside the
server right now, this isn't a bug fix, just cleanup.
files.c writes initial contents to game state files with fixed size.
Necessary for setting up invariants, such as struct sctstr members
sct_x, sct_y matching sct_uid.
Do that from the oninit() callback, so ef_blank() sets up invariants
correctly. Since ef_blank() isn't used for these files right now,
this isn't a bug fix, just cleanup.
Instead of stuffing NULL initializers into the cache initializer
macros UNMAPPED_CACHE(), ARRAY_CACHE(), PTR_CACHE(), ARRAY_TABLE().
In preparation of having some non-NULL initializers.
empdump -i now complains about extra rows instead of silently growing
the file to a size the server will reject. Affects tables sector,
nation, realms, game.
Bonus fix: better error message on I/O error or insufficient memory.
empdump -i now complains about missing rows instead of silently
truncating the file to a size the server will reject. Affects tables
sector, nation, realms, game.
New struct empfile member nent replaces ef_open() parameter nelt.
Cleaner, because the expected size is a property of the file, not of
how it's used. Also fixes empdump to check file sizes.
Complication: with EFF_CREATE, ef_open() creates an empty file, to be
extended to the correct size. Callers passed nelt argument -1 along
with EFF_CREATE, to make ef_open() accept the empty file. Can't do
the same for empfile member nent. Instead, make ef_open() not check
the (zero) size then.
Replaces commit 5750107b, v4.3.15.
ef_verify() assumes views are open. Bug is harmless, because
ef_nelem() returns zero for closed views, and ef_verify() accesses
only immutable parts of struct empfile then.
New struct empfile member base replaces ef_open_view() parameter base.
Cleaner, because the base table is a property of the view, not of how
it's used.
Use it to clean up verify_fail()'s base table access, and for extra
sanity checks in ef_open() and ef_open_view().
ef_open() handles onresize() failing incorrectly. Instead of fixing
that, drop the failure mode. It's not really used: unit_onresize()
fails only when used incorrectly. It isn't. If it ever is, ignoring
the failure is safe.
Make ef_close() clear them always, even for views. Harmless, as
ef_open_view() always sets the same flags.
Drop redundant assignment to ep->flags in ef_open(). ef_close()
clears mutable flags, no need to clear them some more right before
calling it. Missed in commit 3eb3607f, v4.3.0.
ef_open() and ef_close() clear EFF_SENTINEL because of that. Broken
since commit 1492845c (v4.3.17) added EFF_SENTINEL. Harmless, as no
file-backed table has a sentinel.
The message claims the file is larger than it actually is. Broken
since commit 71908018 (v4.3.0) implemented static cache in ef_open().
Harmless, because no file-backed table has a statically allocated
cache.