From fe188957a9897fc9b4297249261fdd02294959b1 Mon Sep 17 00:00:00 2001 From: Fulvio Date: Wed, 1 Feb 2023 17:49:48 +0100 Subject: [PATCH] Report invalid dates when parsing PGNs. --- src/date.h | 11 ++++------- src/pgnparse.h | 43 ++++++++++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/date.h b/src/date.h index cf3a608c..5bc45b4e 100644 --- a/src/date.h +++ b/src/date.h @@ -75,13 +75,10 @@ date_GetDay (dateT date) return (uint32_t) (date & 31); } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//### date_GetMonthDay(): -// Get the month and day; used to check for year-only dates. S.A -inline uint32_t -date_GetMonthDay (dateT date) -{ - return (uint32_t) (date & 511); +// Return true if the date does not include the year, the month or the day. +inline bool date_isPartial(dateT date) { + return date_GetYear(date) == 0 || date_GetMonth(date) == 0 || + date_GetDay(date) == 0; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/pgnparse.h b/src/pgnparse.h index d470bcad..168f8641 100644 --- a/src/pgnparse.h +++ b/src/pgnparse.h @@ -27,6 +27,7 @@ #include "game.h" #include "pgn_lexer.h" #include +#include #include /** @@ -160,12 +161,28 @@ class PgnVisitor { if (tagLen == 0 || tagLen + valueLen > 240 || !parseTagPair(tag.first, tagLen, value)) // Failure { - std::string err(tag.first, tag.second); - err.append(" \""); - err.append(value.first, value.second); - err.push_back('"'); - logErr("Error parsing the tag pair: ", - {err.c_str(), err.c_str() + err.size()}); + const auto tag_sv = std::string_view(tag.first, tagLen); + const auto value_sv = std::string_view(value.first, valueLen); + std::string tag_parsed; + std::string value_parsed; + game.viewTagPairs([&](auto game_tag, auto game_value) { + if (tag_sv == game_tag) { + tag_parsed = game_tag; + value_parsed = game_value; + } + }); + if (tag_sv != tag_parsed || value_sv != value_parsed) { + std::string err(tag_sv); + err.append(" \""); + err.append(value_sv); + err.append("\" ==> "); + err.append(tag_parsed); + err.append(" \""); + err.append(value_parsed); + err.push_back('"'); + logWarning("Error parsing the tag pair: ", + {err.c_str(), err.c_str() + err.size()}); + } } return true; } @@ -268,8 +285,9 @@ class PgnVisitor { break; case 4: if (std::equal(tag, tag + 4, "Date")) { - game.SetDate(date_parsePGNTag(value)); - return true; + const auto date = date_parsePGNTag(value); + game.SetDate(date); + return !date_isPartial(date); } break; case 6: @@ -280,13 +298,16 @@ class PgnVisitor { if (std::equal(tag, tag + 7, "UTCDate") && game.GetDate() == ZERO_DATE) { // Add two tags: "UTCDate" and the standard "Date". - game.SetDate(date_parsePGNTag(value)); + const auto date = date_parsePGNTag(value); + if (!date_isPartial(date)) + game.SetDate(date); } break; case 9: if (std::equal(tag, tag + 9, "EventDate")) { - game.SetEventDate(date_parsePGNTag(value)); - return true; + const auto date = date_parsePGNTag(value); + game.SetEventDate(date); + return !date_isPartial(date); } if (std::equal(tag, tag + 9, "ScidFlags")) { game.SetScidFlags(value.first,