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'], + ]; + } +}