Bug 782144 - git-master - Save Corrupts Data File / Not Open Data File

After much thrashing this turned out to be caused by a date string
with a 3-digit year and that caused an unexpected boost::bad_cast
exception from boost::posix_time::time_from_string().

To prevent that and anything like it, pre-parse the string with
regular expressions to classify them and split out the timezone
if there is one. If neither (perhaps eventually none) of the
regexes match throw std::invalid_argument. The C function will
catch this and return 0.
This commit is contained in:
John Ralls 2018-04-08 17:37:39 -07:00
parent 89a1cfd24a
commit 7a0f0d57c8

View File

@ -282,19 +282,31 @@ GncDateTimeImpl::GncDateTimeImpl(std::string str) :
m_time(unix_epoch, utc_zone)
{
if (str.empty()) return;
auto tzpos = str.find_first_of("+-", str.find(":"));
auto tzptr = tz_from_string(tzpos != str.npos ? str.substr(tzpos) : "");
if (tzpos != str.npos && str[tzpos - 1] == ' ') --tzpos;
TZ_Ptr tzptr;
try
{
bool delimited = str.find("-") == 4;
if (!delimited)
str.insert(8, "T");
auto pdt = delimited ?
boost::posix_time::time_from_string(str.substr(0, tzpos)) :
boost::posix_time::from_iso_string(str.substr(0,tzpos));
static const boost::regex delim_iso("^(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(?:\\.\\d{0,9})?)\\s*([+-]\\d{2}(?::?\\d{2})?)?$");
static const boost::regex non_delim("^(\\d{14}(?:\\.\\d{0,9})?)\\s*([+-]\\d{2}\\s*(:?\\d{2})?)?$");
PTime pdt;
boost::smatch sm;
if (regex_match(str, sm, non_delim))
{
std::string time_str(sm[1]);
time_str.insert(8, "T");
pdt = boost::posix_time::from_iso_string(time_str);
}
else if (regex_match(str, sm, delim_iso))
{
pdt = boost::posix_time::time_from_string(sm[1]);
}
else
{
throw(std::invalid_argument("The date string was not formatted in a way that GncDateTime(std::string) knows how to parse."));
}
std::string tzstr("");
if (sm[2].matched)
tzstr += sm[2];
tzptr = tz_from_string(tzstr);
m_time = LDT(pdt.date(), pdt.time_of_day(), tzptr,
LDTBase::NOT_DATE_TIME_ON_ERROR);
}