Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/games/gomoku gomoku: make parsing of the debug command 'o' r...



details:   https://anonhg.NetBSD.org/src/rev/9dadb26e2146
branches:  trunk
changeset: 366528:9dadb26e2146
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sun May 29 20:21:28 2022 +0000

description:
gomoku: make parsing of the debug command 'o' robust

Previously, the (invalid) debug command 'o,' succeeded to parse and led
to out-of-bounds memory access. Add proper parsing for the arguments of
that debug command. Add a short usage for that debug command, as
guessing the usage from the previous code was time-consuming due to the
large amount of ad-hoc low-level parsing code.

When leaving debug mode, clear the debug prompt.

diffstat:

 games/gomoku/main.c |  106 +++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 76 insertions(+), 30 deletions(-)

diffs (159 lines):

diff -r 1cd8b2a66bf8 -r 9dadb26e2146 games/gomoku/main.c
--- a/games/gomoku/main.c       Sun May 29 18:25:39 2022 +0000
+++ b/games/gomoku/main.c       Sun May 29 20:21:28 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: main.c,v 1.71 2022/05/29 17:01:42 rillig Exp $ */
+/*     $NetBSD: main.c,v 1.72 2022/05/29 20:21:28 rillig Exp $ */
 
 /*
  * Copyright (c) 1994
@@ -36,7 +36,7 @@
 __COPYRIGHT("@(#) Copyright (c) 1994\
  The Regents of the University of California.  All rights reserved.");
 /*     @(#)main.c      8.4 (Berkeley) 5/4/95   */
-__RCSID("$NetBSD: main.c,v 1.71 2022/05/29 17:01:42 rillig Exp $");
+__RCSID("$NetBSD: main.c,v 1.72 2022/05/29 20:21:28 rillig Exp $");
 
 #include <sys/stat.h>
 #include <curses.h>
@@ -412,6 +412,59 @@
 }
 
 #ifdef DEBUG
+
+static bool
+skip_any(const char **pp, const char *s)
+{
+       while (strchr(s, **pp) != NULL)
+               (*pp)++;
+       return true;
+}
+
+static bool
+parse_char_index(const char **pp, const char *s, unsigned int *out)
+{
+       const char *found = strchr(s, **pp);
+       if (found != NULL)
+               *out = (unsigned int)(found - s), (*pp)++;
+       return found != NULL;
+}
+
+static bool
+parse_direction(const char **pp, direction *out)
+{
+       unsigned int u;
+       if (!parse_char_index(pp, "-\\|/", &u))
+               return false;
+       *out = (direction)u;
+       return true;
+}
+
+static bool
+parse_row(const char **pp, unsigned int *out)
+{
+       if (!('0' <= **pp && **pp <= '9'))
+               return false;
+       unsigned int u = *(*pp)++ - '0';
+       if ('0' <= **pp && **pp <= '9')
+               u = 10 * u + *(*pp)++ - '0';
+       *out = u;
+       return 1 <= u && u <= BSZ;
+}
+
+static bool
+parse_spot(const char **pp, spot_index *out)
+{
+       unsigned row, col;
+       if (!parse_char_index(pp, "abcdefghjklmnopqrst", &col) &&
+           !parse_char_index(pp, "ABCDEFGHJKLMNOPQRST", &col))
+               return false;
+       if (!parse_row(pp, &row))
+               return false;
+       *out = PT(col + 1, row);
+       return true;
+}
+
 /*
  * Handle strange situations and ^C.
  */
@@ -419,12 +472,13 @@
 void
 whatsup(int signum __unused)
 {
-       int n, d1, d2;
+       unsigned int n;
        player_color color;
        spot_index s, s1, s2;
+       direction r1, r2;
        struct spotstr *sp;
        FILE *fp;
-       char *str;
+       const char *str;
        struct elist *ep;
        struct combostr *cbp;
        char input[128];
@@ -447,7 +501,8 @@
                debuglog("Debug set to %d", debug);
                goto top;
        case 'c':
-               break;
+               ask("");
+               return;
        case 'b':               /* back up a move */
                if (game.nmoves > 0) {
                        game.nmoves--;
@@ -485,30 +540,21 @@
                fclose(fp);
                goto top;
        case 'o':
-               /* avoid use w/o initialization on invalid input */
-               d1 = s1 = 0;
-
-               n = 0;
-               for (str = input + 1; *str != '\0'; str++)
-                       if (*str == ',') {
-                               for (d1 = 0; d1 < 4; d1++)
-                                       if (str[-1] == pdir[d1])
-                                               break;
-                               str[-1] = '\0';
-                               sp = &board[s1 = ctos(input + 1)];
-                               n = sp->s_frame[d1] * FAREA;
-                               *str++ = '\0';
-                               break;
-                       }
-               sp = &board[s2 = ctos(str)];
-               while (*str != '\0')
-                       str++;
-               for (d2 = 0; d2 < 4; d2++)
-                       if (str[-1] == pdir[d2])
-                               break;
-               n += sp->s_frame[d2];
-               debuglog("overlap %s%c,%s%c = %x", stoc(s1), pdir[d1],
-                   stoc(s2), pdir[d2], overlap[n]);
+               str = input + 1;
+               if (skip_any(&str, " ") &&
+                   parse_spot(&str, &s1) &&
+                   parse_direction(&str, &r1) &&
+                   skip_any(&str, ", ") &&
+                   parse_spot(&str, &s2) &&
+                   parse_direction(&str, &r2) &&
+                   *str == '\0') {
+                       n = board[s1].s_frame[r1] * FAREA
+                           + board[s2].s_frame[r2];
+                       debuglog("overlap %s%c,%s%c = %02x",
+                           stoc(s1), pdir[r1], stoc(s2), pdir[r2],
+                           overlap[n]);
+               } else
+                       debuglog("usage: o <spot><dir> <spot><dir>");
                goto top;
        case 'p':
                sp = &board[s = ctos(input + 1)];
@@ -524,7 +570,7 @@
                        sp->s_fval[WHITE][0].s, sp->s_fval[WHITE][1].s,
                        sp->s_fval[WHITE][2].s, sp->s_fval[WHITE][3].s);
                goto top;
-       case 'e':       /* e {b|w} [0-9] spot */
+       case 'e':       /* e [0-9] spot */
                str = input + 1;
                if (*str >= '0' && *str <= '9')
                        n = *str++ - '0';



Home | Main Index | Thread Index | Old Index