From a3be803bf8f42adbd4d7458e44d7cf5920495e48 Mon Sep 17 00:00:00 2001 From: Turkin Maksim Date: Fri, 14 Jun 2024 22:16:21 +0300 Subject: [PATCH] Fix: Attachment::decodeName remove .. from file name If attached file has name like test..xml, then dots remove and broke file extension. --- src/Attachment.php | 7 ++++++- tests/AttachmentTest.php | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 tests/AttachmentTest.php diff --git a/src/Attachment.php b/src/Attachment.php index 451dfe2..2720df0 100755 --- a/src/Attachment.php +++ b/src/Attachment.php @@ -314,7 +314,12 @@ public function decodeName(?string $name): string { // sanitize $name // order of '..' is important - return str_replace(['\\', '/', chr(0), ':', '..'], '', $name); + $replaces = [ + '/\\\\/' => '', + '/[\/\0:]+/' => '', + '/\.+/' => '.', + ]; + return preg_replace(array_keys($replaces), array_values($replaces), $name); } return ""; } diff --git a/tests/AttachmentTest.php b/tests/AttachmentTest.php new file mode 100644 index 0000000..566ea65 --- /dev/null +++ b/tests/AttachmentTest.php @@ -0,0 +1,37 @@ +getFixture("attachment_encoded_filename.eml"); + $this->attachment = $message->getAttachments()->first(); + } + /** + * @dataProvider decodeNameDataProvider + */ + public function testDecodeName(string $input, string $output): void + { + $name = $this->attachment->decodeName($input); + $this->assertEquals($output, $name); + } + + public function decodeNameDataProvider(): array + { + return [ + ['../../../../../../../../../../../var/www/shell.php', '.varwwwshell.php'], + ['test..xml', 'test.xml'], + [chr(0), ''], + ['C:\\file.txt', 'Cfile.txt'], + ]; + } +}