]> git.pond.sub.org Git - empserver/commitdiff
Make generation numbers catch more potential yields on input
authorMarkus Armbruster <armbru@pond.sub.org>
Mon, 11 Apr 2011 19:37:23 +0000 (21:37 +0200)
committerMarkus Armbruster <armbru@pond.sub.org>
Thu, 14 Apr 2011 18:21:23 +0000 (20:21 +0200)
getstarg(), snxtitem() and snxtsct() can yield the processor, because
they call getstring().  But only for null or empty arguments.  For
other arguments, we should call ef_make_stale(), to catch errors.
Problem: if a caller never passes null or empty arguments, it may rely
on these functions not yielding.  We'd get false positives.  In
general, we can't know whether that's the case.  But we do know in the
common special case of player arguments.  Call ef_make_stale() for
those.

include/prototypes.h
src/lib/player/player.c
src/lib/subs/getstarg.c
src/lib/subs/onearg.c
src/lib/subs/snxtitem.c
src/lib/subs/snxtsct.c

index 07a03b64c5528392980bce2728f3aec58585eb0f..13c0ed7c94888aaa04d38791cec378557a607103 100644 (file)
@@ -363,6 +363,7 @@ extern int natpass(natid, char *);
 extern struct player *player;  /* current player's context */
 extern char *praddr(struct player *);
 extern void player_main(struct player *);
+extern void make_stale_if_command_arg(char *);
 /* more under Commands */
 /* recvclient.c */
 extern int recvclient(char *, int);
index 7f40b13e07b2873a87828662e8dff3cf7c4e8bfb..d93211eb939a460437a450be5a20aef612158e2d 100644 (file)
@@ -202,6 +202,36 @@ status(void)
     return 1;
 }
 
+/* Is ARG one of the player's last command's arguments?  */
+static int
+is_command_arg(char *arg)
+{
+    int i;
+
+    for (i = 1; i < 128 && player->argp[i]; i++) {
+       if (arg == player->argp[i])
+           return 1;
+    }
+    return 0;
+}
+
+/*
+ * Make all objects stale if ARG is one of the player's command arguments.
+ * See ef_make_stale() for what "making stale" means.
+ * Useful for functions that prompt for missing arguments.
+ * These can yield the processor, so we'd like to call ef_make_stale()
+ * there.  Except that leads to false positives when the caller passes
+ * an argument that is never null, and relies on the fact that the
+ * function doesn't yield then.  We can't know that in general.  But
+ * we do know in the common special case of command arguments.
+ */
+void
+make_stale_if_command_arg(char *arg)
+{
+    if (is_command_arg(arg))
+       ef_make_stale();
+}
+
 /*
  * XXX This whole mess should be redone; execute block should
  * start with "exec start", and should end with "exec end".
index 20c6af61bb7def15d9a6db8bf307ead72e3cf94b..731bed1eed93436c8caf16b5ff6769ebfcd18b36 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <string.h>
 #include "misc.h"
+#include "prototypes.h"
 
 /*
  * Get string argument.
@@ -50,6 +51,7 @@ getstarg(char *input, char *prompt, char *buf)
            return NULL;
     } else {
        strcpy(buf, input);
+       make_stale_if_command_arg(input);
     }
     return buf;
 }
index b97ce0a71d0d022595987fa448a9c2b114aa7547..3784bdc784cf84b39fde2a87806260a963e19a61 100644 (file)
@@ -43,7 +43,8 @@ onearg(char *arg, char *prompt)
     if (!arg || !*arg) {
        if (!(arg = getstring(prompt, buf)))
            return -1;
-    }
+    } else
+       make_stale_if_command_arg(arg);
     n = atoi(arg);
     if (n < 0)
        return -1;
index da8b86adeba4b883a963ab5cae080e6ce258d176..bcb8f7d0245d367acbb631e8dfaa0d4532131320 100644 (file)
@@ -73,9 +73,9 @@ snxtitem(struct nstr_item *np, int type, char *str, char *prompt)
        str = getstring(prompt, buf);
        if (!str)
            return 0;
-    }
+    } else
+       make_stale_if_command_arg(str);
     if (*str == 0) {
-       /* empty string passed by player */
        return 0;
     }
     if (type == EF_NATION && isalpha(*str)) {
index 7657c4560c9866ab944235b314467b4f8a007219..01d8b59744b1031ae4a8fa2e32389b49518ff030 100644 (file)
@@ -44,7 +44,7 @@
 
 /*
  * setup the nstr_sect structure for sector selection.
- * can select on either NS_ALL, NS_AREA, or NS_RANGE
+ * can select on either NS_ALL, NS_AREA, or NS_DIST
  * iterate thru the "condarg" string looking
  * for arguments to compile into the nstr.
  * Using this function for anything but command arguments is usually
@@ -63,7 +63,8 @@ snxtsct(struct nstr_sect *np, char *str)
     if (!str || !*str) {
        if (!(str = getstring("(sects)? ", buf)))
            return 0;
-    }
+    } else
+       make_stale_if_command_arg(str);
     switch (sarg_type(str)) {
     case NS_AREA:
        if (!sarg_area(str, &range))