gnucash master: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Sat Jan 14 14:57:46 EST 2017


Updated	 via  https://github.com/Gnucash/gnucash/commit/88cb24ca (commit)
	 via  https://github.com/Gnucash/gnucash/commit/43a8db25 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3925106e (commit)
	from  https://github.com/Gnucash/gnucash/commit/c1e38d5a (commit)



commit 88cb24caa70c5ccb50cc2b8658c34f92c575d0a0
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Jan 14 11:51:52 2017 -0800

    Ensure that all GncDate and GncDateTime constructors are in try blocks.
    
    To prevent leaking exceptions to C code.

diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 82a3180..066a34a 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -46,6 +46,8 @@ extern "C"
 #endif
 }
 
+#include <cinttypes>
+
 #include "gnc-date.h"
 #include "gnc-date-p.h"
 #include "gnc-datetime.hpp"
@@ -344,13 +346,26 @@ gnc_date_string_to_monthformat(const char *fmt_str, GNCDateMonthFormat *format)
 char*
 gnc_print_time64(time64 time, const char* format)
 {
-    GncDateTime gncdt(time);
-    auto sstr = gncdt.format(format);
-    //ugly C allocation so that the ptr can be freed at the other end
-    char* cstr = static_cast<char*>(malloc(sstr.length() + 1));
-    memset(cstr, 0, sstr.length() + 1);
-    strncpy(cstr, sstr.c_str(), sstr.length());
-    return cstr;
+    try
+    {
+        GncDateTime gncdt(time);
+        auto sstr = gncdt.format(format);
+        //ugly C allocation so that the ptr can be freed at the other end
+        char* cstr = static_cast<char*>(malloc(sstr.length() + 1));
+        memset(cstr, 0, sstr.length() + 1);
+        strncpy(cstr, sstr.c_str(), sstr.length());
+        return cstr;
+    }
+    catch(std::runtime_error& err)
+    {
+        PWARN("Error processing time64 %" PRId64 ": %s", time, err.what());
+        return nullptr;
+    }
+    catch(std::logic_error& err)
+    {
+        PWARN("Error processing time64 %" PRId64 ": %s", time, err.what());
+        return nullptr;
+    }
 }
 
 /********************************************************************\
@@ -602,12 +617,24 @@ size_t
 qof_print_date_dmy_buff (char * buff, size_t len, int day, int month, int year)
 {
     if (!buff) return 0;
-
-    GncDate date(year, month, day);
-    std::string str = date.format(qof_date_format_get_string(dateFormat));
-    strncpy(buff, str.c_str(), len);
-    if (str.length() >= len)
-	buff[len - 1] = '\0';
+    try
+    {
+        GncDate date(year, month, day);
+        std::string str = date.format(qof_date_format_get_string(dateFormat));
+        strncpy(buff, str.c_str(), len);
+        if (str.length() >= len)
+            buff[len - 1] = '\0';
+    }
+    catch(std::logic_error& err)
+    {
+        PWARN("Error processing year-month-day %d-%d-%d: %s",
+              year, month, day, err.what());
+    }
+    catch(std::runtime_error& err)
+    {
+        PWARN("Error processing year-month-day %d-%d-%d: %s",
+              year, month, day, err.what());
+    }
     return strlen(buff);
 }
 
@@ -616,11 +643,22 @@ qof_print_date_buff (char * buff, size_t len, time64 t)
 {
     if (!buff) return 0;
 
-    GncDateTime gncdt(t);
-    std::string str = gncdt.format(qof_date_format_get_string(dateFormat));
-    strncpy(buff, str.c_str(), len);
-    if (str.length() >= len)
-	buff[len - 1] = '\0';
+    try
+    {
+        GncDateTime gncdt(t);
+        std::string str = gncdt.format(qof_date_format_get_string(dateFormat));
+        strncpy(buff, str.c_str(), len);
+        if (str.length() >= len)
+            buff[len - 1] = '\0';
+    }
+    catch(std::logic_error& err)
+    {
+        PWARN("Error processing time64 %" PRId64 ": %s", t, err.what());
+    }
+    catch(std::runtime_error& err)
+    {
+        PWARN("Error processing time64 %" PRId64 ": %s", t, err.what());
+    }
     return strlen(buff);
 }
 
@@ -1158,8 +1196,14 @@ gnc_iso8601_to_timespec_gmt(const char *cstr)
         GncDateTime gncdt(cstr);
         return {static_cast<time64>(gncdt), 0};
     }
-    catch(...)
+    catch(std::logic_error& err)
     {
+        PWARN("Error processing %s: %s", cstr, err.what());
+        return {0, 0};
+    }
+    catch(std::runtime_error& err)
+    {
+        PWARN("Error processing time64 %s: %s", cstr, err.what());
         return {0, 0};
     }
 }
@@ -1174,13 +1218,26 @@ gnc_timespec_to_iso8601_buff (Timespec ts, char * buff)
     const char* format = "%Y-%m-%d %H:%M:%s %q";
 
     if (! buff) return NULL;
+    try
+    {
+        GncDateTime gncdt(ts.tv_sec);
+        auto sstr = gncdt.format(format);
 
-    GncDateTime gncdt(ts.tv_sec);
-    auto sstr = gncdt.format(format);
+        memset(buff, 0, sstr.length() + 1);
+        strncpy(buff, sstr.c_str(), sstr.length());
+        return buff + sstr.length();
+    }
+    catch(std::logic_error& err)
+    {
+        PWARN("Error processing time64 %" PRId64 ": %s", ts.tv_sec, err.what());
+        return buff;
+    }
+    catch(std::runtime_error& err)
+    {
+        PWARN("Error processing time64 %" PRId64 ": %s", ts.tv_sec, err.what());
+        return buff;
+    }
 
-    memset(buff, 0, sstr.length() + 1);
-    strncpy(buff, sstr.c_str(), sstr.length());
-    return buff + sstr.length();
 }
 
 void

commit 43a8db25ac41255dcac6a8782c97445e46a225c4
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Jan 14 11:49:48 2017 -0800

    Make GncDate and GncDateTime default constructors have the current day/time.
    
    Like documented, and instead of the epoch day/time like the underlying boost
    implementation.

diff --git a/src/libqof/qof/gnc-date.cpp b/src/libqof/qof/gnc-date.cpp
index 4d21ef7..82a3180 100644
--- a/src/libqof/qof/gnc-date.cpp
+++ b/src/libqof/qof/gnc-date.cpp
@@ -237,7 +237,6 @@ time64
 gnc_time (time64 *tbuf)
 {
     GncDateTime gncdt;
-    gncdt.now();
     auto time = static_cast<time64>(gncdt);
     if (tbuf != NULL)
         *tbuf = time;
@@ -1316,7 +1315,6 @@ GDate timespec_to_gdate (Timespec ts)
 GDate* gnc_g_date_new_today ()
 {
     GncDate gncd;
-    gncd.today();
     auto ymd = gncd.year_month_day();
     auto month = static_cast<GDateMonth>(ymd.month);
     auto result = g_date_new_dmy (ymd.day, month, ymd.year);
diff --git a/src/libqof/qof/gnc-datetime.cpp b/src/libqof/qof/gnc-datetime.cpp
index ab3803c..25d16a9 100644
--- a/src/libqof/qof/gnc-datetime.cpp
+++ b/src/libqof/qof/gnc-datetime.cpp
@@ -63,7 +63,7 @@ static constexpr auto ticks_per_second = INT64_C(1000000000);
 class GncDateImpl
 {
 public:
-    GncDateImpl(): m_greg(unix_epoch.date()) {}
+    GncDateImpl(): m_greg(boost::gregorian::day_clock::local_day()) {}
     GncDateImpl(const int year, const int month, const int day) :
         m_greg(year, static_cast<Month>(month), day) {}
     GncDateImpl(Date d) : m_greg(d) {}
@@ -134,7 +134,7 @@ LDT_from_struct_tm(const struct tm tm)
 class GncDateTimeImpl
 {
 public:
-    GncDateTimeImpl() : m_time(unix_epoch, tzp.get(unix_epoch.date().year())) {}
+    GncDateTimeImpl() : m_time(boost::local_time::local_sec_clock::local_time(tzp.get(boost::gregorian::day_clock::local_day().year()))) {}
     GncDateTimeImpl(const time64 time) : m_time(LDT_from_unix_local(time)) {}
     GncDateTimeImpl(const struct tm tm) : m_time(LDT_from_struct_tm(tm)) {}
     GncDateTimeImpl(const std::string str);
diff --git a/src/libqof/qof/test/gtest-gnc-datetime.cpp b/src/libqof/qof/test/gtest-gnc-datetime.cpp
index 6d378a8..7bba79a 100644
--- a/src/libqof/qof/test/gtest-gnc-datetime.cpp
+++ b/src/libqof/qof/test/gtest-gnc-datetime.cpp
@@ -40,7 +40,8 @@ TEST(gnc_date_constructors, test_ymd_constructor)
 TEST(gnc_datetime_constructors, test_default_constructor)
 {
     GncDateTime atime;
-    EXPECT_EQ(static_cast<time64>(atime), static_cast<time64>(INT64_C(0)));
+    long time_now = time(nullptr);
+    EXPECT_EQ(static_cast<time64>(atime), static_cast<time64>(time_now));
 }
 
 TEST(gnc_datetime_constructors, test_time64_constructor)

commit 3925106e706c680880f2133293b923d53b0ea648
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Jan 14 11:48:18 2017 -0800

    Fix crash when $TZ isn’t defined.

diff --git a/src/libqof/qof/gnc-timezone.cpp b/src/libqof/qof/gnc-timezone.cpp
index 3a8e14b..4a8ecff 100644
--- a/src/libqof/qof/gnc-timezone.cpp
+++ b/src/libqof/qof/gnc-timezone.cpp
@@ -666,7 +666,8 @@ TimeZoneProvider::parse_file(const std::string& tzname)
         zone_vector.push_back(zone_from_rule(max_year, last_rule));
 }
 
-TimeZoneProvider::TimeZoneProvider(const std::string& tzname) :  zone_vector {}
+bool
+TimeZoneProvider::construct(const std::string& tzname)
 {
     try
     {
@@ -679,29 +680,33 @@ TimeZoneProvider::TimeZoneProvider(const std::string& tzname) :  zone_vector {}
             TZ_Ptr zone(new PTZ(tzname));
             zone_vector.push_back(std::make_pair(max_year, zone));
         }
-        catch(const std::exception& err)
+        catch(std::exception& err)
         {
-            try
-            {
-                parse_file(getenv("TZ"));
-            }
-            catch(const std::exception& err)
-            {
-
-                std::cerr << "Unable to use either provided tzname or TZ environment variable. Resorting to /etc/localtime.\n";
-                try
-                {
-                    parse_file("/etc/localtime");
-                }
-                catch(const std::invalid_argument& env)
-                {
-                    std::cerr << "/etc/localtime invalid, resorting to GMT.";
-                    TZ_Ptr zone(new PTZ("UTC0"));
-                    zone_vector.push_back(std::make_pair(max_year, zone));
-                }
-            }
+            return false;
         }
     }
+    return true;
+}
+
+TimeZoneProvider::TimeZoneProvider(const std::string& tzname) :  zone_vector {}
+{
+    if(construct(tzname))
+        return;
+    std::cerr << tzname << " invalid, trying TZ environment variable.\n";
+    const char* tz_env = getenv("TZ");
+    if(tz_env && construct(tz_env))
+        return;
+    std::cerr << "No valid $TZ, resorting to /etc/localtime.\n";
+    try
+    {
+        parse_file("/etc/localtime");
+    }
+    catch(const std::invalid_argument& env)
+    {
+        std::cerr << "/etc/localtime invalid, resorting to GMT.";
+        TZ_Ptr zone(new PTZ("UTC0"));
+        zone_vector.push_back(std::make_pair(max_year, zone));
+    }
 }
 #endif
 
diff --git a/src/libqof/qof/gnc-timezone.hpp b/src/libqof/qof/gnc-timezone.hpp
index 546bbf3..9bb0ead 100644
--- a/src/libqof/qof/gnc-timezone.hpp
+++ b/src/libqof/qof/gnc-timezone.hpp
@@ -59,6 +59,7 @@ public:
     static const unsigned int max_year; //9999
 private:
     void parse_file(const std::string& tzname);
+    bool construct(const std::string& tzname);
     TZ_Vector zone_vector;
 #if PLATFORM(WINDOWS)
     void load_windows_dynamic_tz(HKEY, time_zone_names);



Summary of changes:
 src/libqof/qof/gnc-date.cpp                | 107 ++++++++++++++++++++++-------
 src/libqof/qof/gnc-datetime.cpp            |   4 +-
 src/libqof/qof/gnc-timezone.cpp            |  47 +++++++------
 src/libqof/qof/gnc-timezone.hpp            |   1 +
 src/libqof/qof/test/gtest-gnc-datetime.cpp |   3 +-
 5 files changed, 112 insertions(+), 50 deletions(-)



More information about the gnucash-changes mailing list