From 7c0679ad61d7787dc3a3326551acbdf6658db0b0 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Thu, 7 Jan 2010 11:59:32 +0100 Subject: [PATCH] Fix 'position ..... moves ' parsing bug If after 'moves' there is a space then we crash. The problem is that operator>>() trims whitespaces so that after 'moves' has been extract we are still not at eof() but remaining string contains only spaces. So that the next extarction operation uip >> token ends up with unchanged token value that remains 'moves', this garbage value is then feeded to RootPosition.do_move() through move_from_string() that does not detect the invalid move value leading to a crash. This bug is triggered by Shredder 12 interface under Mac that puts a space after 'moves' without any actual move list. Bug fixed by Justin Blanchard After reviewing UCI parsing code I spotted other possible weak points due to the fact that we don't test if the last extract operation has been succesful. So I have extended Justing patch to fix the remaining possible holes in uci.cpp No functional change. Signed-off-by: Marco Costalba --- src/uci.cpp | 46 +++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/src/uci.cpp b/src/uci.cpp index c4c1a037..f7ba2067 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -107,7 +107,8 @@ namespace { UCIInputParser uip(command); string token; - uip >> token; // operator>>() skips any whitespace + if (!(uip >> token)) // operator>>() skips any whitespace + return true; if (token == "quit") return false; @@ -159,14 +160,8 @@ namespace { else if (token == "perft") perft(uip); else - { cout << "Unknown command: " << command << endl; - while (!uip.eof()) - { - uip >> token; - cout << token << endl; - } - } + return true; } @@ -181,33 +176,33 @@ namespace { string token; - uip >> token; // operator>>() skips any whitespace + if (!(uip >> token)) // operator>>() skips any whitespace + return; if (token == "startpos") RootPosition.from_fen(StartPosition); else if (token == "fen") { string fen; - while (token != "moves" && !uip.eof()) + while (uip >> token && token != "moves") { - uip >> token; fen += token; fen += ' '; } RootPosition.from_fen(fen); } - if (!uip.eof()) + if (uip.good()) { if (token != "moves") uip >> token; + if (token == "moves") { Move move; StateInfo st; - while (!uip.eof()) + while (uip >> token) { - uip >> token; move = move_from_string(RootPosition, token); RootPosition.do_move(move, st); if (RootPosition.rule_50_counter() == 0) @@ -231,18 +226,14 @@ namespace { string token, name; - uip >> token; - if (token == "name") - { - uip >> name; - while (!uip.eof()) - { - uip >> token; - if (token == "value") - break; + if (!(uip >> token)) // operator>>() skips any whitespace + return; + if (token == "name" && uip >> name) + { + while (uip >> token && token != "value") name += (" " + token); - } + if (token == "value") { // Reads until end of line and left trim white space @@ -276,10 +267,8 @@ namespace { searchMoves[0] = MOVE_NONE; - while (!uip.eof()) + while (uip >> token) { - uip >> token; - if (token == "infinite") infinite = true; else if (token == "ponder") @@ -327,10 +316,9 @@ namespace { int depth, tm, n; Position pos = RootPosition; - if (uip.eof()) + if (!(uip >> depth)) return; - uip >> depth; tm = get_system_time(); n = perft(pos, depth * OnePly); -- 2.39.2