security fix: replaced strcpy with safeStrCpy from backend.c
[xboard.git] / winboard / jaws.c
index 8aad901..8d7e42c 100644 (file)
@@ -5,7 +5,7 @@
  * Massachusetts.\r
  *\r
  * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,\r
- * 2007, 2008, 2009 Free Software Foundation, Inc.\r
+ * 2007, 2008, 2009, 2010 Free Software Foundation, Inc.\r
  *\r
  * XBoard borrows its colors and the bitmaps.xchess bitmap set from XChess,\r
  * which was written and is copyrighted by Wayne Christopher.\r
@@ -162,9 +162,9 @@ PSAYSTRING RealSayString;
 \r
 VOID SayString(char *mess, BOOL flag)\r
 { // for debug file\r
-       char buf[MSG_SIZ], *p;\r
+       char buf[8000], *p;\r
        if(appData.debugMode) fprintf(debugFP, "SAY '%s'\n", mess);\r
-       strcpy(buf, mess);\r
+       safeStrCpy(buf, mess, sizeof(buf)/sizeof(buf[0]));\r
        if(p = StrCaseStr(buf, "Xboard adjudication:")) {\r
                int i;\r
                for(i=19; i>1; i--) p[i] = p[i-1];\r
@@ -229,7 +229,6 @@ AdaptMenu()
 \r
        helpMenuInfo.cbSize = sizeof(helpMenuInfo);\r
        menuMain = GetMenu(hwndMain);\r
-       if(appData.debugMode) fprintf(debugFP, "hwndMain: %8x %8x\n", hwndMain, menuMain);\r
        menuJAWS = CreatePopupMenu();\r
        \r
        for(i=0; menuItemJAWS[i].name; i++) {\r
@@ -283,6 +282,7 @@ InitJAWS()
 \r
 int beeps[] = { 1, 0, 0, 0, 0 };\r
 int beepCodes[] = { 0, MB_OK, MB_ICONERROR, MB_ICONQUESTION, MB_ICONEXCLAMATION, MB_ICONASTERISK };\r
+static int dropX = -1, dropY = -1;\r
 \r
 VOID\r
 KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
@@ -291,6 +291,10 @@ KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        char *piece, *xchar, *ynum ;\r
        int n, beepType = 1; // empty beep\r
 \r
+       if(fromX == -1 || fromY == -1) { // if we just dropped piece, stay at that square\r
+               fromX = dropX; fromY = dropY;\r
+               dropX = dropY = -1; // but only once\r
+        }\r
        if(fromX == -1 || fromY == -1) {\r
                fromX = BOARD_LEFT; fromY = 0;\r
         }\r
@@ -346,14 +350,13 @@ KeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                ynum = SquareToNum(fromY);\r
                if(currentPiece != EmptySquare) {\r
 //                     SayString(piece[0] == 'W' ? "white" : "black", TRUE);\r
-                       sprintf(buf, "%s %s %s", piece, xchar, ynum);\r
+                       sprintf(buf, "%s %s %s", xchar, ynum, piece);\r
                } else sprintf(buf, "%s %s", xchar, ynum);\r
                SayString(buf, TRUE);\r
        }\r
        return;\r
 }\r
 \r
-extern char castlingRights[MAX_MOVES][BOARD_SIZE];\r
 int PosFlags(int nr);\r
 \r
 typedef struct {\r
@@ -432,8 +435,7 @@ PossibleAttackMove()
        swapColor = piece <  (int)BlackPawn && !WhiteOnMove(currentMove) ||\r
                    piece >= (int)BlackPawn &&  WhiteOnMove(currentMove);\r
        cl.count = 0; cl.rf = fromY; cl.ff = fromX; cl.rt = cl.ft = -1;\r
-       GenLegal(boards[currentMove], PosFlags(currentMove + swapColor), EP_NONE, \r
-                                               castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);\r
+       GenLegal(boards[currentMove], PosFlags(currentMove + swapColor), ReadCallback, (VOIDSTAR) &cl);\r
        if(cl.count == 0) SayString("None", FALSE);\r
        boards[currentMove][fromY][fromX] = victim; // repair\r
 \r
@@ -460,16 +462,14 @@ PossibleAttacked()
        victim = boards[currentMove][fromY][fromX]; // put dummy piece on target square, to activate Pawn captures\r
        boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen;\r
        cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1;\r
-       GenLegal(boards[currentMove], PosFlags(currentMove+1), EP_NONE, \r
-                                               castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);\r
+       GenLegal(boards[currentMove], PosFlags(currentMove+1), ReadCallback, (VOIDSTAR) &cl);\r
        if(cl.count == 0) SayString("None", FALSE);\r
 \r
        SayString("You are defended by", FALSE);\r
 \r
        boards[currentMove][fromY][fromX] = WhiteOnMove(currentMove) ? BlackQueen : WhiteQueen;\r
        cl.count = 0; cl.rt = fromY; cl.ft = fromX; cl.rf = cl.ff = -1;\r
-       GenLegal(boards[currentMove], PosFlags(currentMove), EP_NONE, \r
-                                               castlingRights[currentMove], ReadCallback, (VOIDSTAR) &cl);\r
+       GenLegal(boards[currentMove], PosFlags(currentMove), ReadCallback, (VOIDSTAR) &cl);\r
        if(cl.count == 0) SayString("None", FALSE);\r
        boards[currentMove][fromY][fromX] = victim; // put back original occupant\r
 \r
@@ -894,11 +894,11 @@ SayAllBoard()
 VOID\r
 SayWhosTurn()\r
 {\r
-       if(gameMode == MachinePlaysBlack || gameMode == IcsPlayingBlack) {\r
+       if(gameMode == MachinePlaysBlack || gameMode == IcsPlayingWhite) {\r
                if(WhiteOnMove(currentMove))\r
                        SayString("It is your turn", FALSE);\r
                else    SayString("It is your opponents turn", FALSE);\r
-       } else if(gameMode == MachinePlaysWhite || gameMode == IcsPlayingWhite) {\r
+       } else if(gameMode == MachinePlaysWhite || gameMode == IcsPlayingBlack) {\r
                if(WhiteOnMove(currentMove))\r
                        SayString("It is your opponents turn", FALSE);\r
                else    SayString("It is your turn", FALSE);\r
@@ -952,7 +952,7 @@ SayMachineMove(int evenIfDuplicate)
                                    break;\r
                                }\r
                            }\r
-                           if(c != lastMover) return; // line is thinking output of future move, ignore.\r
+                           if(c != lastMover && !evenIfDuplicate) return; // line is thinking output of future move, ignore.\r
                            if(2*moveNr - (dotCount < 2) == previousMove)\r
                                return; // do not repeat same move; likely ponder output\r
                            sprintf(buf, "score %s %d at %d ply", \r
@@ -1076,11 +1076,11 @@ SayClockTime()
                suppressClocks = 0; // back on after two requests in rapid succession\r
        sprintf(buf1, "%s", TimeString(whiteTimeRemaining));\r
        str1 = buf1;\r
-       SayString("White's remaining time is", FALSE);\r
+       SayString("White clock", FALSE);\r
        SayString(str1, FALSE);\r
        sprintf(buf2, "%s", TimeString(blackTimeRemaining));\r
        str2 = buf2;\r
-       SayString("Black's remaining time is", FALSE);\r
+       SayString("Black clock", FALSE);\r
        SayString(str2, FALSE);\r
        lastWhiteTime = whiteTimeRemaining;\r
        lastBlackTime = blackTimeRemaining;\r
@@ -1123,9 +1123,10 @@ KeyboardMove(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                                (BlackPawn <= pdown && pdown <= BlackKing &&\r
                                 BlackPawn <= pup && pup <= BlackKing))) {\r
                        /* EditPosition, empty square, or different color piece;\r
-                       click-click move is possible */\r
+                       click-click move is possible */         \r
+                       char promoChoice = NULLCHAR;\r
                \r
-                       if (IsPromotion(oldFromX, oldFromY, fromX, fromY)) {\r
+                       if (HasPromotionChoice(oldFromX, oldFromY, fromX, fromY, &promoChoice)) {\r
                                if (appData.alwaysPromoteToQueen) {\r
                                        UserMoveEvent(oldFromX, oldFromY, fromX, fromY, 'q');\r
                                }\r
@@ -1136,7 +1137,7 @@ KeyboardMove(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                                }       \r
                        }\r
                        else {\r
-                               UserMoveEvent(oldFromX, oldFromY, fromX, fromY, NULLCHAR);\r
+                               UserMoveEvent(oldFromX, oldFromY, fromX, fromY, promoChoice);\r
                        }\r
                oldFromX = oldFromY = -1;\r
                break;\r
@@ -1184,11 +1185,11 @@ NiceTime(int x)
 }\r
 \r
 #define JAWS_ARGS \\r
-  { "beepOffBoard", ArgInt, (LPVOID) beeps, TRUE },\\r
-  { "beepEmpty", ArgInt, (LPVOID) (beeps+1), TRUE },\\r
-  { "beepWhite", ArgInt, (LPVOID) (beeps+2), TRUE },\\r
-  { "beepBlack", ArgInt, (LPVOID) (beeps+3), TRUE },\\r
-  { "beepHoldings", ArgInt, (LPVOID) (beeps+4), TRUE },\\r
+  { "beepOffBoard", ArgInt, (LPVOID) beeps, TRUE, (ArgIniType) 1 },\\r
+  { "beepEmpty", ArgInt, (LPVOID) (beeps+1), TRUE, (ArgIniType) 0 },\\r
+  { "beepWhite", ArgInt, (LPVOID) (beeps+2), TRUE, (ArgIniType) 0 },\\r
+  { "beepBlack", ArgInt, (LPVOID) (beeps+3), TRUE, (ArgIniType) 0 },\\r
+  { "beepHoldings", ArgInt, (LPVOID) (beeps+4), TRUE, (ArgIniType) 0 },\\r
 \r
 #define JAWS_ALT_INTERCEPT \\r
            if(suppressOneKey) {\\r
@@ -1198,6 +1199,7 @@ NiceTime(int x)
            if ((char)wParam == 022 && gameMode == EditPosition) { /* <Ctl R>. Pop up piece menu */\\r
                POINT pt; int x, y;\\r
                SquareToPos(fromY, fromX, &x, &y);\\r
+               dropX = fromX; dropY = fromY;\\r
                pt.x = x; pt.y = y;\\r
                if(gameInfo.variant != VariantShogi)\\r
                    MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\\r