diff --git a/src/Attachment.php b/src/Attachment.php index efae50ca..2fbde843 100755 --- a/src/Attachment.php +++ b/src/Attachment.php @@ -216,6 +216,10 @@ protected function fetch(): void { $this->filename = $this->decodeName($filename); } + if(!$this->filename){ + $this->filename = bin2hex(random_bytes(10)); + } + if (($name = $this->part->name) !== null) { $this->name = $this->decodeName($name); } @@ -233,11 +237,6 @@ protected function fetch(): void { $this->name = $this->part->subtype; } } - - if (!$this->filename) { - $this->filename = $this->name; - } - $this->attributes = array_merge($this->part->getHeader()->getAttributes(), $this->attributes); } @@ -248,19 +247,19 @@ protected function fetch(): void { * * @return boolean */ - public function save(string $path, string $filename = null): bool { - $filename = $filename ?? $this->filename ?? $this->name ?? $this->id; + public function save(string $path, ?string $filename = null): bool { + $filename = $filename ? $this->decodeName($filename) : $this->filename; return file_put_contents($path.DIRECTORY_SEPARATOR.$filename, $this->getContent()) !== false; } /** * Decode a given name - * @param $name + * @param string|null $name * * @return string */ - public function decodeName($name): string { + public function decodeName(?string $name): string { if ($name !== null) { if (str_contains($name, "''")) { $parts = explode("''", $name); @@ -282,6 +281,11 @@ public function decodeName($name): string { if (preg_match('/%[0-9A-F]{2}/i', $name)) { $name = urldecode($name); } + + // sanitize $name + // order of '..' is important + $name = str_replace(['\\', '/', chr(0), ':', '..'], '', $name); + return $name; } return ""; @@ -317,8 +321,8 @@ public function getExtension(): ?string { } } if ($extension === null) { - $extensions = explode(".", $this->filename); - $extension = end($extensions); + $parts = explode(".", $this->filename); + $extension = count($parts) > 1 ? end($parts) : null; } return $extension; } diff --git a/tests/fixtures/AttachmentNoDispositionTest.php b/tests/fixtures/AttachmentNoDispositionTest.php index cb037053..1eee597b 100644 --- a/tests/fixtures/AttachmentNoDispositionTest.php +++ b/tests/fixtures/AttachmentNoDispositionTest.php @@ -38,7 +38,7 @@ public function testFixture() : void { $attachment = $message->attachments()->first(); self::assertInstanceOf(Attachment::class, $attachment); - self::assertEquals("Prostřeno_2014_poslední volné termíny.xls", $attachment->filename); + self::assertMatchesRegularExpression('/^[a-z0-9]{20}$/', $attachment->filename); self::assertEquals("Prostřeno_2014_poslední volné termíny.xls", $attachment->name); self::assertEquals('text', $attachment->type); self::assertEquals('xls', $attachment->getExtension()); diff --git a/tests/fixtures/EmbeddedEmailWithoutContentDispositionTest.php b/tests/fixtures/EmbeddedEmailWithoutContentDispositionTest.php index 0c7e53cb..0f6a8a3f 100644 --- a/tests/fixtures/EmbeddedEmailWithoutContentDispositionTest.php +++ b/tests/fixtures/EmbeddedEmailWithoutContentDispositionTest.php @@ -61,7 +61,7 @@ public function testFixture() : void { $attachment = $attachments[1]; self::assertInstanceOf(Attachment::class, $attachment); - self::assertEquals("", $attachment->name); + self::assertMatchesRegularExpression('/^[a-z0-9]{20}$/', $attachment->name); self::assertEquals('text', $attachment->type); self::assertEquals('', $attachment->getExtension()); self::assertEquals("message/rfc822", $attachment->content_type); diff --git a/tests/fixtures/ExampleBounceTest.php b/tests/fixtures/ExampleBounceTest.php index 89810fc0..685a72cf 100644 --- a/tests/fixtures/ExampleBounceTest.php +++ b/tests/fixtures/ExampleBounceTest.php @@ -72,7 +72,7 @@ public function testFixture(): void { $attachment = $attachments[0]; self::assertInstanceOf(Attachment::class, $attachment); - self::assertEquals("", $attachment->filename); + self::assertMatchesRegularExpression('/^[a-z0-9]{20}$/', $attachment->filename); self::assertEquals("", $attachment->name); self::assertEquals('', $attachment->getExtension()); self::assertEquals('text', $attachment->type); diff --git a/tests/fixtures/InlineAttachmentTest.php b/tests/fixtures/InlineAttachmentTest.php index c20ac8d5..b66976ef 100644 --- a/tests/fixtures/InlineAttachmentTest.php +++ b/tests/fixtures/InlineAttachmentTest.php @@ -45,7 +45,7 @@ public function testFixture() : void { $attachment = $attachments[0]; self::assertInstanceOf(Attachment::class, $attachment); - self::assertEquals("", $attachment->name); + self::assertMatchesRegularExpression('/^[a-z0-9]{20}$/', $attachment->name); self::assertEquals('text', $attachment->type); self::assertEquals('', $attachment->getExtension()); self::assertEquals("image/png", $attachment->content_type);