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.
Split tables require the record index in the leftmost column.
defellipsis() correctly rejects "..." when the table doesn't have one.
It fails to reject it when it has one that is NSC_EXTRA, and thus not
permitted in a dump. This is the case for table sect. defellipsis()
happily succeeds, then chkflds() demands column "uid" if it's missing,
and rejects it if its present.
It missed those with more flags than just NSC_EXTRA set: table sect
name uid, table nat names passwd, xorg, yorg, contacts, rejects.
Since xundump() doesn't provide space for these, the bug could lead to
buffer overruns. Fixes flawed commit 726a8e3d, v4.3.12.
xubody() neglected to check ef_truncate()'s return value. Two failure
modes: invalid arguments, and ftruncate() failure. The former
shouldn't happen, and the latter can happen only for file-backed
tables, hence only in empdump -i.
Tables with a file name are: any game state, and any table that's
initialized from a .config file.
Tables that are no longer customizable: "updates" (customization had
no effect, because update_get_schedule() overwrote it), "table",
"meta" and the symbol tables (customization couldn't change them
anyway), and news-chr (customizing r_newsstory[] was kind of neat, but
unsafe because they are format strings for sprintf()).
"xdump updates" believes there are always 15 (UPDATE_TIME_LEN - 1)
scheduled updates. When fewer than 15 updates are scheduled, it shows
whatever crap update time happens to be in the unused part of
update_time[]: the initial zero or a previously scheduled update.
Root cause is that table EF_UPDATES has always UPDATE_TIME_LEN - 1
entries, which is incorrect when fewer updates are scheduled. Only
xdump is affected, as the other users ignore the length and stop at
the sentinel.
Fix update_get_schedule() to resize table EF_UPDATES.
Makes ef_verify() check carrier UIDs are sane. Partially protects
unit_cargo_init(), which oopses on bad carriers.
This has become possible only since commit 64a53c90 (v4.3.17) set
their values to -1 in newly created units. Before, they were zero in
units that had never been used, and a proper ca_table would have made
ef_verify() fail when unit#0 didn't exist.
The only unit# selectors left without a proper ca_table are ship's
follow, lost's id and trade's unitid. Document why.
The NSC_CONST flags added in commit fa63f87b have always been missing
here. The previous commit changed xdump meta meta. Other than that,
it's just different encodings.
The C identifier permits looking up the table in the source. The
table name permits lookup with xdump.
Coders should know how to go from table name to C identifier. Deities
aren't all coders; we shouldn't ask them to guess table names from C
identifiers.
These are commonly timestamps (no verification implemented), or
aliases for a non-extra column (which gets verified). Commit 49780e2c
(v4.3.12) added the exception: EF_SECTOR's uid. Proof by example that
ignoring these columns is wrong. Fix: ignore only virtual columns.