jim-easterbrook / python-exiv2

Low level Python interface to the Exiv2 C++ library.
GNU General Public License v3.0
15 stars 1 forks source link

tests fail in year 2038 #44

Open bmwiedemann opened 2 days ago

bmwiedemann commented 2 days ago

While working on reproducible builds for openSUSE I found that our python-exiv2 fails 2 tests (on x86_64) when run after the 0x7fffffff 31-bit overflow of the signed UNIX epoch (count of seconds since 1970)

======================================================================
FAIL: test_DateValue (test_value.TestValueModule)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/abuild/rpmbuild/BUILD/python-exiv2-0.17.1/tests/test_value.py", line 378, in test_DateValue
    self.do_conversion_tests(value, py_date.isoformat(), seconds)
  File "/home/abuild/rpmbuild/BUILD/python-exiv2-0.17.1/tests/test_value.py", line 94, in do_conversion_tests
    self.assertAlmostEqual(
AssertionError: -2147408896.0 != 2147558400.0 within 5 places (4294967296.0 difference)

======================================================================
FAIL: test_TimeValue (test_value.TestValueModule)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/abuild/rpmbuild/BUILD/python-exiv2-0.17.1/tests/test_value.py", line 448, in test_TimeValue
    self.do_conversion_tests(value, py_time.isoformat(), seconds)
  File "/home/abuild/rpmbuild/BUILD/python-exiv2-0.17.1/tests/test_value.py", line 79, in do_conversion_tests
    self.assertAlmostEqual(result, float(number), places=5)
AssertionError: 81252.0 != -5148.0 within 5 places (86400.0 difference)

----------------------------------------------------------------------
Ran 59 tests in 0.031s

FAILED (failures=2, skipped=2)

In Debian and openSUSE, you can reproduce it with

osc checkout openSUSE:Factory/python-exiv2 && cd $_
osc build --vm-type=kvm --noservice --clean --build-opt=--vm-custom-opt="-rtc base=2038-01-20T00:00:00" -j4 standard

And maybe using faketime can also trigger the issue.

jim-easterbrook commented 2 days ago

Thanks for that. Do you know if other applications using libexiv2 suffer a similar problem? I'm assuming it's a problem in libexiv2 itself, but I'll investigate further next week.

bmwiedemann commented 2 days ago

I did not see any others so far... but OTOH most projects don't run as many automated tests as python does.

jim-easterbrook commented 2 days ago

I've found the problem with test_DateValue. It's checking the result of DateValue.toRational, which is of type Exiv2.Rational. https://exiv2.org/doc/classExiv2_1_1DateValue.html#a9897cf9cee63d3f4d073db3c2d0ad355

Exiv2.Rational is defined as a pair of int32_t. https://exiv2.org/doc/namespaceExiv2.html#a03e01c8ca5f7a70f166db6b05115bef7

For most sensible uses of Exiv2.Rational this is quite sufficient, so I don't expect the exiv2 project would welcome any attempt to change it. There is no sensible reason to want a UNIX timestamp as a rational number, so I may just remove this from the Python interface.

The problem with test_TimeValue is similar. https://exiv2.org/doc/classExiv2_1_1TimeValue.html#a3f35dfcf48c850030e57e960e32085ea