diff options
author | William Wilgus <me.theuser@yahoo.com> | 2017-01-31 04:28:02 +0100 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2017-02-01 01:33:48 +0100 |
commit | 1fa7c5635184e3a8c16b696a658c027fcc0862d8 (patch) | |
tree | debeb03ca2da9a20ccfae5ece4fc512847046014 /apps/plugins/chessbox/chessbox_pgn.c | |
parent | 37522ec63ae8fd2f88a66ed3d7020ebe95e9980e (diff) | |
download | rockbox-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/plugins/chessbox/chessbox_pgn.c')
-rw-r--r-- | apps/plugins/chessbox/chessbox_pgn.c | 70 |
1 files changed, 47 insertions, 23 deletions
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 | ||
162 | static void pgn_to_coords(struct pgn_ply_node* ply){ | 162 | static 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 | ||
357 | static void coords_to_pgn(struct pgn_ply_node* ply){ | 368 | static 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 | ||