diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/ObjectController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/ObjectController.php index 0f59db0fc..fd078d119 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/ObjectController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/ObjectController.php @@ -795,7 +795,7 @@ class ObjectController extends BrickController // Updating host object $oFormManager->OnUpdate(array( - 'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), + 'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), )); $oHostObject = $oFormManager->GetObject(); } @@ -807,7 +807,7 @@ class ObjectController extends BrickController $sQuery = $this->oRequestManipulatorHelper->ReadParam('sSearchValue', ''); $sFormPath = $this->oRequestManipulatorHelper->ReadParam('sFormPath', ''); $sFieldId = $this->oRequestManipulatorHelper->ReadParam('sFieldId', ''); - $aObjectIdsToIgnore = $this->oRequestManipulatorHelper->ReadParam('aObjectIdsToIgnore', null, FILTER_UNSAFE_RAW); + $aObjectIdsToIgnore = $this->oRequestManipulatorHelper->ReadParam('aObjectIdsToIgnore', null, FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); // Building search query // - Retrieving target object class from attcode @@ -1274,8 +1274,8 @@ class ObjectController extends BrickController // Retrieving parameters $sObjectClass = $this->oRequestManipulatorHelper->ReadParam('sObjectClass', ''); - $aObjectIds = $this->oRequestManipulatorHelper->ReadParam('aObjectIds', array(), FILTER_UNSAFE_RAW); - $aObjectAttCodes = $this->oRequestManipulatorHelper->ReadParam('aObjectAttCodes', array(), FILTER_UNSAFE_RAW); + $aObjectIds = $this->oRequestManipulatorHelper->ReadParam('aObjectIds', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); + $aObjectAttCodes = $this->oRequestManipulatorHelper->ReadParam('aObjectAttCodes', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); if (empty($sObjectClass) || empty($aObjectIds) || empty($aObjectAttCodes)) { IssueLog::Info(__METHOD__.' at line '.__LINE__.' : sObjectClass, aObjectIds and aObjectAttCodes expected, "'.$sObjectClass.'", "'.implode('/', $aObjectIds).'" given.'); @@ -1332,10 +1332,10 @@ class ObjectController extends BrickController // Retrieving parameters $sObjectClass = $this->oRequestManipulatorHelper->ReadParam('sObjectClass', ''); $sLinkClass = $this->oRequestManipulatorHelper->ReadParam('sLinkClass', ''); - $aObjectIds = $this->oRequestManipulatorHelper->ReadParam('aObjectIds', array(), FILTER_UNSAFE_RAW); - $aObjectAttCodes = $this->oRequestManipulatorHelper->ReadParam('aObjectAttCodes', array(), FILTER_UNSAFE_RAW); - $aLinkAttCodes = $this->oRequestManipulatorHelper->ReadParam('aLinkAttCodes', array(), FILTER_UNSAFE_RAW); - $sDateTimePickerWidgetParent = $this->oRequestManipulatorHelper->ReadParam('sDateTimePickerWidgetParent', array(), FILTER_UNSAFE_RAW); + $aObjectIds = $this->oRequestManipulatorHelper->ReadParam('aObjectIds', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); + $aObjectAttCodes = $this->oRequestManipulatorHelper->ReadParam('aObjectAttCodes', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); + $aLinkAttCodes = $this->oRequestManipulatorHelper->ReadParam('aLinkAttCodes', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); + $sDateTimePickerWidgetParent = $this->oRequestManipulatorHelper->ReadParam('sDateTimePickerWidgetParent', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); if (empty($sObjectClass) || empty($aObjectIds) || empty($aObjectAttCodes)) { IssueLog::Info(__METHOD__.' at line '.__LINE__.' : sObjectClass, aObjectIds and aObjectAttCodes expected, "'.$sObjectClass.'", "'.implode('/', diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php index 3025d26fc..5ef56b42f 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php @@ -115,7 +115,7 @@ class UserProfileBrickController extends BrickController // If this is ajax call, we are just submitting preferences or password forms if ($oRequest->isXmlHttpRequest()) { - $aCurrentValues = $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW); + $aCurrentValues = $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); $sFormType = $aCurrentValues['form_type']; if ($sFormType === PreferencesFormManager::FORM_TYPE) { @@ -214,7 +214,7 @@ class UserProfileBrickController extends BrickController $oFormManager = $sFormManagerClass::FromJSON($sFormManagerData); // Applying modification to object $aFormData['validation'] = $oFormManager->OnSubmit(array( - 'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), + 'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), )); // Reloading page only if preferences were changed if (($aFormData['validation']['valid'] === true) && !empty($aFormData['validation']['messages']['success'])) @@ -294,7 +294,7 @@ class UserProfileBrickController extends BrickController $oFormManager = $sFormManagerClass::FromJSON($sFormManagerData); // Applying modification to object $aFormData['validation'] = $oFormManager->OnSubmit(array( - 'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), + 'currentValues' => $this->oRequestManipulatorHelper->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), )); } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/BrickControllerHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/BrickControllerHelper.php index 2aa278feb..aad620084 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/BrickControllerHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/BrickControllerHelper.php @@ -53,7 +53,7 @@ class BrickControllerHelper public function ExtractSortParams() { // Getting sort params - $aSortParams = $this->oRequestManipulator->ReadParam('aSortParams', array()); + $aSortParams = $this->oRequestManipulator->ReadParam('aSortParams', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); // Converting sort direction to proper format for DBObjectSet as it only accept real booleans foreach ($aSortParams as $sAttributeAlias => $sDirection) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/ObjectFormHandlerHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/ObjectFormHandlerHelper.php index 08b7d3b23..a5b83e563 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/ObjectFormHandlerHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/ObjectFormHandlerHelper.php @@ -222,7 +222,7 @@ class ObjectFormHandlerHelper $aPrefillFormParam = array( 'user' => UserRights::GetUser(), 'origin' => 'portal', - 'stimulus' => $this->oRequestManipulator->ReadParam('apply_stimulus', null)['code'], + 'stimulus' => $this->oRequestManipulator->ReadParam('apply_stimulus', null, FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY)['code'], ); $oObject->PrefillForm('state_change', $aPrefillFormParam); } @@ -315,10 +315,10 @@ class ObjectFormHandlerHelper // Applying modification to object $aFormData['validation'] = $oFormManager->OnSubmit( array( - 'currentValues' => $this->oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), - 'attachmentIds' => $this->oRequestManipulator->ReadParam('attachment_ids', array(), FILTER_UNSAFE_RAW), + 'currentValues' => $this->oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), + 'attachmentIds' => $this->oRequestManipulator->ReadParam('attachment_ids', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), 'formProperties' => $aFormProperties, - 'applyStimulus' => $this->oRequestManipulator->ReadParam('apply_stimulus', null), + 'applyStimulus' => $this->oRequestManipulator->ReadParam('apply_stimulus', null, FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), ) ); if ($aFormData['validation']['valid'] === true) @@ -337,7 +337,7 @@ class ObjectFormHandlerHelper break; case 'update': - $oFormManager->OnUpdate(array('currentValues' => $this->oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), 'formProperties' => $aFormProperties)); + $oFormManager->OnUpdate(array('currentValues' => $this->oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY), 'formProperties' => $aFormProperties)); break; case 'cancel': @@ -399,7 +399,7 @@ class ObjectFormHandlerHelper ApplicationContext::MakeObjectUrl($sObjectClass, $sObjectId) ); } - + return $aFormData; } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/RequestManipulatorHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/RequestManipulatorHelper.php index dbffde21d..c2756c8c4 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/RequestManipulatorHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/RequestManipulatorHelper.php @@ -90,26 +90,27 @@ class RequestManipulatorHelper * @param string $sKey * @param mixed $default * @param int $iFilter Default is FILTER_SANITIZE_SPECIAL_CHARS + * @param int $aFilterOptions @since 3.2.0 - N°6934 - Symfony 6.4 - upgrade Symfony bundles to 6.4 * * @return mixed|null * * @since 2.5.1 */ - public function ReadParam($sKey, $default = null, $iFilter = FILTER_SANITIZE_SPECIAL_CHARS) + public function ReadParam($sKey, $default = null, $iFilter = FILTER_SANITIZE_SPECIAL_CHARS, $aFilterOptions = []) { if ($this->GetCurrentRequest()->query->has($sKey)) { - return $this->GetCurrentRequest()->query->filter($sKey, $default, $iFilter); + return $this->GetCurrentRequest()->query->filter($sKey, $default, $iFilter, $aFilterOptions); } if ($this->GetCurrentRequest()->attributes->has($sKey)) { - return $this->GetCurrentRequest()->attributes->filter($sKey, $default, $iFilter); + return $this->GetCurrentRequest()->attributes->filter($sKey, $default, $iFilter, $aFilterOptions); } if ($this->GetCurrentRequest()->request->has($sKey)) { - return $this->GetCurrentRequest()->request->filter($sKey, $default, $iFilter); + return $this->GetCurrentRequest()->request->filter($sKey, $default, $iFilter, $aFilterOptions); } return $default; diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-portal-base/RequestManipulatorTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-portal-base/RequestManipulatorTest.php new file mode 100644 index 000000000..2a4fe4a12 --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-portal-base/RequestManipulatorTest.php @@ -0,0 +1,73 @@ + + * + */ + +namespace Combodo\iTop\Test\UnitTest\Module\iTopPortalBase; + +use Combodo\iTop\Portal\Helper\RequestManipulatorHelper; +use Combodo\iTop\Test\UnitTest\ItopTestCase; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; + +/** + * @covers \Combodo\iTop\Portal\Helper\RequestManipulatorHelper + */ +class RequestManipulatorTest extends ItopTestCase +{ + + protected function LoadRequiredItopFiles(): void + { + parent::LoadRequiredItopFiles(); + $this->RequireOnceItopFile('datamodels/2.x/itop-portal-base/portal/src/Helper/RequestManipulatorHelper.php'); + } + + public function testReadParam() + { + // Create a simple request with only necessary information + $oRequest = new Request(); + $aValue = ['a', 'b', 'c']; + $oRequest->request->set('array_value', $aValue); + + // Create a request stack + $oRequestStack = new RequestStack(); + $oRequestStack->push($oRequest); + + // Instantiate request manipulator helper service + $oRequestManipulatorHelper = new RequestManipulatorHelper($oRequestStack); + + // I - default null value + $oNullArrayValue = $oRequestManipulatorHelper->ReadParam('null_array_value', null, FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); + $this->assertNull($oNullArrayValue); + + // II - default empty array value + $oEmptyArrayValue = $oRequestManipulatorHelper->ReadParam('empty_array_value', [], FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); + $this->assertEmpty($oNullArrayValue); + + // III - since symfony 6.4, this code raised a bad request exception + $this->expectException("Symfony\\Component\\HttpFoundation\\Exception\\BadRequestException"); + $oRequestManipulatorHelper->ReadParam('array_value', null, FILTER_UNSAFE_RAW); + + // IV - control value + $aReadValue = $oRequestManipulatorHelper->ReadParam('array_value', null, FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY); + $this->assertEquals($aValue, $aReadValue); + } + + +}