diff --git a/src/tags_int.cpp b/src/tags_int.cpp index f9a3ea28..2b21de04 100644 --- a/src/tags_int.cpp +++ b/src/tags_int.cpp @@ -2768,15 +2768,18 @@ namespace Exiv2 { } std::ostringstream oss; oss.copyfmt(os); - const float sec = 3600 * value.toFloat(0) - + 60 * value.toFloat(1) - + value.toFloat(2); + const double t = 3600 * value.toFloat(0) + + 60 * value.toFloat(1) + + value.toFloat(2); + enforce(std::isfinite(t), "Non-finite time value"); int p = 0; - if (sec != static_cast(sec)) p = 1; - - const int hh = static_cast(sec / 3600); - const int mm = static_cast((sec - 3600 * hh) / 60); - const float ss = sec - 3600 * hh - 60 * mm; + const double fraction = std::fmod(t,1); + if (fraction != 0) p = 1; + const double ss = std::fmod(t, 60); + const double minutes = (t - ss)/60; + const int mm = static_cast(std::fmod(minutes, 60)); + const double hours = (minutes - mm)/60; + const int hh = static_cast(std::fmod(hours, 24)); os << std::setw(2) << std::setfill('0') << std::right << hh << ":" << std::setw(2) << std::setfill('0') << std::right << mm << ":" diff --git a/test/data/issue_1912_poc.jpg b/test/data/issue_1912_poc.jpg new file mode 100644 index 00000000..837d2ebb Binary files /dev/null and b/test/data/issue_1912_poc.jpg differ diff --git a/tests/bugfixes/github/test_issue_1912.py b/tests/bugfixes/github/test_issue_1912.py new file mode 100644 index 00000000..de496a6a --- /dev/null +++ b/tests/bugfixes/github/test_issue_1912.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, path, check_no_ASAN_UBSAN_errors + +class TagsIntPrint0x0007IntegerOverflow(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/issues/1912 + """ + url = "https://github.com/Exiv2/exiv2/issues/1912" + + filename = path("$data_path/issue_1912_poc.jpg") + commands = ["$exiv2 -q -Pt $filename"] + stderr = [""] + retval = [0] + + compare_stdout = check_no_ASAN_UBSAN_errors