Skip to content

Commit

Permalink
Fix issue with Timestamp overflow
Browse files Browse the repository at this point in the history
Fix #140
  • Loading branch information
h4tr3d committed Jan 12, 2025
1 parent 68a21be commit f984467
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
10 changes: 4 additions & 6 deletions src/timestamp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,12 @@ Timestamp::operator bool() const noexcept

Timestamp operator+(const Timestamp &left, const Timestamp &right) noexcept
{
// Use more good precision
if (left.timebase() < right.timebase()) {
auto ts = av_add_stable(left.timebase(), left.timestamp(),
right.timebase(), right.timestamp());
// av_add_stable() required that rhs value less than lhs
if (left >= right) {
auto const ts = av_add_stable(left.timebase(), left.timestamp(), right.timebase(), right.timestamp());
return {ts, left.timebase()};
} else {
auto ts = av_add_stable(right.timebase(), right.timestamp(),
left.timebase(), left.timestamp());
auto ts = av_add_stable(right.timebase(), right.timestamp(), left.timebase(), left.timestamp());
return {ts, right.timebase()};
}
}
Expand Down
3 changes: 2 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ add_executable(test_executor
AvDeleter.cpp
Packet.cpp
Format.cpp
Rational.cpp)
Rational.cpp
Timestamp.cpp)
target_link_libraries(test_executor PUBLIC Catch2::Catch2 test_main avcpp::avcpp)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../catch2/contrib")
Expand Down
57 changes: 57 additions & 0 deletions tests/Timestamp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <catch2/catch.hpp>

#include <vector>

#include "rational.h"
#include "timestamp.h"

#ifdef _MSC_VER
# pragma warning(disable : 4702) // Disable warning: unreachable code
#endif


using namespace std;

TEST_CASE("Core", "[Overflow]")
{
SECTION("Overflow operator+(a,b)")
{
{
auto const tsLimit = std::numeric_limits<int64_t>::max() / 48000;

av::Timestamp t {
tsLimit, av::Rational {1, 48000}
};
av::Timestamp inc {48000, t.timebase()}; // 1s

auto v1 = t;
v1 += inc;

auto v2 = t + inc;
auto v3 = inc + t;

CHECK(v1 == v2);
CHECK(v1 == v3);
}

#if 0
av::Timestamp t1(48000, av::Rational {1, 48000}); // 1s
av::Timestamp t2 = t1;
av::Timestamp t3 = t1;
for (int64_t i = 0; i < 4194258; ++i) {
t1 = t1 + av::Timestamp {1024, t1.timebase()}; // fail case
t2 += av::Timestamp {1024, t2.timebase()}; // good
t3 = av::Timestamp {1024, t1.timebase()} + t3;

CHECK(t3 == t2);
CHECK(t1 == t2);
CHECK(t1.seconds() >= 1.0);

if (t1 != t2 || t2 != t3 || t1.seconds() < 1.0) {
CHECK(i < 0); // always fail, just for report
break;
}
}
#endif
}
}

0 comments on commit f984467

Please sign in to comment.