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 ""'.
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().
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.
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.
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.
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()).
Why upgrade? I'm not a lawyer, but here's my take on the differences
to version 2:
* Software patents: better protection against abuse of patents to
prevent users from exercising the rights under the GPL. I doubt
we'll get hit with a patent suit, but it's a good move just on
general principles.
* License compatibility: compatible with more free licenses, i.e. can
"steal" more free software for use in Empire. I don't expect to steal
much, but it's nice to have the option.
* Definition of "source code": modernization of some details for today's
networked world, to make it easier to distribute the software. Not
really relevant to us now, as we normally distribute full source code.
* Tivoization: this is about putting GPL-licensed software in hardware,
then make the hardware refuse to run modified software. "Neat" trick
to effectively deny its users their rights under the GPL. Abuse was
"pioneered" by TiVo (popular digital video recorders). GPLv3 forbids
it. Unlikely to become a problem for us.
* Internationalization: more careful wording, to harden the license
outside the US. The lawyers tell us it better be done that way.
* License violations: friendlier way to deal with license violations.
This has come out of past experience enforcing the GPL.
* Additional permissions: Probably not relevant to us.
Also include myself in the list of principal authors.
ef_elt_by_name(), xdprval_sym() and symval() checked whether a file
type T is a symbol table by comparing ef_cadef(T) to symbol_ca, even
though T may be EF_BAD. Before commit 50cfdcb5, ef_cadef(EF_BAD)
accessed empfile[] out of bounds, which could conceivably crash or
somehow happen to yield symbol_ca. Since then, it oopses and returns
null.
Fix by testing the file type before calling ef_cadef().
Xundump had special hackery to maintain configuration tables'
sentinels: xubody() and getobj() added a sentinel element when
initializing or growing a table, which xubody() stripped off again
before returning. The latter was an unclean hack.
Replace this by building knowledge of sentinels into struct empfile:
new flag EFF_SENTINEL, set for the appropriate members of empfile[],
obeyed by ef_extend() and ef_truncate().
Commit da8a1dae (v4.3.12) introduced virtual selectors, but neglected
to update xundump. Xundump can't work for them, because they don't
provide a setter method.
This didn't actually break anything, because all virtual selectors
have flag NSC_EXTRA set, or are in table EF_VERSION, which xundump
refuses to touch.
Make deffld() oops on virtual selector, just to be safe.
Make deffld() reject fields whose selector has flag NSC_EXTRA set.
Since xundump() doesn't provides space for these, the bug could lead
to buffer overruns.
Use ef_ensure_space() in getobj(). This also makes sure objects are
properly initialized before undumping writes to them.
Clean up how sentinels are appended: instead of keeping its slot
reserved while undumping, keep it in the table, and strip it off when
done.
(caseen): Remove.
(xufldhdr, deffld): Record only fields in this part in caflds[]. This
fixes the check for duplicate fields in parts other than the first.
(cafldspp): New, to record fields in previous parts.
(xundump): Initialize and finalize it.
(xufooter): Update it. Requires new parameter ca. Caller changed.
(fldval_must_match): Use it to do the right thing for split arrays.
(chkflds): Adapt for changed caflds[].
(chkflds): The check for missing fields was skipped for all parts of a
split table instead of for all but the final part.