Skip to content

Validate constructor parameters for dynamically instantiated list views - #6708

Open
SoftCreatR wants to merge 1 commit into
WoltLab:6.2from
SoftCreatR:bugfix/list-view-parameter-validation
Open

Validate constructor parameters for dynamically instantiated list views#6708
SoftCreatR wants to merge 1 commit into
WoltLab:6.2from
SoftCreatR:bugfix/list-view-parameter-validation

Conversation

@SoftCreatR

Copy link
Copy Markdown
Contributor

List views were instantiated by unpacking unvalidated query parameters directly into their constructors. Scalar values could therefore reach constructor properties and downstream methods with incorrect types.

This caused malformed tagIDs parameters to reach TagEngine::getSubselectForObjectsByTagIDs(), resulting in a TypeError:

<<<<<<<<bdc8ad84657e8ab54d7ad351e478815665280f18<<<<
Wed, 02 Sep 2026 06:40:25 +0000
Message: wcf\system\tagging\TagEngine::{closure:wcf\system\tagging\TagEngine::getSubselectForObjectsByTagIDs():341}(): Argument #1 ($tagID) must be of type int, string given
PHP version: 8.4.25
WoltLab Suite version: 6.2.6
Request URI: GET /list-view-filter/?listView=wcf%5Csystem%5ClistView%5Cuser%5CTaggedArticleListView&listViewParameters%5BtagIDs%5D%5B0%5D=14%22%27%2C%28.%29abcd
Referrer: 
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Peak Memory Usage: 5617872/536870912
======
Error Class: TypeError
Error Message: wcf\system\tagging\TagEngine::{closure:wcf\system\tagging\TagEngine::getSubselectForObjectsByTagIDs():341}(): Argument #1 ($tagID) must be of type int, string given
Error Code: 0
File: /lib/system/tagging/TagEngine.class.php (341)
Extra Information: -
Stack Trace: [{"function":"{closure:wcf\\system\\tagging\\TagEngine::getSubselectForObjectsByTagIDs():341}","class":"wcf\\system\\tagging\\TagEngine","type":"::","args":["[error_during_sanitization]"],"file":"[internal function]","line":"?"},{"file":"\/lib\/system\/tagging\/TagEngine.class.php","line":341,"function":"array_map","args":["Closure",["[redacted]"]],"class":"","type":""},{"file":"\/lib\/system\/listView\/user\/TaggedArticleListView.class.php","line":30,"function":"getSubselectForObjectsByTagIDs","class":"wcf\\system\\tagging\\TagEngine","type":"->","args":["com.woltlab.wcf.article",["[redacted]"]]},{"file":"\/lib\/system\/listView\/AbstractListView.class.php","line":250,"function":"createObjectList","class":"wcf\\system\\listView\\user\\TaggedArticleListView","type":"->","args":[]},{"file":"\/lib\/system\/listView\/AbstractListView.class.php","line":826,"function":"initObjectList","class":"wcf\\system\\listView\\AbstractListView","type":"->","args":[]},{"file":"\/lib\/system\/listView\/AbstractListView.class.php","line":519,"function":"init","class":"wcf\\system\\listView\\AbstractListView","type":"->","args":[]},{"file":"\/lib\/system\/listView\/AbstractListView.class.php","line":432,"function":"getAvailableFilters","class":"wcf\\system\\listView\\AbstractListView","type":"->","args":[]},{"file":"\/lib\/action\/ListViewFilterAction.class.php","line":64,"function":"isFilterable","class":"wcf\\system\\listView\\AbstractListView","type":"->","args":[]},{"file":"\/lib\/system\/request\/Request.class.php","line":52,"function":"handle","class":"wcf\\action\\ListViewFilterAction","type":"->","args":["Laminas\\Diactoros\\ServerRequest"]},{"file":"\/lib\/http\/middleware\/HandleValinorMappingErrors.class.php","line":35,"function":"handle","class":"wcf\\system\\request\\Request","type":"->","args":["Laminas\\Diactoros\\ServerRequest"]},{"file":"\/lib\/system\/request\/RequestHandler.class.php","line":168,"function":"process","class":"wcf\\http\\Pipeline","type":"->","args":["Laminas\\Diactoros\\ServerRequest","wcf\\http\\RequestHandlerMiddleware"]},{"file":"\/index.php","line":10,"function":"handle","class":"wcf\\system\\request\\RequestHandler","type":"->","args":["wcf"]}]
<<<<

This change/PR:

  • adds Helper::mapQueryParametersToClass() to map query parameters against a class constructor signature;
  • uses constructor argument mapping without attempting to map the complete object;
  • applies the helper to ListViewFilterAction, GetItem, and GetItems;
  • declares TaggedArticleListView::$tagIDs as a non-empty-list<positive-int>.

Invalid parameters now result in the existing HTTP 400 mapping error instead of reaching the list view or its downstream services with invalid types.

Map query parameters against list view constructor signatures before instantiating the selected view.

This consistently validates parameters across the filter action and both list view endpoints, preventing malformed tag IDs and other constructor arguments from reaching downstream code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant