summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2017-01-31 04:28:02 +0100
committerWilliam Wilgus <me.theuser@yahoo.com>2017-02-01 01:33:48 +0100
commit1fa7c5635184e3a8c16b696a658c027fcc0862d8 (patch)
treedebeb03ca2da9a20ccfae5ece4fc512847046014 /apps
parent37522ec63ae8fd2f88a66ed3d7020ebe95e9980e (diff)
downloadrockbox-1fa7c5635184e3a8c16b696a658c027fcc0862d8.tar.gz
rockbox-1fa7c5635184e3a8c16b696a658c027fcc0862d8.zip
Fix for Chessbox bug FS#10363
Chessbox was overflowing GameList[240] causing the board to flip + crash GameCnt changed to unsigned char which allows the array to roll over to 0 after 255 define MAX_GAME_CNT 256 and GameList[MAX_GAME_CNT] along with 1 byte GameCnt should fix this issue dbg save routine left in for now to help identify any other problems Added bounds checking to prevent second bug found when loading .pgn files Change-Id: I2b615c8ecbed4368724412f80ce07346f3cf30a7
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/chessbox/chessbox.c112
-rw-r--r--apps/plugins/chessbox/chessbox_pgn.c70
-rw-r--r--apps/plugins/chessbox/gnuchess.c9
-rw-r--r--apps/plugins/chessbox/gnuchess.h7
4 files changed, 164 insertions, 34 deletions
diff --git a/apps/plugins/chessbox/chessbox.c b/apps/plugins/chessbox/chessbox.c
index 86ca5a355e..7d42b72c1b 100644
--- a/apps/plugins/chessbox/chessbox.c
+++ b/apps/plugins/chessbox/chessbox.c
@@ -26,8 +26,7 @@
26#if (MEMORYSIZE > 8) /* Lowmem doesn't have playback in chessbox */ 26#if (MEMORYSIZE > 8) /* Lowmem doesn't have playback in chessbox */
27#define HAVE_PLAYBACK_CONTROL 27#define HAVE_PLAYBACK_CONTROL
28#endif 28#endif
29 29/*#define CHESSBOX_SAVE_FILE_DBG PLUGIN_GAMES_DATA_DIR "/chessbox_dbg.save"*/
30
31#ifdef HAVE_PLAYBACK_CONTROL 30#ifdef HAVE_PLAYBACK_CONTROL
32#include "lib/playback_control.h" 31#include "lib/playback_control.h"
33#endif 32#endif
@@ -265,12 +264,117 @@ static void cb_levelup ( void ) {
265 rb->splash ( HZ/2 , level_string[Level-1] ); 264 rb->splash ( HZ/2 , level_string[Level-1] );
266}; 265};
267 266
267#ifdef CHESSBOX_SAVE_FILE_DBG
268/* Save a debug file with names, variables, and sizes */
269static void cb_saveposition_dbg ( void )
270{
271 int fd;
272 short sq,i,c;
273 unsigned short temp;
274 char buf[32]="\0";
275 int ch_ct = 0;
276
277 rb->splash ( 0 , "Saving debug" );
278 fd = rb->open(CHESSBOX_SAVE_FILE_DBG, O_WRONLY|O_CREAT, 0666);
279 ch_ct = rb->snprintf(buf,31,"computer = %d, %d bytes\n",computer+1,
280 sizeof(computer));
281 rb->write(fd, buf, ch_ct);
282 ch_ct = rb->snprintf(buf,31,"opponent = %d, %d bytes\n",opponent+1,
283 sizeof(opponent));
284 rb->write(fd, buf, ch_ct);
285 ch_ct = rb->snprintf(buf,31,"Game50 = %d, %d bytes\n",Game50,
286 sizeof(Game50));
287 rb->write(fd, buf, ch_ct);
288 ch_ct = rb->snprintf(buf,31,"CastldWht = %d, %d bytes\n",castld[white],
289 sizeof(castld[white]));
290 rb->write(fd, buf, ch_ct);
291 ch_ct = rb->snprintf(buf,31,"CastldBlk = %d, %d bytes\n",castld[black],
292 sizeof(castld[black]));
293 rb->write(fd, buf, ch_ct);
294 ch_ct = rb->snprintf(buf,31,"KngMovedWht = %d, %d bytes\n",kingmoved[white],
295 sizeof(kingmoved[white]));
296 rb->write(fd, buf, ch_ct);
297 ch_ct = rb->snprintf(buf,31,"KngMovedBlk = %d, %d bytes\n",kingmoved[black],
298 sizeof(kingmoved[black]));
299 rb->write(fd, buf, ch_ct);
300 ch_ct = rb->snprintf(buf,31,"WithBook = %d, %d bytes\n",withbook,
301 sizeof(withbook));
302 rb->write(fd, buf, ch_ct);
303 ch_ct = rb->snprintf(buf,31,"Lvl = %ld, %d bytes\n",Level,
304 sizeof(Level));
305 rb->write(fd, buf, ch_ct);
306 ch_ct = rb->snprintf(buf,31,"TCflag = %d, %d bytes\n",TCflag,
307 sizeof(TCflag));
308 rb->write(fd, buf, ch_ct);
309 ch_ct = rb->snprintf(buf,31,"OpTime = %d, %d bytes\n",OperatorTime,
310 sizeof(OperatorTime));
311 rb->write(fd, buf, ch_ct);
312 ch_ct = rb->snprintf(buf,31,"TmCtlClkWht = %ld, %d bytes\n",
313 TimeControl.clock[white], sizeof(TimeControl.clock[white]));
314 rb->write(fd, buf, ch_ct);
315 ch_ct = rb->snprintf(buf,31,"TmCtlClkBlk = %ld, %d bytes\n",
316 TimeControl.clock[black], sizeof(TimeControl.clock[black]));
317 rb->write(fd, buf, ch_ct);
318 ch_ct = rb->snprintf(buf,31,"TmCtlMovesWht = %d, %d bytes\n",
319 TimeControl.moves[white], sizeof(TimeControl.moves[white]));
320 rb->write(fd, buf, ch_ct);
321 ch_ct = rb->snprintf(buf,31,"TmCtlMovesBlk = %d, %d bytes\n",
322 TimeControl.moves[black], sizeof(TimeControl.moves[black]));
323 rb->write(fd, buf, ch_ct);
324 for (sq = 0; sq < 64; sq++) {
325 if (color[sq] == neutral) c = 0; else c = color[sq]+1;
326 temp = 256*board[sq] + c ;
327 ch_ct = rb->snprintf(buf,31,"sq %02d = %d, %d bytes\n",sq, temp,
328 sizeof(temp));
329 rb->write(fd, buf, ch_ct);
330 }
331 for (i = 0; i <= GameCnt; i++) {
332 ch_ct = rb->snprintf(buf,31,"GameCt %d, %d bytes\n",i,
333 sizeof(GameCnt));
334 rb->write(fd, buf, ch_ct);
335 if (GameList[i].color == neutral)
336 {
337 c = 0;
338 ch_ct = rb->snprintf(buf,31,"color = %d, %d bytes\n",c,
339 sizeof(c));
340 rb->write(fd, buf, ch_ct);
341 }
342 else
343 c = GameList[i].color + 1;
344 ch_ct = rb->snprintf(buf,31,"gmove = %d, %d bytes\n",GameList[i].gmove,
345 sizeof(GameList[i].gmove));
346 rb->write(fd, buf, ch_ct);
347 ch_ct = rb->snprintf(buf,31,"score = %d, %d bytes\n",GameList[i].score,
348 sizeof(GameList[i].score));
349 rb->write(fd, buf, ch_ct);
350 ch_ct = rb->snprintf(buf,31,"depth = %d, %d bytes\n",GameList[i].depth,
351 sizeof(GameList[i].depth));
352 rb->write(fd, buf, ch_ct);
353 ch_ct = rb->snprintf(buf,31,"nodes = %ld, %d bytes\n",GameList[i].nodes,
354 sizeof(GameList[i].nodes));
355 rb->write(fd, buf, ch_ct);
356 ch_ct = rb->snprintf(buf,31,"time = %d, %d bytes\n",GameList[i].time,
357 sizeof(GameList[i].time));
358 rb->write(fd, buf, ch_ct);
359 ch_ct = rb->snprintf(buf,31,"piece = %d, %d bytes\n",GameList[i].piece,
360 sizeof(GameList[i].piece));
361 rb->write(fd, buf, ch_ct);
362 ch_ct = rb->snprintf(buf,31,"color = %d, %d bytes\n",c,sizeof(c));
363 rb->write(fd, buf, ch_ct);
364 }
365 rb->close(fd);
366
367}
368#endif
369
268/* ---- Save current position ---- */ 370/* ---- Save current position ---- */
269static void cb_saveposition ( void ) { 371static void cb_saveposition ( void ) {
270 int fd; 372 int fd;
271 short sq,i,c; 373 short sq,i,c;
272 unsigned short temp; 374 unsigned short temp;
273 375#ifdef CHESSBOX_SAVE_FILE_DBG
376 cb_saveposition_dbg();
377#endif
274 rb->splash ( 0 , "Saving position" ); 378 rb->splash ( 0 , "Saving position" );
275 379
276 fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT, 0666); 380 fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT, 0666);
@@ -356,7 +460,7 @@ static void cb_restoreposition ( void ) {
356 else 460 else
357 --color[sq]; 461 --color[sq];
358 } 462 }
359 GameCnt = -1; 463 GameCnt = MAX_GAME_CNT - 1; /*uchar rollsover to 0 after 255*/
360 while (rb->read(fd, &(GameList[++GameCnt].gmove), 464 while (rb->read(fd, &(GameList[++GameCnt].gmove),
361 sizeof(GameList[GameCnt].gmove)) > 0) { 465 sizeof(GameList[GameCnt].gmove)) > 0) {
362 rb->read(fd, &(GameList[GameCnt].score), 466 rb->read(fd, &(GameList[GameCnt].score),
diff --git a/apps/plugins/chessbox/chessbox_pgn.c b/apps/plugins/chessbox/chessbox_pgn.c
index 98d9e29431..f5f19e2688 100644
--- a/apps/plugins/chessbox/chessbox_pgn.c
+++ b/apps/plugins/chessbox/chessbox_pgn.c
@@ -159,9 +159,10 @@ static char pgn_from_piece(unsigned short piece, unsigned short color){
159 return pgn_piece; 159 return pgn_piece;
160} 160}
161 161
162static void pgn_to_coords(struct pgn_ply_node* ply){ 162static bool pgn_to_coords(struct pgn_ply_node* ply){
163 bool success = true;
163 unsigned short str_length = rb->strlen(ply->pgn_text); 164 unsigned short str_length = rb->strlen(ply->pgn_text);
164 char str[10]; 165 char str[9];
165 rb->strcpy(str,ply->pgn_text); 166 rb->strcpy(str,ply->pgn_text);
166 ply->column_from = 0xFF; 167 ply->column_from = 0xFF;
167 ply->row_from = 0xFF; 168 ply->row_from = 0xFF;
@@ -172,6 +173,7 @@ static void pgn_to_coords(struct pgn_ply_node* ply){
172 ply->enpassant = false; 173 ply->enpassant = false;
173 ply->castle = false; 174 ply->castle = false;
174 ply->promotion = false; 175 ply->promotion = false;
176
175 unsigned short i, j, piece; 177 unsigned short i, j, piece;
176 bool found = false; 178 bool found = false;
177 179
@@ -342,16 +344,25 @@ static void pgn_to_coords(struct pgn_ply_node* ply){
342 /* leave a very complete log of the parsing of the game while it gets stable */ 344 /* leave a very complete log of the parsing of the game while it gets stable */
343 for (i=0;i<8;i++){ 345 for (i=0;i<8;i++){
344 for (j=0;j<8;j++) { 346 for (j=0;j<8;j++) {
347
345 rb->fdprintf(loghandler,"%c",pgn_from_piece(board[locn[7-i][j]],color[locn[7-i][j]])); 348 rb->fdprintf(loghandler,"%c",pgn_from_piece(board[locn[7-i][j]],color[locn[7-i][j]]));
346 } 349 }
347 rb->fdprintf(loghandler,"\n"); 350 rb->fdprintf(loghandler,"\n");
348 } 351 }
349 352 /* check bounds of row and columns should be 0-7 bad .pgn returns 0xFF */
353 if ((ply->row_to | ply->column_to | ply->row_from | ply->column_from) < 8)
354 {
350 /* update the board */ 355 /* update the board */
351 board[locn[ply->row_to][ply->column_to]] = board[locn[ply->row_from][ply->column_from]]; 356 board[locn[ply->row_to][ply->column_to]] =
352 color[locn[ply->row_to][ply->column_to]] = color[locn[ply->row_from][ply->column_from]]; 357 board[locn[ply->row_from][ply->column_from]];
353 board[locn[ply->row_from][ply->column_from]] = no_piece; 358 color[locn[ply->row_to][ply->column_to]] =
354 color[locn[ply->row_from][ply->column_from]] = neutral; 359 color[locn[ply->row_from][ply->column_from]];
360 board[locn[ply->row_from][ply->column_from]] = no_piece;
361 color[locn[ply->row_from][ply->column_from]] = neutral;
362 }
363 else
364 success = false; /*ERROR*/
365 return success;
355} 366}
356 367
357static void coords_to_pgn(struct pgn_ply_node* ply){ 368static void coords_to_pgn(struct pgn_ply_node* ply){
@@ -657,9 +668,10 @@ void pgn_parse_game(const char* filename,
657 struct pgn_game_node* selected_game){ 668 struct pgn_game_node* selected_game){
658 struct pgn_ply_node size_ply, *first_ply = NULL; 669 struct pgn_ply_node size_ply, *first_ply = NULL;
659 struct pgn_ply_node *temp_ply = NULL, *curr_node = NULL; 670 struct pgn_ply_node *temp_ply = NULL, *curr_node = NULL;
671 bool success = true;
660 int fhandler, i; 672 int fhandler, i;
661 char line_buffer[128]; 673 char line_buffer[128];
662 char token_buffer[10]; 674 char token_buffer[9];
663 unsigned short pos; 675 unsigned short pos;
664 unsigned short curr_player = white; 676 unsigned short curr_player = white;
665 677
@@ -685,24 +697,35 @@ void pgn_parse_game(const char* filename,
685 || (token_buffer[0] >= 'a' && token_buffer[0] <= 'z') 697 || (token_buffer[0] >= 'a' && token_buffer[0] <= 'z')
686 || (token_buffer[0] == '0' && token_buffer[2] != '1')){ 698 || (token_buffer[0] == '0' && token_buffer[2] != '1')){
687 temp_ply = (struct pgn_ply_node *)pl_malloc(sizeof size_ply); 699 temp_ply = (struct pgn_ply_node *)pl_malloc(sizeof size_ply);
688 temp_ply->player = curr_player; 700 /* Null pointer can be returned from pl_malloc check for this */
689 curr_player = (curr_player==white)?black:white; 701 if (temp_ply)
690 rb->strcpy(temp_ply->pgn_text, token_buffer); 702 {
691 pgn_to_coords(temp_ply); 703 temp_ply->player = curr_player;
692 temp_ply->prev_node = NULL; 704 curr_player = (curr_player==white)?black:white;
693 temp_ply->next_node = NULL; 705 rb->strcpy(temp_ply->pgn_text, token_buffer);
694 if (first_ply == NULL) { 706 success = pgn_to_coords(temp_ply);
695 first_ply = curr_node = temp_ply; 707 temp_ply->prev_node = NULL;
696 } else { 708 temp_ply->next_node = NULL;
697 curr_node->next_node = temp_ply; 709 if (first_ply == NULL && success) {
698 temp_ply->prev_node = curr_node; 710 first_ply = curr_node = temp_ply;
699 curr_node = temp_ply; 711 } else if (success){
700 } 712 curr_node->next_node = temp_ply;
701 rb->fdprintf(loghandler, 713 temp_ply->prev_node = curr_node;
702 "player: %u; pgn: %s; from: %u,%u; to: %u,%u; taken: %u.\n", 714 curr_node = temp_ply;
715 } else{
716 /* bad .pgn break loop and notify user */
717 first_ply = NULL;
718 break;
719 }
720
721 rb->fdprintf(loghandler,
722 "player: %u; pgn: %s; from: %u,%u; to: %u,%u; taken: %u.\n",
703 temp_ply->player, temp_ply->pgn_text, temp_ply->row_from, 723 temp_ply->player, temp_ply->pgn_text, temp_ply->row_from,
704 temp_ply->column_from, temp_ply->row_to, 724 temp_ply->column_from, temp_ply->row_to,
705 temp_ply->column_to, temp_ply->taken_piece); 725 temp_ply->column_to, temp_ply->taken_piece);
726 }
727 else
728 first_ply = NULL;
706 } 729 }
707 } 730 }
708 } 731 }
@@ -719,6 +742,7 @@ void pgn_parse_game(const char* filename,
719 curr_node->next_node = temp_ply; 742 curr_node->next_node = temp_ply;
720 } 743 }
721 selected_game->first_ply = first_ply; 744 selected_game->first_ply = first_ply;
745
722 rb->close(fhandler); 746 rb->close(fhandler);
723} 747}
724 748
diff --git a/apps/plugins/chessbox/gnuchess.c b/apps/plugins/chessbox/gnuchess.c
index 5e67df4f39..4b21cd785c 100644
--- a/apps/plugins/chessbox/gnuchess.c
+++ b/apps/plugins/chessbox/gnuchess.c
@@ -103,8 +103,9 @@ short INCscore;
103short HasPawn[2],HasKnight[2],HasBishop[2],HasRook[2],HasQueen[2]; 103short HasPawn[2],HasKnight[2],HasBishop[2],HasRook[2],HasQueen[2];
104short ChkFlag[maxdepth],CptrFlag[maxdepth],PawnThreat[maxdepth]; 104short ChkFlag[maxdepth],CptrFlag[maxdepth],PawnThreat[maxdepth];
105short Pscore[maxdepth],Tscore[maxdepth],Threat[maxdepth]; 105short Pscore[maxdepth],Tscore[maxdepth],Threat[maxdepth];
106struct GameRec GameList[240]; 106struct GameRec GameList[MAX_GAME_CNT];
107short GameCnt,Game50,epsquare,lpost,rcptr,contempt; 107unsigned char GameCnt; /*Bug fix now rolls over instead of overflow*/
108short Game50,epsquare,lpost,rcptr,contempt;
108short MaxSearchDepth,Xscore; 109short MaxSearchDepth,Xscore;
109struct TimeControlRec TimeControl; 110struct TimeControlRec TimeControl;
110short TCflag,TCmoves,TCminutes,OperatorTime; 111short TCflag,TCmoves,TCminutes,OperatorTime;
@@ -1132,7 +1133,7 @@ static short i,alpha,beta,score,tempb,tempc,tempsf,tempst,xside,rpt;
1132 if (--TimeControl.moves[side] == 0) SetTimeControl(); 1133 if (--TimeControl.moves[side] == 0) SetTimeControl();
1133 } 1134 }
1134 if ((root->flags & draw) && bothsides) quit = true; 1135 if ((root->flags & draw) && bothsides) quit = true;
1135 if (GameCnt > 238) quit = true; 1136 if (GameCnt > MAX_GAME_CNT - 2) quit = true;
1136 player = xside; 1137 player = xside;
1137 Sdepth = 0; 1138 Sdepth = 0;
1138 return(0); 1139 return(0);
@@ -2319,7 +2320,7 @@ void NewGame() {
2319 xwndw = 90; 2320 xwndw = 90;
2320 MaxSearchDepth = 29; 2321 MaxSearchDepth = 29;
2321 contempt = 0; 2322 contempt = 0;
2322 GameCnt = -1; Game50 = 0; 2323 GameCnt = MAX_GAME_CNT - 1; Game50 = 0;
2323 Zwmtl = Zbmtl = 0; 2324 Zwmtl = Zbmtl = 0;
2324 Developed[white] = Developed[black] = false; 2325 Developed[white] = Developed[black] = false;
2325 castld[white] = castld[black] = false; 2326 castld[white] = castld[black] = false;
diff --git a/apps/plugins/chessbox/gnuchess.h b/apps/plugins/chessbox/gnuchess.h
index b7a3a309f8..f52e1b1a0a 100644
--- a/apps/plugins/chessbox/gnuchess.h
+++ b/apps/plugins/chessbox/gnuchess.h
@@ -1,7 +1,7 @@
1 1
2#ifndef _GNUCHESS_H_ 2#ifndef _GNUCHESS_H_
3#define _GNUCHESS_H_ 3#define _GNUCHESS_H_
4 4#define MAX_GAME_CNT 256
5#define neutral 2 5#define neutral 2
6#define white 0 6#define white 0
7#define black 1 7#define black 1
@@ -39,9 +39,10 @@ extern bool withbook;
39extern long Level; 39extern long Level;
40extern short TCflag,TCmoves,TCminutes; 40extern short TCflag,TCmoves,TCminutes;
41extern short timeout; 41extern short timeout;
42extern short GameCnt,Game50,castld[2],kingmoved[2],OperatorTime; 42extern unsigned char GameCnt; /* Bug fix rolls over at 255 instead of overflow */
43extern short Game50,castld[2],kingmoved[2],OperatorTime;
43extern struct TimeControlRec TimeControl; 44extern struct TimeControlRec TimeControl;
44extern struct GameRec GameList[240]; 45extern struct GameRec GameList[MAX_GAME_CNT];
45 46
46/* ---- The beginning of a GNUChess v2 APIfication ---- */ 47/* ---- The beginning of a GNUChess v2 APIfication ---- */
47void SetTimeControl(void); 48void SetTimeControl(void);