Check tablebase files
authorJoost VandeVondele <Joost.VandeVondele@gmail.com>
Thu, 3 Jan 2019 22:56:11 +0000 (23:56 +0100)
committerSt├ęphane Nicolet <stephanenicoletsuriphone@gmail.com>
Fri, 4 Jan 2019 14:36:39 +0000 (15:36 +0100)
This addresses partially issue #1911 in that it documents in our
Readme the command that users can use to verifying the md5sum of
their downloaded tablebase files.

Additionally, a quick check of the file size (the size of each
tablebase file modulo 64 is 16 as pointed out by @syzygy1) has been
implemented at launch time in Stockfish.

Closes https://github.com/official-stockfish/Stockfish/pull/1927
and https://github.com/official-stockfish/Stockfish/issues/1911

No functional change.

Readme.md
src/syzygy/tbprobe.cpp

index a68ef560b99f25a05bdca551eee76c6b2a896bc7..bc058dbc911e05139302e4214a8a15a5f0e6a409 100644 (file)
--- a/Readme.md
+++ b/Readme.md
@@ -86,7 +86,9 @@ Currently, Stockfish has the following UCI options:
     Example: `C:\tablebases\wdl345;C:\tablebases\wdl6;D:\tablebases\dtz345;D:\tablebases\dtz6`
     
     It is recommended to store .rtbw files on an SSD. There is no loss in storing 
-    the .rtbz files on a regular HD.
+    the .rtbz files on a regular HD. It is recommended to verify all md5 checksums
+    of the downloaded tablebase files (`md5sum -c checksum.md5`) as corruption will
+    lead to engine crashes.
 
   * #### SyzygyProbeDepth
     Minimum remaining search depth for which a position is probed. Set this option
index 57c7d872e1b496a104774582de1a07838b4587af..bf6ed4218a63e08d094f81afb1d4ec894616dffc 100644 (file)
@@ -214,14 +214,22 @@ public:
             return *baseAddress = nullptr, nullptr;
 
         fstat(fd, &statbuf);
+
+        if (statbuf.st_size % 64 != 16)
+        {
+            std::cerr << "Corrupt tablebase file " << fname << std::endl;
+            exit(EXIT_FAILURE);
+        }
+
         *mapping = statbuf.st_size;
         *baseAddress = mmap(nullptr, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
         madvise(*baseAddress, statbuf.st_size, MADV_RANDOM);
         ::close(fd);
 
-        if (*baseAddress == MAP_FAILED) {
+        if (*baseAddress == MAP_FAILED)
+        {
             std::cerr << "Could not mmap() " << fname << std::endl;
-            exit(1);
+            exit(EXIT_FAILURE);
         }
 #else
         // Note FILE_FLAG_RANDOM_ACCESS is only a hint to Windows and as such may get ignored.
@@ -233,21 +241,30 @@ public:
 
         DWORD size_high;
         DWORD size_low = GetFileSize(fd, &size_high);
+
+        if (size_low % 64 != 16)
+        {
+            std::cerr << "Corrupt tablebase file " << fname << std::endl;
+            exit(EXIT_FAILURE);
+        }
+
         HANDLE mmap = CreateFileMapping(fd, nullptr, PAGE_READONLY, size_high, size_low, nullptr);
         CloseHandle(fd);
 
-        if (!mmap) {
+        if (!mmap)
+        {
             std::cerr << "CreateFileMapping() failed" << std::endl;
-            exit(1);
+            exit(EXIT_FAILURE);
         }
 
         *mapping = (uint64_t)mmap;
         *baseAddress = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0);
 
-        if (!*baseAddress) {
+        if (!*baseAddress)
+        {
             std::cerr << "MapViewOfFile() failed, name = " << fname
                       << ", error = " << GetLastError() << std::endl;
-            exit(1);
+            exit(EXIT_FAILURE);
         }
 #endif
         uint8_t* data = (uint8_t*)*baseAddress;
@@ -255,7 +272,8 @@ public:
         constexpr uint8_t Magics[][4] = { { 0xD7, 0x66, 0x0C, 0xA5 },
                                           { 0x71, 0xE8, 0x23, 0x5D } };
 
-        if (memcmp(data, Magics[type == WDL], 4)) {
+        if (memcmp(data, Magics[type == WDL], 4))
+        {
             std::cerr << "Corrupted table in file " << fname << std::endl;
             unmap(*baseAddress, *mapping);
             return *baseAddress = nullptr, nullptr;
@@ -416,7 +434,7 @@ class TBTables {
             }
         }
         std::cerr << "TB hash table size too low!" << std::endl;
-        exit(1);
+        exit(EXIT_FAILURE);
     }
 
 public: