diff --git a/src/Services/InfoProviderSystem/DTOs/FileDTO.php b/src/Services/InfoProviderSystem/DTOs/FileDTO.php index 516ab949..d5ba7fe2 100644 --- a/src/Services/InfoProviderSystem/DTOs/FileDTO.php +++ b/src/Services/InfoProviderSystem/DTOs/FileDTO.php @@ -29,14 +29,24 @@ namespace App\Services\InfoProviderSystem\DTOs; */ class FileDTO { + /** + * @var string The URL where to get this file + */ + public readonly string $url; + /** * @param string $url The URL where to get this file * @param string|null $name Optionally the name of this file */ public function __construct( - public readonly string $url, + string $url, public readonly ?string $name = null, - ) {} + ) { + //Find all occurrences of non URL safe characters and replace them with their URL encoded version. + //We only want to replace characters which can not have a valid meaning in a URL (what would break the URL). + //Digikey provided some wrong URLs with a ^ in them, which is not a valid URL character. (https://github.com/Part-DB/Part-DB-server/issues/521) + $this->url = preg_replace_callback('/[^a-zA-Z0-9_\-.$+!*();\/?:@=&#%]/', fn($matches) => urlencode($matches[0]), $url); + } } \ No newline at end of file diff --git a/tests/Services/InfoProviderSystem/DTOs/FileDTOTest.php b/tests/Services/InfoProviderSystem/DTOs/FileDTOTest.php new file mode 100644 index 00000000..3f0deafd --- /dev/null +++ b/tests/Services/InfoProviderSystem/DTOs/FileDTOTest.php @@ -0,0 +1,52 @@ +. + */ + +namespace App\Tests\Services\InfoProviderSystem\DTOs; + +use App\Services\InfoProviderSystem\DTOs\FileDTO; +use PHPUnit\Framework\TestCase; + +class FileDTOTest extends TestCase +{ + + + public static function escapingDataProvider(): array + { + return [ + //Normal URLs must be unchanged, even if they contain special characters + ["https://localhost:8000/en/part/1335/edit#attachments", "https://localhost:8000/en/part/1335/edit#attachments"], + ["https://localhost:8000/en/part/1335/edit?test=%20%20&sfee_aswer=test-223!*()", "https://localhost:8000/en/part/1335/edit?test=%20%20&sfee_aswer=test-223!*()"], + + //Remaining URL unsafe characters must be escaped + ["test%5Ese", "test^se"], + ["test+se", "test se"], + ["test%7Cse", "test|se"], + ]; + } + + /** + * @dataProvider escapingDataProvider + */ + public function testURLEscaping(string $expected, string $input): void + { + $fileDTO = new FileDTO( $input); + self::assertSame($expected, $fileDTO->url); + } +}