From 58ed1d1b9e3d59103f56bc4a0612b643ae77bc8f Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 3 May 2011 07:53:37 +0200 Subject: [PATCH] Fix empdump not to grow game state files with fixed size 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. --- include/file.h | 1 + src/lib/common/file.c | 22 ++++++++++++++++++++++ src/lib/common/xundump.c | 14 +++++++++----- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/include/file.h b/include/file.h index e385b3be..73816c6f 100644 --- a/include/file.h +++ b/include/file.h @@ -219,6 +219,7 @@ extern int ef_write(int, int, void *); extern void ef_set_uid(int, void *, int); extern int ef_extend(int, int); extern int ef_ensure_space(int, int, int); +extern int ef_id_limit(int); extern int ef_truncate(int, int); extern int ef_nelem(int); extern int ef_flags(int); diff --git a/src/lib/common/file.c b/src/lib/common/file.c index 0a579f5e..d7fd6355 100644 --- a/src/lib/common/file.c +++ b/src/lib/common/file.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -931,3 +932,24 @@ ef_ensure_space(int type, int id, int count) } return 1; } + +/* + * Return maximum ID acceptable for table TYPE. + * Assuming infinite memory and disk space. + */ +int +ef_id_limit(int type) +{ + struct empfile *ep; + + if (ef_check(type) < 0) + return -1; + ep = &empfile[type]; + if (ep->nent >= 0) + return ep->nent - 1; + if (ep->flags & EFF_MEM) { + if (ep->flags & EFF_STATIC) + return ep->csize - 1 - ((ep->flags & EFF_SENTINEL) != 0); + } + return INT_MAX; +} diff --git a/src/lib/common/xundump.c b/src/lib/common/xundump.c index 97a3eed1..490a9e74 100644 --- a/src/lib/common/xundump.c +++ b/src/lib/common/xundump.c @@ -487,16 +487,20 @@ static void * getobj(void) { struct empfile *ep = &empfile[cur_type]; + int max_id; if (!cur_obj) { cur_obj_is_blank = cur_id >= ep->fids; if (cur_obj_is_blank) { - if (ef_ensure_space(cur_type, cur_id, 1)) + max_id = ef_id_limit(cur_type); + if (cur_id > max_id) + gripe("Can't put ID %d into table %s, it holds only 0..%d", + cur_id, ep->name, max_id); + else if (!ef_ensure_space(cur_type, cur_id, 1)) + gripe("Can't put ID %d into table %s", + cur_id, ep->name); + else cur_obj = ef_ptr(cur_type, cur_id); - /* FIXME diagnose out of dynamic memory vs. static table full */ - if (!cur_obj) - gripe("Can't put ID %d into table %s, it holds only 0..%d.", - cur_id, ep->name, ep->fids - 1); } else cur_obj = ef_ptr(cur_type, cur_id); }