From: Scott Worley Date: Thu, 31 Dec 2015 08:22:27 +0000 (-0800) Subject: Input validation X-Git-Url: http://git.scottworley.com/slidingtile/commitdiff_plain/b18667f24728cb960b0c60fa55824062582278bf?ds=inline Input validation --- diff --git a/sliding_tile_lib.cc b/sliding_tile_lib.cc index 24642f1..3b7806b 100644 --- a/sliding_tile_lib.cc +++ b/sliding_tile_lib.cc @@ -21,6 +21,29 @@ signed char adjacent[BOARD_SIZE][5] = { 11, 14, -1, -1, -1, }; +bool Board::is_valid() { + bool seen[BOARD_SIZE]; + for (int i = 0; i < BOARD_SIZE; i++) { + seen[i] = false; + } + + for (int i = 0; i < BOARD_SIZE; i++) { + if (board[i] < 0 || board[i] >= BOARD_SIZE || seen[board[i]]) { + return false; + } + seen[board[i]] = true; + } + + // Redundant because pigeon-hole-principle, but check anyway + for (int i = 0; i < BOARD_SIZE; i++) { + if (!seen[i]) { + return false; + } + } + + return true; +} + std::istream& operator>>(std::istream& is, Board& board) { for (int i = 0; i < BOARD_SIZE; i++) { if (!is.good()) { @@ -35,5 +58,8 @@ std::istream& operator>>(std::istream& is, Board& board) { is >> numeric; board.board[i] = numeric; } + if (!board.is_valid()) { + is.setstate(std::istream::failbit); + } return is; } diff --git a/sliding_tile_lib.h b/sliding_tile_lib.h index 1ffe6fa..89c65c1 100644 --- a/sliding_tile_lib.h +++ b/sliding_tile_lib.h @@ -8,6 +8,7 @@ const int BOARD_SIZE = BOARD_DIM * BOARD_DIM; struct Board { signed char board[BOARD_SIZE]; + bool is_valid(); }; std::istream& operator>>(std::istream& is, Board& board); diff --git a/sliding_tile_lib_test.cc b/sliding_tile_lib_test.cc index a0a6b52..7f032a4 100644 --- a/sliding_tile_lib_test.cc +++ b/sliding_tile_lib_test.cc @@ -55,3 +55,24 @@ TEST(Board, NonNumericInput) { is >> b; EXPECT_TRUE(is.fail()); } + +TEST(Board, RepeatedTileInput) { + std::istringstream is{"15,15,9,13,3,1,12,8,0,11,6,4,7,5,2,10"}; + Board b; + is >> b; + EXPECT_TRUE(is.fail()); +} + +TEST(Board, LowTileInput) { + std::istringstream is{"-1,14,9,13,3,1,12,8,0,11,6,4,7,5,2,10"}; + Board b; + is >> b; + EXPECT_TRUE(is.fail()); +} + +TEST(Board, HighTileInput) { + std::istringstream is{"16,14,9,13,3,1,12,8,0,11,6,4,7,5,2,10"}; + Board b; + is >> b; + EXPECT_TRUE(is.fail()); +}