diff --git a/src/tags_int.cpp b/src/tags_int.cpp index cc23ded71d..69eed8a1af 100644 --- a/src/tags_int.cpp +++ b/src/tags_int.cpp @@ -2585,12 +2585,22 @@ namespace Exiv2 { URational exposureTime(float shutterSpeedValue) { URational ur(1, 1); - double tmp = std::exp(std::log(2.0) * static_cast(shutterSpeedValue)); + const double tmp = std::exp(std::log(2.0) * static_cast(shutterSpeedValue)); if (tmp > 1) { - ur.second = static_cast(tmp + 0.5); + // Add 0.5 for rounding. + const double x = tmp + 0.5; + // Check that x is within the range of a uint32_t before casting. + if (x <= std::numeric_limits::max()) { + ur.second = static_cast(x); + } } else { - ur.first = static_cast(1/tmp + 0.5); + // Add 0.5 for rounding. + const double x = 1/tmp + 0.5; + // Check that x is within the range of a uint32_t before casting. + if (0 <= x && x <= std::numeric_limits::max()) { + ur.first = static_cast(x); + } } return ur; } diff --git a/test/data/issue_1827_poc.crw b/test/data/issue_1827_poc.crw new file mode 100644 index 0000000000..eafb762353 Binary files /dev/null and b/test/data/issue_1827_poc.crw differ diff --git a/tests/bugfixes/github/test_issue_1827.py b/tests/bugfixes/github/test_issue_1827.py new file mode 100644 index 0000000000..3f9c4eaf3f --- /dev/null +++ b/tests/bugfixes/github/test_issue_1827.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, CopyTmpFiles, path, check_no_ASAN_UBSAN_errors + +class ExposureTimeCastDoubleToLong(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/issues/1827 + """ + url = "https://github.com/Exiv2/exiv2/issues/1827" + + filename = path("$data_path/issue_1827_poc.crw") + commands = ["$exiv2 $filename"] + stderr = [""] + retval = [0] + + compare_stdout = check_no_ASAN_UBSAN_errors