Key 'L' copies the source sector to a destination sector. Bug: it
doesn't copy, it messes up the source sector badly instead, and can
smash the stack on some machines.
Root cause: doland() passes § instead of sect to ef_set_uid().
Impact:
1. ef_setuid() clobbers a few bytes at §.
When the bitfield and uid fit into sizeof(sect) bytes, it clobbers
just sect, which has no effect, because doland() returns without
using it again. This is the case on a typical 64-bit machine: bit
field and uid are both 4 bytes, sizeof(sect) is 8.
When they don't fit, whatever is adjacent to sect gets clobbered.
On a typical 32-bit machine with stack growing down, that's p.
Again, no effect, because doland() returns without using it again.
With stack growing up, it could well be the return address,
crashing the server.
2. ef_setuid() fails to update *sect. Impact (when we survive 1):
sect->sct_uid remains unchanged. putsect() writes to the source
sector instead of the destination sector, clobbering the source's
sct_x, sct_y. Breaks invariant sctoff(sct_x, sct_y) == sct_uid!
Subsequent edits are all applied to the source sector.
sect->sct_seqno remains unchanged. No effect, because we write to
the source sector, and the unchanged sequence number is the right
one there.
Broken in commit 536ef0b0, v4.3.15.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Non-integer values are already parsed there. Treating integer values
specially complicates things for no real gain.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
edit, setresource and setsector report change in three ways:
* Print a message.
* Send a bulletin to the changed object's owner. This should be done
if and only if the change is visible to the owner, e.g. in census or
xdump.
* Report divine aid in news. This should be done if and only if a
bulletin was sent, except for changes that are neither negative nor
positive, such as changing the distribution sector.
Fix the places that don't get it right for sectors:
cmd key sctstr member before after notes
-------------------------------------------------
edit l O sct_oldown -- B-
edit l F sct_fallout -- BN 1
edit l M sct_mines -- BN 2 3
edit l D sct_dist_x,y -- B- 1
edit l s sct_type -- B- 1
edit l S sct_newtype -- B- 1
setse ow sct_own B- BN
setse ol sct_oldown -- B-
setse e sct_effic -- BN 2
setse mo sct_mobil -- BN 2
setse a sct_avail -- BN 2
setse w sct_work -- BN 2
The two characters in columns before, after show whether the command
sends a bulletin (B) or not (-), and whether it reports news (N) or
not (-).
Notes:
1. Printed message massaged slightly for consistency with other keys.
2. Printed message improved to show the old value, too. Necessary to
give the deity a chance to catch unexpected changes, e.g. a player
laying mines right before the deity edits them. Watching out for
such changes is especially important with non-interactive edit.
3. Bulletin and news suppressed for occupied sectors.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Send bulletin to owner and report news exactly like for key 'o'.
Also print a "sector duplicated" message, just for consistency with
other keys.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Back in Empire 1, resources were limited consistently: fertility to
120, all others to 100.
When Chainsaw added setresource, consistency was lost: fertility got
limited to 100 there.
Chainsaw 3 changed edit to limit all resources to 127.
Commit 3fcee8dd and commit 8e430ae2 (both v4.3.11) changed fairland
and setsector to limit fertility to 100, matching setresource.
Now only edit remains different. Change it to finally make things
consistent again.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
setsector() reads the first two characters unconditionally. Wrong if
the first character is NUL. The second character read isn't actually
used then. Screwed up in Chainsaw.
When getstarg() returns an empty string, it's always in the buffer
passed as third argument. Thus, reading the second character is
actually safe.
Clean it up anyway.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Commit 77e95bd7 (v4.3.12) missed the move of log.c there. A few
pointers to other headers are missing.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
When the deity sets the number of mines with setsector, the sector
owner (if any) is told the resulting number of mines. Even for
occupied sectors, where mines belong to the old owner, and thus
shouldn't be disclosed. Oops.
Fix setsector not to tell the sector owner anything then.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Fails to print actual change for occupied sectors. Broken in v4.3.31.
This reverts commit eb4adc93ff.
Conflicts:
src/lib/commands/setsect.c
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Deities get bulletins when they use edit, give, setsector and
setresource on stuff they own. Except for POGO, who can't own
anything.
The bulletins are annoying; suppress them.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Option GODNEWS is documented to be about deities giving or taking
things from players. Nevertheless, edit, give, setsector and
setresource report news of deities meddling with things owned by
deities other than POGO. Don't.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
give already suppresses when the new value equals the old one, but
edit, setresource and setsector don't. Make them.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
In the beginning, all bulletins came from POGO. Chainsaw changed edit
and give to send them from the deity using the command. Its new
command setresource sent from POGO regardless. Its new command
setsector did both.
Go back to sending them only from POGO.
Some of the affected bulletins don't mention the acting deity. Reword
them so they do.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
To simplify the next commit.
Changes the error message for unknown keys to show the full key.
Shouldn't matter.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Empty key arguments work fine when passed as command arguments, but
not interactively. For example, 'edit s 42 R ""' clears the retreat
path, but in an interactive 'edit s 43', 'R ""' sets it to "".
In Empire 1, omitting the argument made it empty. Empire 2 turned
that into an error without providing an alternative.
Switch to the common command parser, so that quoting works, and "" is
parsed as empty argument.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Necessary to give the deity a chance to catch unexpected changes,
e.g. a player moving away stuff right before a give command, leaving
fewer items than the deity intends to take.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
give() silently caps the resulting number of items to 0..ITEM_MAX.
However, its test for "< 0" suffers integer overflow on two's
complement machines (i.e. practically everywhere) when the amount
argument is INT_MIN. give() proceeds as if the result was in range:
it sets the number of items to (short)(n + INT_MIN), telexes the owner
that INT_MIN items were stolen (obviously bogus), and tells the deity
that there are now n + INT_MIN items in X,Y.
On common machines, (short)(n + INT_MIN) == n, i.e. nothing is given.
On an oddball machine with short as wide as int, the cast to short
does nothing, item_prewrite() oopses, and corrects the number of items
to zero.
In both cases, output and telegram lie.
Likewise, its test for "> ITEM_MAX" suffers integer overflow for
sufficiently big amount arguments. Again, give() proceeds as if the
result was in range: it sets the number of items to (short)(n + amt),
telexes the owner that -amt items were stolen (obviously bogus), and
tells the deity that there are now close to INT_MIN items in X,Y.
On common machines, (short)(n + amt) = n + INT_MAX - amt - 1,
i.e. some items are stolen.
On an oddball machine with short as wide as int, the cast to short
does nothing, item_prewrite() oopses, and corrects the number of items
to zero.
Again, output and telegram lie.
Aside: setsector can suffer similar overflows, but it reports the
resulting change correctly. Good enough.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Only one of struct lndstr members lnd_ship, lnd_land may be
non-negative. When a deity screws that up, the server oopses. Be
nice: when setting one, zap the other.
Same for struct plnstr members pln_ship, pln_land.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Upper bounds corrected:
cmd key struct member wrong correct notes
-------------------------------------------------
edit l m sct_mobil 255 127 1
t sct_ptime 255 32767
edit c b nat_btu 1024 max_btus
edit p m pln_mobil 255 127 1
edit u F lnd_harden 255 127 1
Missing bounds supplied, arguments out of bounds are silently clipped
unless noted otherwise:
cmd key struct member bounds notes
---------------------------------------------------
edit c t nat_tgms 0 USHRT_MAX 2
m nat_reserve 0 INT_MAX
T... nat_level[] 0 infinity
edit s a shp_pstage 0 PLG_EXPOSED 3
b shp_ptime 0 32767
M shp_mobil -127 127
c... shp_item[] 0 load limit 4
edit u Y lnd_land -1 size of table 5
M lnd_mobil -127 127
S lnd_ship -1 size of table 5
Z lnd_retreat 0 100
c... lnd_item[] 0 load limit 4
edit p r pln_range 0 max range
s pln_ship -1 size of table 5
y pln_land -1 size of table 5
Notes:
1. Values between SCHAR_MAX and 255 were cast to signed char, changing
the sign.
2. The real upper bound is the number of telegrams in the mailbox, but
counting them isn't worth it.
3. This check is particularly important, because values out of bounds
make the server refuse to start without -F, and empdump -x warn
"export has errors, not importable as is".
4. Values outside 0..ITEM_MAX got caught and clipped by
item_prewrite(). This check avoids the oops, and tightens the upper
bound for units.
5. Argument out-of-bounds are rejected. This check is particularly
important, because unit numbers beyond the size of the table trigger
oopses.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Negative numbers and numbers greater or equal than MAXNOC are invalid.
edit handles such arguments inconsistently:
cmd key struct member arg < 0 arg >= MAXNOC
---------------------------------------------------
edit l o sct_own reject MAXNOC - 1
O sct_oldown reject MAXNOC - 1
X sct_che_target 0 MAXNOC - 1
edit s O shp_own cast skip
edit u O lnd_own cast skip
edit p O pln_own cast skip
Legend:
0 replace arg by 0
MAXNOC - 1 replace arg by MAXNOC - 1
reject command fails
cast replace arg by (natid)arg
bug: can be >= MAXNOC!
skip ignore this key and arg
bug: telexes the owner he lost the unit, which is a lie
Unify to reject. Matches setsector.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
cname() calls getnatp(), and returns a null pointer when it fails.
Some systems (GNU, Windows) deal gracefully with printing null
strings, others crash.
Because we keep table EF_NATION entirely in memory, getnatp() should
fail only on invalid country number.
Rewrite prnatid() to catch this error and recover.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
doland() edits a sector, not a land unit. That one's called dounit().
Lacks taste. Call the helper for editing a FOO edit_FOO(), and make
the FOO * the first parameter instead of the last.
Rename the print helpers to print_FOO(), for consistency. Also frees
up identifier prnat for the next commit.
While there, clean up an unused #define.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This is a fairly comprehensive test of the deity commands to edit game
state: edit, setresource, setsector, give, swapsector.
The test makes edit screw up game state, triggering oopses. The
server refuses to start without -F then, and empdump -x warns "export
has errors, not importable as is". Until these bugs are fixed, skip
this test in "make check".
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Tests can't run in parallel anyway, because they use uses a single
sandbox directory and a single TCP port.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Capturing the client's output tests both client and server, which is
nice. However, player input isn't visible in the resulting file,
which makes it more difficult to understand.
Route player output to journal (econfig key "keep_journal 2"), and
ignore client output.
Separate tests for the client would be useful.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
When formatting coordinates for fixed-width output, the width should
be at least four characters.
cutoff was fine until 4.0.2 reduced coordinate width to three to make
space for civilian and military delivery thresholds.
level has always used width three.
Can't fix either without making lines too long or dropping
information, so just document the problem for now.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
When formatting coordinates for fixed-width output, the width should
be at least four characters.
Columns x,y and op-sect use three. Has always been that way. Widen
them both to four. This cleans up output for world sizes between 200
and 1998.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
When formatting coordinates for fixed-width output, the width should
be at least four characters.
Columns x,y, start and end use three. Has always been that way,
except for end, which used two until commit e07fb30 (v4.2.13).
Widen them all to four. This cleans up output for world sizes between
200 and 1998.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Coordinates run into army when the y coordinate is wider than three
characters. Has always been broken. Insert a separating space.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Land unit coordinates run into efficiency in output of satellite when
the y coordinate is wider than three characters. Broken in Empire 2.
Restore the separating space.
Both ship and land unit table header aren't aligned with the table
body. Affects recon and sweep with spy planes, and satellite. Fix
the header.
Reported-by: William Fittge <ptkei2@gmail.com>
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
Leaks one file descriptor per configured IPv6 address, which should be
pretty harmless. Broken in commit da154ff, v4.3.31.
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>