sabre-io / dav

sabre/dav is a CalDAV, CardDAV and WebDAV framework for PHP
http://sabre.io
BSD 3-Clause "New" or "Revised" License
1.54k stars 347 forks source link

PHP 8.2 ValueError: Epoch doesn't fit in a PHP integer in PDO.php #1525

Closed Octet-nl closed 11 months ago

Octet-nl commented 11 months ago

Hello,

I'm using Sabre in a Baikal package on a Raspberry Pi.

On a RPi 3 with Raspbian Buster (Debian 10, PHP 7.3) everything works ok.

On a RPi 4 with Raspbian Bookworm (Debian 12, PHP 8.2.7) I get a lot of error messages in /var/log/apache2/error.log

Offending line is: 636 $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp();

The messages are probably pointing to the PHP 2038 problem. Strange thing is I don't get them in PHP 7.2.

[Wed Dec 06 11:08:52.068143 2023] [php:notice] [pid 1047] [client 99.999.999.999:9999] ValueError: Epoch doesn't fit in a PHP integer in /www/baikal/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php:636\nStack trace:\n#0 /www/baikal/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php(636): DateTimeImmutable->getTimestamp()\n#1 /www/baikal/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php(545): Sabre\\CalDAV\\Backend\\PDO->getDenormalizedData()\n#2 /www/baikal/vendor/sabre/dav/lib/CalDAV/Calendar.php(199): Sabre\\CalDAV\\Backend\\PDO->createCalendarObject()\n#3 /www/baikal/vendor/sabre/dav/lib/DAV/Server.php(1098): Sabre\\CalDAV\\Calendar->createFile()\n#4 /www/baikal/vendor/sabre/dav/lib/DAV/CorePlugin.php(504): Sabre\\DAV\\Server->createFile()\n#5 /www/baikal/vendor/sabre/event/lib/WildcardEmitterTrait.php(89): Sabre\\DAV\\CorePlugin->httpPut()\n#6 /www/baikal/vendor/sabre/dav/lib/DAV/Server.php(472): Sabre\\DAV\\Server->emit()\n#7 /www/baikal/vendor/sabre/dav/lib/DAV/Server.php(253): Sabre\\DAV\\Server->invokeMethod()\n#8 /www/baikal/vendor/sabre/dav/lib/DAV/Server.php(321): Sabre\\DAV\\Server->start()\n#9 /www/baikal/Core/Frameworks/Baikal/Core/Server.php(119): Sabre\\DAV\\Server->exec()\n#10 /www/baikal/html/dav.php(69): Baikal\\Core\\Server->start()\n#11 {main}

phil-davis commented 11 months ago

https://www.php.net/manual/en/datetime.gettimestamp.php "If the timestamp cannot be represented as int, a DateRangeError is thrown. Prior to PHP 8.3.0, a ValueError is thrown. And, prior to PHP 8.0.0, false was returned in this case."

In PHP 7.4 it seems that the Unix timestamp would have got effectively set to 0 (false) when a calendar date is out-of-range. On a 32-bit RPi3 that would have happened when trying to process dates beyond the 2038 Unix 32-bit timestamp limit. (And/or for dates a logn time in the past - negative before 1970).

In PHP 8.0 8.1 8.2 an exception is thrown ValueError, and in PHP 8.3 it is now DateRangeError. So now the code aborts, whereas with PHP 7.4 it probably ended up displaying 1970-01-01:00:00:00.

The RPi4 seems to be 64-bit but still delivered by default with a 32-bit Debian installed: https://support.thepihut.com/hc/en-us/articles/360017234718-Why-isn-t-my-Raspberry-Pi-64-bit-

In your case, try using a 64-bit OS on your RPi4.

For the general case, I wonder if we should try to catch and handle these new exceptions. For example, "the timestamp can be retrieved as string by using DateTimeInterface::format() with the U format." So if the calculated timestamp does not fit in an int, we can get and return a string of ASCII digits that is a text representation of the "big Unix timestamp" number. But then the problem might just be passed back to the consumers - they will get back "text numbers" that are too big for them to calculate with, unless they use some big-int library themselves to do calculations/comparisons/conversions.

Octet-nl commented 11 months ago

Thanks for your detailed explanation.

Re-installing a 64 bit OS is not an option, the server runs a lot of (older) applications and I would undoubtedly run into other incompatibility errors.

For the time being, for me a workable solution is adding

restore_error_handler()

near the top of function getDenormalizedData. I understand this restores PHP 7 behaviour.

All the mentioned errormessages are removed, as there are no more exceptions thrown.

Regards and thanks for your answer.