diff --git a/wcfsetup/install/files/lib/system/gridView/AbstractGridView.class.php b/wcfsetup/install/files/lib/system/gridView/AbstractGridView.class.php index ee322b79a7a..d5e30f2f894 100644 --- a/wcfsetup/install/files/lib/system/gridView/AbstractGridView.class.php +++ b/wcfsetup/install/files/lib/system/gridView/AbstractGridView.class.php @@ -2,12 +2,12 @@ namespace wcf\system\gridView; -use LogicException; use wcf\action\GridViewFilterAction; use wcf\data\DatabaseObject; use wcf\data\DatabaseObjectList; use wcf\event\IPsr14Event; use wcf\system\event\EventHandler; +use wcf\system\gridView\filter\exception\InvalidFilterValue; use wcf\system\interaction\bulk\IBulkInteractionProvider; use wcf\system\interaction\IInteraction; use wcf\system\interaction\IInteractionProvider; @@ -567,15 +567,15 @@ public function getFilterLabel(string $id): string { $column = $this->getColumn($id); if (!$column) { - throw new LogicException("Unknown column '" . $id . "'."); + throw new \LogicException("Unknown column '" . $id . "'."); } if (!$column->getFilter()) { - throw new LogicException("Column '" . $id . "' has no filter."); + throw new \LogicException("Column '" . $id . "' has no filter."); } if (!isset($this->activeFilters[$id])) { - throw new LogicException("No value for filter '" . $id . "' found."); + throw new \LogicException("No value for filter '" . $id . "' found."); } $value = $column->getFilter()->renderValue($this->activeFilters[$id]); @@ -761,14 +761,28 @@ protected function initObjectList(): void */ protected function applyFilters(): void { - foreach ($this->getActiveFilters() as $key => $value) { + $this->activeFilters = \array_filter($this->activeFilters, function ($value, $key) { $column = $this->getColumn($key); if (!$column) { - throw new LogicException("Unknown column '" . $key . "'"); + if (\ENABLE_DEBUG_MODE) { + throw new \LogicException("Filter applied for unknown column '{$key}'."); + } else { + return false; + } } - $column->getFilter()->applyFilter($this->getObjectList(), $column->getID(), $value); - } + try { + $column->getFilter()->applyFilter($this->getObjectList(), $column->getID(), $value); + } catch (InvalidFilterValue $e) { + if (\ENABLE_DEBUG_MODE) { + throw $e; + } else { + return false; + } + } + + return true; + }, \ARRAY_FILTER_USE_BOTH); } /** diff --git a/wcfsetup/install/files/lib/system/gridView/filter/CategoryFilter.class.php b/wcfsetup/install/files/lib/system/gridView/filter/CategoryFilter.class.php index aafdd6fa510..96828898eed 100644 --- a/wcfsetup/install/files/lib/system/gridView/filter/CategoryFilter.class.php +++ b/wcfsetup/install/files/lib/system/gridView/filter/CategoryFilter.class.php @@ -6,6 +6,7 @@ use wcf\system\category\CategoryHandler; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\SelectFormField; +use wcf\system\gridView\filter\exception\InvalidFilterValue; /** * Allows a column to be filtered on the basis of a select category. @@ -36,9 +37,14 @@ public function getFormField(string $id, string $label): AbstractFormField #[\Override] public function applyFilter(DatabaseObjectList $list, string $id, string $value): void { + $category = CategoryHandler::getInstance()->getCategory((int)$value); + if ($category === null) { + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$id}' given."); + } + $columnName = $this->getDatabaseColumnName($list, $id); - $list->getConditionBuilder()->add("{$columnName} = ?", [$value]); + $list->getConditionBuilder()->add("{$columnName} = ?", [$category->categoryID]); } #[\Override] diff --git a/wcfsetup/install/files/lib/system/gridView/filter/DateFilter.class.php b/wcfsetup/install/files/lib/system/gridView/filter/DateFilter.class.php index 7643e560741..772e7f5d634 100644 --- a/wcfsetup/install/files/lib/system/gridView/filter/DateFilter.class.php +++ b/wcfsetup/install/files/lib/system/gridView/filter/DateFilter.class.php @@ -5,6 +5,7 @@ use wcf\data\DatabaseObjectList; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\DateRangeFormField; +use wcf\system\gridView\filter\exception\InvalidFilterValue; use wcf\system\WCF; /** @@ -32,7 +33,7 @@ public function applyFilter(DatabaseObjectList $list, string $id, string $value) $timestamps = $this->getTimestamps($value); if (!$timestamps['from'] && !$timestamps['to']) { - return; + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$id}' given."); } if (!$timestamps['to']) { diff --git a/wcfsetup/install/files/lib/system/gridView/filter/NumericFilter.class.php b/wcfsetup/install/files/lib/system/gridView/filter/NumericFilter.class.php index 16704eac69e..cb41dc21635 100644 --- a/wcfsetup/install/files/lib/system/gridView/filter/NumericFilter.class.php +++ b/wcfsetup/install/files/lib/system/gridView/filter/NumericFilter.class.php @@ -5,6 +5,7 @@ use wcf\data\DatabaseObjectList; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\NumericRangeFormField; +use wcf\system\gridView\filter\exception\InvalidFilterValue; /** * Filter for columns that contain numerics. @@ -39,7 +40,7 @@ public function applyFilter(DatabaseObjectList $list, string $id, string $value) $values = $this->parseValue($value); if (!$values['from'] && !$values['to']) { - return; + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$id}' given."); } if (!$values['to']) { diff --git a/wcfsetup/install/files/lib/system/gridView/filter/SelectFilter.class.php b/wcfsetup/install/files/lib/system/gridView/filter/SelectFilter.class.php index 67aeb57176e..6b6b87a601e 100644 --- a/wcfsetup/install/files/lib/system/gridView/filter/SelectFilter.class.php +++ b/wcfsetup/install/files/lib/system/gridView/filter/SelectFilter.class.php @@ -5,6 +5,7 @@ use wcf\data\DatabaseObjectList; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\SelectFormField; +use wcf\system\gridView\filter\exception\InvalidFilterValue; use wcf\system\WCF; /** @@ -39,6 +40,10 @@ public function getFormField(string $id, string $label): AbstractFormField #[\Override] public function applyFilter(DatabaseObjectList $list, string $id, string $value): void { + if (!isset($this->options[$value])) { + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$id}' given."); + } + $columnName = $this->getDatabaseColumnName($list, $id); $list->getConditionBuilder()->add("{$columnName} = ?", [$value]); diff --git a/wcfsetup/install/files/lib/system/gridView/filter/TimeFilter.class.php b/wcfsetup/install/files/lib/system/gridView/filter/TimeFilter.class.php index d0ac7070fb3..151f5b403af 100644 --- a/wcfsetup/install/files/lib/system/gridView/filter/TimeFilter.class.php +++ b/wcfsetup/install/files/lib/system/gridView/filter/TimeFilter.class.php @@ -5,6 +5,7 @@ use wcf\data\DatabaseObjectList; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\DateRangeFormField; +use wcf\system\gridView\filter\exception\InvalidFilterValue; use wcf\system\WCF; /** @@ -34,7 +35,7 @@ public function applyFilter(DatabaseObjectList $list, string $id, string $value) $timestamps = $this->getTimestamps($value); if (!$timestamps['from'] && !$timestamps['to']) { - return; + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$id}' given."); } if (!$timestamps['to']) { diff --git a/wcfsetup/install/files/lib/system/gridView/filter/UserFilter.class.php b/wcfsetup/install/files/lib/system/gridView/filter/UserFilter.class.php index 299e430a3f4..8271408c8fa 100644 --- a/wcfsetup/install/files/lib/system/gridView/filter/UserFilter.class.php +++ b/wcfsetup/install/files/lib/system/gridView/filter/UserFilter.class.php @@ -6,6 +6,7 @@ use wcf\system\cache\runtime\UserRuntimeCache; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\user\UserFormField; +use wcf\system\gridView\filter\exception\InvalidFilterValue; /** * Filter for columns that contain user ids. @@ -28,9 +29,14 @@ public function getFormField(string $id, string $label): AbstractFormField #[\Override] public function applyFilter(DatabaseObjectList $list, string $id, string $value): void { + $user = UserRuntimeCache::getInstance()->getObject((int)$value); + if ($user === null) { + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$id}' given."); + } + $columnName = $this->getDatabaseColumnName($list, $id); - $list->getConditionBuilder()->add("{$columnName} = ?", [$value]); + $list->getConditionBuilder()->add("{$columnName} = ?", [$user->userID]); } #[\Override] diff --git a/wcfsetup/install/files/lib/system/gridView/filter/exception/InvalidFilterValue.class.php b/wcfsetup/install/files/lib/system/gridView/filter/exception/InvalidFilterValue.class.php new file mode 100644 index 00000000000..3bb8168db4c --- /dev/null +++ b/wcfsetup/install/files/lib/system/gridView/filter/exception/InvalidFilterValue.class.php @@ -0,0 +1,13 @@ + + * @since 6.2 + */ +final class InvalidFilterValue extends \RuntimeException {} diff --git a/wcfsetup/install/files/lib/system/listView/AbstractListView.class.php b/wcfsetup/install/files/lib/system/listView/AbstractListView.class.php index 868181d82f8..3fd2686af06 100644 --- a/wcfsetup/install/files/lib/system/listView/AbstractListView.class.php +++ b/wcfsetup/install/files/lib/system/listView/AbstractListView.class.php @@ -12,6 +12,7 @@ use wcf\system\interaction\IInteractionProvider; use wcf\system\interaction\InteractionContextMenuComponent; use wcf\system\listView\filter\IListViewFilter; +use wcf\system\listView\filter\exception\InvalidFilterValue; use wcf\system\request\LinkHandler; use wcf\system\WCF; @@ -244,13 +245,27 @@ protected function getSqlOrderBy(): string */ protected function applyFilters(): void { - foreach ($this->getActiveFilters() as $key => $value) { + $this->activeFilters = \array_filter($this->activeFilters, function ($value, $key) { if (!isset($this->availableFilters[$key])) { - throw new \LogicException("Unknown filter '" . $key . "'"); + if (\ENABLE_DEBUG_MODE) { + throw new \LogicException("Filter applied for unknown column '{$key}'."); + } else { + return false; + } } - $this->availableFilters[$key]->applyFilter($this->getObjectList(), $value); - } + try { + $this->availableFilters[$key]->applyFilter($this->getObjectList(), $value); + } catch (InvalidFilterValue $e) { + if (\ENABLE_DEBUG_MODE) { + throw $e; + } else { + return false; + } + } + + return true; + }, \ARRAY_FILTER_USE_BOTH); } /** diff --git a/wcfsetup/install/files/lib/system/listView/filter/CategoryFilter.class.php b/wcfsetup/install/files/lib/system/listView/filter/CategoryFilter.class.php index 6e3310c2b3a..58e4c7a4927 100644 --- a/wcfsetup/install/files/lib/system/listView/filter/CategoryFilter.class.php +++ b/wcfsetup/install/files/lib/system/listView/filter/CategoryFilter.class.php @@ -6,6 +6,7 @@ use wcf\system\category\CategoryHandler; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\SelectFormField; +use wcf\system\listView\filter\exception\InvalidFilterValue; /** * Allows a column to be filtered on the basis of a select category. @@ -41,6 +42,11 @@ public function getFormField(): AbstractFormField #[\Override] public function applyFilter(DatabaseObjectList $list, string $value): void { + $category = CategoryHandler::getInstance()->getCategory((int)$value); + if ($category === null) { + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$this->id}' given."); + } + $columnName = $this->getDatabaseColumnName($list); $list->getConditionBuilder()->add("{$columnName} = ?", [$value]); diff --git a/wcfsetup/install/files/lib/system/listView/filter/DateFilter.class.php b/wcfsetup/install/files/lib/system/listView/filter/DateFilter.class.php index f6675d78bd6..0d24c21cf79 100644 --- a/wcfsetup/install/files/lib/system/listView/filter/DateFilter.class.php +++ b/wcfsetup/install/files/lib/system/listView/filter/DateFilter.class.php @@ -5,6 +5,7 @@ use wcf\data\DatabaseObjectList; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\DateRangeFormField; +use wcf\system\listView\filter\exception\InvalidFilterValue; use wcf\system\WCF; /** @@ -32,7 +33,7 @@ public function applyFilter(DatabaseObjectList $list, string $value): void $timestamps = $this->getTimestamps($value); if (!$timestamps['from'] && !$timestamps['to']) { - return; + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$this->id}' given."); } if (!$timestamps['to']) { diff --git a/wcfsetup/install/files/lib/system/listView/filter/LabelFilter.class.php b/wcfsetup/install/files/lib/system/listView/filter/LabelFilter.class.php index ecfd2f18254..1276d9352a9 100644 --- a/wcfsetup/install/files/lib/system/listView/filter/LabelFilter.class.php +++ b/wcfsetup/install/files/lib/system/listView/filter/LabelFilter.class.php @@ -6,6 +6,7 @@ use wcf\data\label\group\ViewableLabelGroup; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\label\LabelFormField; +use wcf\system\listView\filter\exception\InvalidFilterValue; /** * Filter that allows to filter a list view by labels. @@ -43,6 +44,11 @@ public function getLabel(): string #[\Override] public function applyFilter(DatabaseObjectList $list, string $value): void { + $label = $this->labelGroup->getLabel((int)$value); + if ($label === null) { + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$this->id}' given."); + } + $list->getConditionBuilder()->add( "{$list->getDatabaseTableAlias()}.{$list->getDatabaseTableIndexName()} IN ( SELECT objectID @@ -52,7 +58,7 @@ public function applyFilter(DatabaseObjectList $list, string $value): void )", [ $this->objectTypeID, - $value, + $label->labelID, ] ); } diff --git a/wcfsetup/install/files/lib/system/listView/filter/NumericFilter.class.php b/wcfsetup/install/files/lib/system/listView/filter/NumericFilter.class.php index 4eac64fe58c..55563061e74 100644 --- a/wcfsetup/install/files/lib/system/listView/filter/NumericFilter.class.php +++ b/wcfsetup/install/files/lib/system/listView/filter/NumericFilter.class.php @@ -5,6 +5,7 @@ use wcf\data\DatabaseObjectList; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\NumericRangeFormField; +use wcf\system\listView\filter\exception\InvalidFilterValue; /** * Filter for columns that contain numerics. @@ -41,7 +42,7 @@ public function applyFilter(DatabaseObjectList $list, string $value): void $values = $this->parseValue($value); if (!$values['from'] && !$values['to']) { - return; + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$this->id}' given."); } if (!$values['to']) { diff --git a/wcfsetup/install/files/lib/system/listView/filter/SelectFilter.class.php b/wcfsetup/install/files/lib/system/listView/filter/SelectFilter.class.php index b98d5e28eec..d40ade147e0 100644 --- a/wcfsetup/install/files/lib/system/listView/filter/SelectFilter.class.php +++ b/wcfsetup/install/files/lib/system/listView/filter/SelectFilter.class.php @@ -5,6 +5,7 @@ use wcf\data\DatabaseObjectList; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\SelectFormField; +use wcf\system\listView\filter\exception\InvalidFilterValue; use wcf\system\WCF; /** @@ -41,6 +42,10 @@ public function getFormField(): AbstractFormField #[\Override] public function applyFilter(DatabaseObjectList $list, string $value): void { + if (!isset($this->options[$value])) { + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$this->id}' given."); + } + $columnName = $this->getDatabaseColumnName($list); $list->getConditionBuilder()->add("{$columnName} = ?", [$value]); diff --git a/wcfsetup/install/files/lib/system/listView/filter/TimeFilter.class.php b/wcfsetup/install/files/lib/system/listView/filter/TimeFilter.class.php index 2d6d2e9082d..51533374b6e 100644 --- a/wcfsetup/install/files/lib/system/listView/filter/TimeFilter.class.php +++ b/wcfsetup/install/files/lib/system/listView/filter/TimeFilter.class.php @@ -5,6 +5,7 @@ use wcf\data\DatabaseObjectList; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\DateRangeFormField; +use wcf\system\listView\filter\exception\InvalidFilterValue; use wcf\system\WCF; /** @@ -34,7 +35,7 @@ public function applyFilter(DatabaseObjectList $list, string $value): void $timestamps = $this->getTimestamps($value); if (!$timestamps['from'] && !$timestamps['to']) { - return; + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$this->id}' given."); } if (!$timestamps['to']) { diff --git a/wcfsetup/install/files/lib/system/listView/filter/UserFilter.class.php b/wcfsetup/install/files/lib/system/listView/filter/UserFilter.class.php index 4f44f69ad17..6948f78f2c5 100644 --- a/wcfsetup/install/files/lib/system/listView/filter/UserFilter.class.php +++ b/wcfsetup/install/files/lib/system/listView/filter/UserFilter.class.php @@ -6,6 +6,7 @@ use wcf\system\cache\runtime\UserRuntimeCache; use wcf\system\form\builder\field\AbstractFormField; use wcf\system\form\builder\field\user\UserFormField; +use wcf\system\listView\filter\exception\InvalidFilterValue; /** * Filter for columns that contain user ids. @@ -28,6 +29,11 @@ public function getFormField(): AbstractFormField #[\Override] public function applyFilter(DatabaseObjectList $list, string $value): void { + $user = UserRuntimeCache::getInstance()->getObject((int)$value); + if ($user === null) { + throw new InvalidFilterValue("Invalid value '{$value}' for filter '{$this->id}' given."); + } + $columnName = $this->getDatabaseColumnName($list); $list->getConditionBuilder()->add("{$columnName} = ?", [$value]); diff --git a/wcfsetup/install/files/lib/system/listView/filter/exception/InvalidFilterValue.class.php b/wcfsetup/install/files/lib/system/listView/filter/exception/InvalidFilterValue.class.php new file mode 100644 index 00000000000..779d30476c9 --- /dev/null +++ b/wcfsetup/install/files/lib/system/listView/filter/exception/InvalidFilterValue.class.php @@ -0,0 +1,13 @@ + + * @since 6.2 + */ +final class InvalidFilterValue extends \RuntimeException {}