all(); \array_walk($inputs, function (mixed &$input, int | string $name) use ($params): void { $this->cleanInput($input, (string) $name, null, $params); }); $request->merge($inputs); return $next($request); } /** * @param string[] $params */ private function cleanInput(mixed &$input, string $name, ?string $rootName, array $params): void { if (is_array($input)) { array_walk_recursive($input, function (mixed &$nestedInput, int | string $nestedName) use ($name, $params): void { $this->cleanInput($nestedInput, (string) $nestedName, $name, $params); }); } if (! is_string($input)) { return; } if ($this->shouldApplyRichSanitization($name, $rootName, $params)) { $this->sanitizeRichInput($input); return; } $input = strip_tags($input); } /** * @param string[] $params */ private function shouldApplyRichSanitization(string $name, ?string $rootName, array $params): bool { return in_array($name, $params) || in_array($rootName ?? $name, $params); } private function sanitizeRichInput(string &$input): void { $isJson = \json_decode($input, true); if ($isJson && is_array($isJson)) { \array_walk_recursive($isJson, function (string | array &$item): void { if (\is_string($item)) { $item = $this->purifyString($item); } }); $input = json_encode($isJson, \JSON_THROW_ON_ERROR) ?: throw new \UnexpectedValueException('Failed to encode JSON after sanitization.'); return; } $input = $this->purifyString($input); } private function purifyString(string $input): string { $cleaned = $this->purifierService->clean($input); if (! is_string($cleaned)) { throw new \UnexpectedValueException('Purifier should return a string when input is a string.'); } return ToolboxHelper::stripCkEditorSchemesOnMediaInputs($cleaned); } }