From 52eb4c470932937a175223136bf6d1e59a597528 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 8 Jan 2011 20:01:26 +0100 Subject: [PATCH] set an explicit artificial limit on the allowed time range this is the first building block in an attempt to protrect against time wraparound. The intention is not to be airtight, but practically effective. A really airtight solution would require writing our own SafeInt class --- src/lib/time/lumitime.cpp | 14 ++++++++++++-- src/lib/time/timevalue.hpp | 27 ++++++++++++++++++++++++++- src/tool/try.cpp | 2 +- wiki/renderengine.html | 6 +++++- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/lib/time/lumitime.cpp b/src/lib/time/lumitime.cpp index d2daba3c2..15444a60c 100644 --- a/src/lib/time/lumitime.cpp +++ b/src/lib/time/lumitime.cpp @@ -50,8 +50,9 @@ namespace time { } - const Time Time::MAX ( TimeValue (+std::numeric_limits::max()) ); - const Time Time::MIN ( TimeValue (-std::numeric_limits::max()) ); + /** @note the allowed time range is explicitly limited to help overflow protection */ + const Time Time::MAX ( TimeValue::buildRaw_(+std::numeric_limits::max() / 30) ); + const Time Time::MIN ( TimeValue::buildRaw_(-_raw(Time::MAX) ) ); /** convenience constructor to build an @@ -100,6 +101,15 @@ namespace time { } + /** @internal backdoor to sneak in a raw time value + * bypassing any normalisation and limiting */ + TimeValue + TimeValue::buildRaw_ (gavl_time_t raw) + { + return reinterpret_cast (raw); + } + + }} // namespace lib::Time diff --git a/src/lib/time/timevalue.hpp b/src/lib/time/timevalue.hpp index a19c806be..94b51d209 100644 --- a/src/lib/time/timevalue.hpp +++ b/src/lib/time/timevalue.hpp @@ -71,9 +71,13 @@ namespace time { } public: + /** explicit limit of allowed time range */ + static gavl_time_t limited (gavl_time_t raw); + + explicit TimeValue (gavl_time_t val=0) - : t_(val) + : t_(limited (val)) { } /** copy initialisation allowed */ @@ -83,6 +87,7 @@ namespace time { /** @internal to pass Time values to C functions */ friend gavl_time_t _raw (TimeValue const& time) { return time.t_; } + static TimeValue buildRaw_(gavl_time_t); // Supporting totally_ordered friend bool operator< (TimeValue const& t1, TimeValue const& t2) { return t1.t_ < t2.t_; } @@ -306,5 +311,25 @@ namespace time { }; + + + /* == implementations == */ + + /** @internal applies a limiter on the provided + * raw time value to keep it within the arbitrary + * boundaries defined by (Time::MAX, Time::MIN). + * While Time entities are \c not a "safeInt" + * implementation, we limit new values and + * establish this safety margin to prevent + * wrap-around during time quantisation */ + inline gavl_time_t + TimeValue::limited (gavl_time_t raw) + { + return raw > Time::MAX? Time::MAX.t_ + : raw < Time::MIN? Time::MIN.t_ + : raw; + } + + }} // lib::time #endif diff --git a/src/tool/try.cpp b/src/tool/try.cpp index 16716ccae..ef05aaa97 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -60,7 +60,7 @@ main (int, char**) int64_t muks = std::numeric_limits::max(); - muks -= 5; + muks /= 30; double murks(muks); cout << format("%f // %f || %g \n") % muks % murks % std::numeric_limits::epsilon(); diff --git a/wiki/renderengine.html b/wiki/renderengine.html index ed5b6a57c..550b53eaa 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -4192,7 +4192,7 @@ Viewed as a micro program, the processing patterns are ''weak typed'' &mdash
a given Render Engine configuration is a list of Processors. Each Processor in turn contains a Graph of ProcNode.s to do the acutal data processing. In order to cary out any calculations, the Processor needs to be called with a StateProxy containing the state information for this RenderProcess
 
-
+
The Quantiser implementation works by determining the grid interval containing a given raw time.
 These grid intervals are denoted by ordinal numbers (frame numbers), with interval #0 starting at the grid's origin and negative ordinals allowed.
 
@@ -4241,6 +4241,10 @@ There is an existing [[SafeInt class by David LeBlanc|http://safeint.codeplex.co
 ;ignore the problem
 :again, because of the huge time range, the problem could generally be deemed irrelevant
 :we could apply a limiter to enforce a reduced time range just in the quantisation and evaluation of timecodes
+
+A combination of the last approaches seems to be most appropriate here:
+Limit the officially allowed time range and perform simple checks when quantising a time value and when applying a scale factor.
+We limit {{{Time::MAX}}} by factor 1/30 and define the minimum //symmetrically to this.// This still leaves us with ''±9700 years allowed timerange''.