@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Validate some user provided calendar query range dates

Summary:
Calendar search form allows users to define date ranges. Entering gibberish data leads to a cryptic exception due to calling `format()` on `null`, as `AphrontFormDateControlValue::getDateTime()` can return `null` instead of a `DateTime` object.

Also add some additional PhpDoc as a result of playing with this code.

Note that other calendar query forms are more lenient and still accepts gibberish after applying this patch. The intention behind this patch is replacing a cryptic exception with a more appropriate and descriptive error; this patch does not attempt to introduce validation everywhere.

```
EXCEPTION: (Error) Call to a member function format() on null at [<phorge>/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php:469]
```

Closes T15943

Test Plan:
* On http://phorge.localhost/calendar/query/month/, click "Edit Query", check "Occurs After", replace default date value with "abcde", click "Search" button
* On http://phorge.localhost/calendar/query/month/, click "Edit Query", check "Occurs After", replace default time value with "abcde", click "Search" button
* On http://phorge.localhost/calendar/query/month/, click "Edit Query", check "Occurs Before", replace default date value with "abcde", click "Search" button
* On http://phorge.localhost/calendar/query/month/, click "Edit Query", check "Occurs Before", replace default time value with "abcde", click "Search" button
* On http://phorge.localhost/calendar/query/day/, click "Edit Query", check "Occurs After", replace default date value with "abcde", click "Search" button
* On http://phorge.localhost/calendar/query/day/, click "Edit Query", check "Occurs After", replace default time value with "abcde", click "Search" button
* On http://phorge.localhost/calendar/query/day/, click "Edit Query", check "Occurs Before", replace default date value with "abcde", click "Search" button
* On http://phorge.localhost/calendar/query/day/, click "Edit Query", check "Occurs Before", replace default time value with "abcde", click "Search" button

Reviewers: O1 Blessed Committers, valerio.bozzolan

Reviewed By: O1 Blessed Committers, valerio.bozzolan

Subscribers: tobiaswiese, valerio.bozzolan, Matthew, Cigaryno

Maniphest Tasks: T15943

Differential Revision: https://we.phorge.it/D25825

+34 -3
+34 -3
src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php
··· 485 485 ->setHeader($header); 486 486 } 487 487 488 + /** 489 + * @param string|null $range_start Epoch 490 + * @param string|null $range_end Epoch 491 + * @param string $display View, such as "month" or "day" 492 + * @return array<string|int, string|int, string|int> YYYY, M, D 493 + */ 488 494 private function getDisplayYearAndMonthAndDay( 489 495 $range_start, 490 496 $range_end, ··· 527 533 528 534 /** 529 535 * @param PhabricatorSavedQuery $saved 530 - * @return AphrontFormDateControlValue 536 + * @return AphrontFormDateControlValue Query date range start 531 537 */ 532 538 private function getQueryDateFrom(PhabricatorSavedQuery $saved) { 533 539 if ($this->calendarYear && $this->calendarMonth) { ··· 544 550 )); 545 551 } 546 552 547 - return $this->getQueryDate($saved, 'rangeStart'); 553 + $date = $this->getQueryDate($saved, 'rangeStart'); 554 + $this->validateDate($date); 555 + 556 + return $date; 548 557 } 549 558 559 + /** 560 + * @param PhabricatorSavedQuery $saved 561 + * @return AphrontFormDateControlValue Query date range end 562 + */ 550 563 private function getQueryDateTo(PhabricatorSavedQuery $saved) { 551 - return $this->getQueryDate($saved, 'rangeEnd'); 564 + $date = $this->getQueryDate($saved, 'rangeEnd'); 565 + $this->validateDate($date); 566 + return $date; 567 + } 568 + 569 + /** 570 + * Validate the user provided date and time value(s) by calling 571 + * @{class:AphrontFormDateControlValue}::isValid(). 572 + * Throw an Exception if invalid. 573 + * 574 + * @param AphrontFormDateControlValue $date 575 + * @return void 576 + */ 577 + private function validateDate(AphrontFormDateControlValue $date) { 578 + if (!$date->isValid()) { 579 + // TODO: Use DateMalformedStringException once we require PHP 8.3.0 580 + throw new Exception( 581 + pht('Invalid date or time value set as query value.')); 582 + } 552 583 } 553 584 554 585 private function getQueryDate(PhabricatorSavedQuery $saved, $key) {