Bug 795377 - Reads and saves Gnucash 2.6.19 XML file, then can't reread it, due to bad date in old file

This commit contains another round of cleanups in the
timespec to time64 conversion. There were a number of
false assumptions that time64 = 0 would be a bad date
in the xml parser. This commit corrects enough of them to
eliminate the bug. Further cleanup is probably advised but
can be done at a later stage.
This commit is contained in:
Geert Janssens 2018-04-28 12:16:52 +02:00
parent 9c4469d039
commit b761b5a0dc
5 changed files with 29 additions and 41 deletions

View File

@ -141,7 +141,7 @@ xmlNodePtr
time64_to_dom_tree (const char* tag, const time64 time)
{
xmlNodePtr ret;
g_return_val_if_fail (time, NULL);
g_return_val_if_fail (time != INT64_MAX, NULL);
auto date_str = time64_to_string (time);
if (!date_str)
return NULL;

View File

@ -526,7 +526,7 @@ dom_tree_to_gnc_numeric (xmlNodePtr node)
static time64
time_parse_failure ()
{
return 0;
return INT64_MAX;
}
@ -544,7 +544,7 @@ dom_tree_to_time64 (xmlNodePtr node)
undefined. The XML is valid if it has at least one of <s> or <ns>
and no more than one of each. Order is irrelevant. */
time64 ret {0};
time64 ret {INT64_MAX};
gboolean seen_s = FALSE;
gboolean seen_ns = FALSE;
xmlNodePtr n;
@ -865,9 +865,9 @@ dom_tree_generic_parse (xmlNodePtr node, struct dom_tree_handler* handlers,
gboolean
dom_tree_valid_time64 (time64 val, const xmlChar * name)
{
if (val)
if (val != INT64_MAX)
return TRUE;
g_warning ("Invalid timestamp in data file. Look for a '%s' entry "
"with a date of 1969-12-31 or 1970-01-01.", name);
"with a year outside of the valie range: 1400..10000", name);
return FALSE;
}

View File

@ -127,7 +127,7 @@ test_dom_tree_to_text (void)
static void
test_dom_tree_to_timespec (void)
test_dom_tree_to_time64 (void)
{
int i;
for (i = 0; i < 20; i++)
@ -146,11 +146,11 @@ test_dom_tree_to_timespec (void)
}
else if (test_spec1 == test_spec2)
{
success ("dom_tree_to_timespec");
success ("dom_tree_to_time64");
}
else
{
failure ("dom_tree_to_timespec");
failure ("dom_tree_to_time64");
printf ("Node looks like:\n");
xmlElemDump (stdout, NULL, test_node);
printf ("\n");
@ -266,7 +266,7 @@ main (int argc, char** argv)
fflush (stdout);
test_dom_tree_to_text ();
fflush (stdout);
test_dom_tree_to_timespec ();
test_dom_tree_to_time64 ();
fflush (stdout);
test_dom_tree_to_gnc_numeric ();
fflush (stdout);

View File

@ -1202,7 +1202,7 @@ time64
gnc_iso8601_to_time64_gmt(const char *cstr)
{
time64 time;
if (!cstr) return 0;
if (!cstr) return INT64_MAX;
try
{
GncDateTime gncdt(cstr);
@ -1211,12 +1211,12 @@ gnc_iso8601_to_time64_gmt(const char *cstr)
catch(std::logic_error& err)
{
PWARN("Error processing %s: %s", cstr, err.what());
return 0;
return INT64_MAX;
}
catch(std::runtime_error& err)
{
PWARN("Error processing time64 %s: %s", cstr, err.what());
return 0;
return INT64_MAX;
}
}

View File

@ -1633,40 +1633,28 @@ get_nanoseconds (GDateTime *gdt)
}
static void
test_gnc_iso8601_to_timespec_gmt (FixtureA *f, gconstpointer pData)
test_gnc_iso8601_to_time64_gmt (FixtureA *f, gconstpointer pData)
{
Timespec t = {gnc_iso8601_to_time64_gmt (NULL), 0};
g_assert_cmpint (t.tv_sec, ==, 0);
g_assert_cmpint (t.tv_nsec, ==, 0);
time64 t = gnc_iso8601_to_time64_gmt (NULL);
g_assert_cmpint (t, ==, INT64_MAX);
t.tv_sec = gnc_iso8601_to_time64_gmt ("");
g_assert_cmpint (t.tv_sec, ==, 0);
g_assert_cmpint (t.tv_nsec, ==, 0);
t = gnc_iso8601_to_time64_gmt ("");
g_assert_cmpint (t, ==, 0);
t.tv_sec = gnc_iso8601_to_time64_gmt ("1989-03-27 13:43:27");
g_assert_cmpint (t.tv_sec, ==, f->ts1.tv_sec);
/* MinGW has some precision issues in the last microsecond digit */
#ifdef G_OS_WIN32
g_assert_cmpint (t.tv_nsec - 2000, <=, f->ts1.tv_nsec);
g_assert_cmpint (t.tv_nsec + 2000, >=, f->ts1.tv_nsec);
#else
g_assert_cmpint (t.tv_nsec, ==, f->ts1.tv_nsec);
#endif
t.tv_sec = gnc_iso8601_to_time64_gmt ("2020-11-07 06:21:19 -05");
g_assert_cmpint (t.tv_sec, ==, f->ts2.tv_sec);
g_assert_cmpint (t.tv_nsec, ==, f->ts2.tv_nsec);
t = gnc_iso8601_to_time64_gmt ("1989-03-27 13:43:27");
g_assert_cmpint (t, ==, f->ts1.tv_sec);
t.tv_sec = gnc_iso8601_to_time64_gmt ("2012-07-04 19:27:44.0+08:40");
g_assert_cmpint (t.tv_sec, ==, f->ts3.tv_sec);
g_assert_cmpint (t.tv_nsec, ==, f->ts3.tv_nsec);
t = gnc_iso8601_to_time64_gmt ("2020-11-07 06:21:19 -05");
g_assert_cmpint (t, ==, f->ts2.tv_sec);
t.tv_sec = gnc_iso8601_to_time64_gmt ("1961-09-22 17:53:19 -05");
g_assert_cmpint (t.tv_sec, ==, f->ts4.tv_sec);
g_assert_cmpint (t.tv_nsec, ==, f->ts4.tv_nsec);
t = gnc_iso8601_to_time64_gmt ("2012-07-04 19:27:44.0+08:40");
g_assert_cmpint (t, ==, f->ts3.tv_sec);
t.tv_sec = gnc_iso8601_to_time64_gmt ("2061-01-25 23:21:19.0 -05:00");
g_assert_cmpint (t.tv_sec, ==, f->ts5.tv_sec);
g_assert_cmpint (t.tv_nsec, ==, f->ts5.tv_nsec);
t = gnc_iso8601_to_time64_gmt ("1961-09-22 17:53:19 -05");
g_assert_cmpint (t, ==, f->ts4.tv_sec);
t = gnc_iso8601_to_time64_gmt ("2061-01-25 23:21:19.0 -05:00");
g_assert_cmpint (t, ==, f->ts5.tv_sec);
}
/* gnc_timespec_to_iso8601_buff
char *
@ -2269,7 +2257,7 @@ test_suite_gnc_date (void)
// GNC_TEST_ADD_FUNC (suitename, "qof format time", test_qof_format_time);
// GNC_TEST_ADD_FUNC (suitename, "qof strftime", test_qof_strftime);
GNC_TEST_ADD_FUNC (suitename, "gnc_date_timestamp", test_gnc_date_timestamp);
GNC_TEST_ADD (suitename, "gnc iso8601 to timespec gmt", FixtureA, NULL, setup, test_gnc_iso8601_to_timespec_gmt, NULL);
GNC_TEST_ADD (suitename, "gnc iso8601 to time64 gmt", FixtureA, NULL, setup, test_gnc_iso8601_to_time64_gmt, NULL);
GNC_TEST_ADD (suitename, "gnc timespec to iso8601 buff", FixtureA, NULL, setup, test_gnc_timespec_to_iso8601_buff, NULL);
GNC_TEST_ADD (suitename, "gnc timespec2dmy", FixtureA, NULL, setup, test_gnc_timespec2dmy, NULL);
// GNC_TEST_ADD_FUNC (suitename, "gnc dmy2timespec internal", test_gnc_dmy2timespec_internal);