]> git.sesse.net Git - stockfish/commitdiff
Fix 'position ..... moves ' parsing bug
authorMarco Costalba <mcostalba@gmail.com>
Thu, 7 Jan 2010 10:59:32 +0000 (11:59 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Thu, 7 Jan 2010 10:59:32 +0000 (11:59 +0100)
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 <mcostalba@gmail.com>
src/uci.cpp

index c4c1a03705924516558ac8c5651b7bd63bc13bf5..f7ba2067ee509dbb3c5e735b49fe731712152faf 100644 (file)
@@ -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);