fix(dav): handle out-of-range datetime values in file search - #60364
Conversation
On 32-bit PHP, DateTime::getTimestamp() can throw ValueError or DateRangeError when a WebDAV SEARCH datetime value is outside the platform's representable integer timestamp range. This can happen when clients send broad date ranges for file search, for example dates before 1970 or after 2038. The exception is currently converted to an InvalidArgumentException and aborts the whole SEARCH request. Clamp unrepresentable datetime values to the nearest platform boundary instead, so the SEARCH request can still be executed. Signed-off-by: Iven Ahrens <25607353+Ahnz@users.noreply.github.com>
artonge
left a comment
There was a problem hiding this comment.
Looks good.
Some DAV SEARCH requests use very broad datetime bounds for file search
Do you have examples?
|
Hello there, We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process. Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6 Thank you for contributing to Nextcloud and we hope to hear from you soon! (If you believe you should not receive this message, you can add yourself to the blocklist.) |
One public example for broad datetime bounds is in nextcloud/ios#3598, where the iOS media search log contains: That is the kind of broad date range I meant. On 32-bit PHP, both sides are outside the representable timestamp range: I also reproduced this locally on a 32-bit Nextcloud setup with the current iOS app. The iOS log showed the media search failing against {
"app": "webdav",
"method": "SEARCH",
"url": "/remote.php/dav",
"message": "Invalid property value for {DAV:}getlastmodified",
"userAgent": "Mozilla/5.0 (iOS) Nextcloud-iOS/33.0.8",
"version": "33.0.3.2",
"exception": {
"Exception": "InvalidArgumentException",
"Message": "Invalid property value for {DAV:}getlastmodified",
"File": "/var/www/nextcloud/apps/dav/lib/Files/FileSearchBackend.php",
"Previous": {
"Exception": "ValueError",
"Message": "Epoch doesn't fit in a PHP integer",
"File": "/var/www/nextcloud/apps/dav/lib/Files/FileSearchBackend.php"
}
}
}If I am not mistaken, the same code path can also be triggered with a direct DAV |
Summary
Some DAV SEARCH requests use very broad datetime bounds for file search. For example, media searches may use a range such as
0001-01-01to4001-01-01to search across all possible media dates.On 32-bit PHP, those bounds are outside the timestamp range that can be represented as a native integer:
When
FileSearchBackend::castValue()converts such a datetime withDateTime::getTimestamp(), PHP throws because the resulting timestamp does not fit into a 32-bit integer. PHP 8.2 throwsValueError; PHP 8.3 and newer throwDateRangeError.transformSearchOperation()then turns the error into:InvalidArgumentException: Invalid property value for {DAV:}getlastmodifiedThe whole SEARCH request fails.
Fix
Move DATETIME casting into a small helper and handle datetime values that cannot be represented on the current platform by clamping them to the platform-supported range:
0PHP_INT_MAXThis preserves the existing behavior for datetime values that can be represented on the current platform. The added handling only applies when
DateTime::getTimestamp()cannot represent the value.This does not extend the supported date range on 32-bit PHP. It keeps the SEARCH request executable by mapping out-of-range search bounds to the nearest documented 32-bit boundary.
Notes
The fix is generic for DAV datetime search values and is not specific to the iOS client.
Related issues:
Testing
Invalid property value for {DAV:}getlastmodifiedno longer appears innextcloud.logphp -l apps/dav/lib/Files/FileSearchBackend.phpChecklist
AI