Verify table uid sanity more tightly
authorMarkus Armbruster <armbru@pond.sub.org>
Mon, 25 Apr 2011 07:34:11 +0000 (09:34 +0200)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 25 Jun 2011 14:54:29 +0000 (16:54 +0200)
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.

include/empobj.h
src/lib/commands/xdump.c
src/lib/common/ef_verify.c
src/lib/common/empobj.c

index f0e6563be80c3609a0919a11ea6b5550534458d4..cb8a059682926c4721590462ce8162c20b2c3853 100644 (file)
@@ -100,5 +100,6 @@ struct empobj_chr;
 
 extern char *empobj_chr_name(struct empobj *gp);
 extern int get_empobj_mob_max(int type);
+extern int empobj_in_use(int, void *);
 
 #endif
index dfa7f84090403a6a2e617fe8b1d44e3598bdcdf3..133714a68b86353aa7514656e4b19d91fc942acc 100644 (file)
 #include <ctype.h>
 #include "commands.h"
 #include "empobj.h"
-#include "news.h"
 #include "optlist.h"
-#include "product.h"
-#include "version.h"
 #include "xdump.h"
 
 /*
@@ -53,63 +50,45 @@ xdvisible(int type, void *p)
     struct lonstr *lp = p;
     struct natstr *natp;
     int tlev;
-    char *name;
+
+    if (!empobj_in_use(type, p))
+       return 0;
 
     switch (type) {
     case EF_SECTOR:
-       return gp->own == player->cnum || player->god;
     case EF_SHIP:
     case EF_PLANE:
     case EF_LAND:
     case EF_NUKE:
     case EF_LOST:
-       return gp->own != 0 && (gp->own == player->cnum || player->god);
-    case EF_NATION:
-       return ((struct natstr *)p)->nat_stat != STAT_UNUSED;
+    case EF_REALM:
+       return gp->own == player->cnum || player->god;
     case EF_COUNTRY:
        return gp->own == player->cnum;
     case EF_NEWS:
-       return ((struct nwsstr *)p)->nws_vrb != 0
-           && (!opt_HIDDEN || player->god); /* FIXME */
+       return !opt_HIDDEN || player->god; /* FIXME */
     case EF_TREATY:
-       return tp->trt_status != TS_FREE
-           && (tp->trt_cna == player->cnum || tp->trt_cnb == player->cnum
-               || player->god);
+       return tp->trt_cna == player->cnum
+           || tp->trt_cnb == player->cnum
+           || player->god;
     case EF_LOAN:
-       if (lp->l_status == LS_FREE)
-           return 0;
        if (lp->l_status == LS_SIGNED)
            return 1;
        return lp->l_loner == player->cnum || lp->l_lonee == player->cnum
            || player->god;
-    case EF_TRADE:
-    case EF_COMM:
-       return gp->own != 0;
-    case EF_REALM:
-       natp = getnatp(((struct realmstr *)p)->r_cnum);
-       return (gp->own == player->cnum || player->god)
-           && (natp->nat_stat != STAT_UNUSED);
-    case EF_PRODUCT:
-       return ((struct pchrstr *)p)->p_sname[0] != 0;
     case EF_SHIP_CHR:
        tlev = ((struct mchrstr *)p)->m_tech;
-       name = ((struct mchrstr *)p)->m_name;
        goto tech;
     case EF_PLANE_CHR:
        tlev = ((struct plchrstr *)p)->pl_tech;
-       name = ((struct plchrstr *)p)->pl_name;
        goto tech;
     case EF_LAND_CHR:
        tlev = ((struct lchrstr *)p)->l_tech;
-       name = ((struct lchrstr *)p)->l_name;
     tech:
        natp = getnatp(player->cnum);
-       if (!name[0])
-           return 0;
        return player->god || tlev <= (int)(1.25 * natp->nat_level[NAT_TLEV]);
     case EF_NUKE_CHR:
        tlev = ((struct nchrstr *)p)->n_tech;
-       name = ((struct nchrstr *)p)->n_name;
        if (drnuke_const > MIN_DRNUKE_CONST) {
            natp = getnatp(player->cnum);
            if (tlev > (int)((int)(1.25 * natp->nat_level[NAT_RLEV])
@@ -117,8 +96,6 @@ xdvisible(int type, void *p)
                return player->god;
        }
        goto tech;
-    case EF_NEWS_CHR:
-       return ((struct rptstr *)p)->r_newspage != 0;
     case EF_TABLE:
        return ((struct empfile *)p)->cadef != NULL;
     default:
index fb18e663479669865d61e4baf1f234598534a94d..1ddd89e097daa11eb1b0bed80a7f8d4a713b44ac 100644 (file)
@@ -28,7 +28,7 @@
  *
  *  Known contributors to this file:
  *     Ron Koenderink, 2005
- *     Markus Armbruster, 2006-2010
+ *     Markus Armbruster, 2006-2011
  */
 
 #include <config.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include "empobj.h"
 #include "file.h"
 #include "misc.h"
 #include "nsc.h"
-#include "plane.h"
 #include "product.h"
 
 static void verify_fail(int, int, struct castr *, int, char *, ...)
@@ -130,7 +130,7 @@ static int
 verify_row(int type, int row)
 {
     struct castr *ca = ef_cadef(type);
-    struct emptypedstr *row_ref;
+    struct empobj *row_ref;
     int i, j, n;
     struct valstr val;
     int ret_val = 0;
@@ -150,6 +150,9 @@ verify_row(int type, int row)
        }
     }
 
+    if (!empobj_in_use(type, row_ref))
+       return ret_val;
+
     for (i = 0; ca[i].ca_name; ++i) {
        if (ca[i].ca_get)
            continue;           /* virtual */
@@ -166,10 +169,6 @@ verify_row(int type, int row)
            }
            if (ca[i].ca_table == type && i == 0) {
                /* uid */
-               /* Some files contain zeroed records, cope */
-               /* TODO tighten this check */
-               if (val.val_as.lng == 0)
-                   continue;
                if (val.val_as.lng != row) {
                    verify_fail(type, row, &ca[i], j,
                                "value is %ld instead of %d",
index a43c7281ed91b222699b9de3d1be2adb053ac2d9..5efe945855efc7c2c61049573f1f1531d8406c60 100644 (file)
@@ -36,7 +36,9 @@
 
 #include "empobj.h"
 #include "file.h"
+#include "news.h"
 #include "optlist.h"
+#include "product.h"
 
 char *
 empobj_chr_name(struct empobj *gp)
@@ -73,3 +75,45 @@ get_empobj_mob_max(int type)
     CANT_REACH();
     return -1;
 }
+
+int
+empobj_in_use(int type, void *p)
+{
+    switch (type) {
+    case EF_SHIP:
+    case EF_PLANE:
+    case EF_LAND:
+    case EF_NUKE:
+    case EF_TRADE:
+    case EF_COMM:
+    case EF_LOST:
+       return ((struct empobj *)p)->own != 0;
+    case EF_NATION:
+    case EF_COUNTRY:
+       return ((struct natstr *)p)->nat_stat != STAT_UNUSED;
+    case EF_NEWS:
+       return ((struct nwsstr *)p)->nws_vrb != 0;
+    case EF_TREATY:
+       return ((struct trtstr *)p)->trt_status != TS_FREE;
+    case EF_LOAN:
+       return ((struct lonstr *)p)->l_status != LS_FREE;
+    case EF_REALM:
+       return empobj_in_use(EF_NATION,
+                            ef_ptr(EF_NATION,
+                                   ((struct realmstr *)p)->r_cnum));
+    case EF_PRODUCT:
+       return ((struct pchrstr *)p)->p_sname[0];
+    case EF_SHIP_CHR:
+       return ((struct mchrstr *)p)->m_name[0];
+    case EF_PLANE_CHR:
+       return ((struct plchrstr *)p)->pl_name[0];
+    case EF_LAND_CHR:
+       return ((struct lchrstr *)p)->l_name[0];
+    case EF_NUKE_CHR:
+       return ((struct nchrstr *)p)->n_name[0];
+    case EF_NEWS_CHR:
+       return ((struct rptstr *)p)->r_newspage != 0;
+    default:
+       return 1;
+    }
+}