8000 [Mime] fixed support for date form parts · symfony/symfony@4507cf5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4507cf5

Browse files
committed
[Mime] fixed support for date form parts
1 parent 5b38e17 commit 4507cf5

File tree

4 files changed

+81
-13
lines changed

4 files changed

+81
-13
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Mime\Encoder;
13+
14+
/**
15+
* @author Fabien Potencier <fabien@symfony.com>
16+
*
17+
* @experimental in 4.3
18+
*/
19+
final class EightBitContentEncoder implements ContentEncoderInterface
20+
{
21+
public function encodeByteStream($stream, int $maxLineLength = 0): iterable
22+
{
23+
yield from $stream;
24+
}
25+
26+
public function getName(): string
27+
{
28+
return '8bit';
29+
}
30+
31+
public function encodeString(string $string, ?string $charset = 'utf-8', int $firstLineOffset = 0, int $maxLineLength = 0): string
32+
{
33+
return $string;
34+
}
35+
}

src/Symfony/Component/Mime/Part/Multipart/FormDataPart.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function __construct(array $fields = [])
4242
$this->fields[$name] = $value;
4343
}
4444
// HTTP does not support \r\n in header values
45-
$this->getHeaders()->setMaxLineLength(1000);
45+
$this->getHeaders()->setMaxLineLength(-1);
4646
}
4747

4848
public function getMediaSubtype(): string
@@ -74,18 +74,26 @@ private function prepareFields(array $fields): array
7474
private function preparePart($name, 8000 $value): TextPart
7575
{
7676
if (\is_string($value)) {
77-
return $this->configurePart($name, new TextPart($value));
77+
return $this->configurePart($name, new TextPart($value, 'utf-8', 'plain', '8bit'));
7878
}
7979

8080
return $this->configurePart($name, $value);
8181
}
8282

8383
private function configurePart(string $name, TextPart $part): TextPart
8484
{
85+
static $r;
86+
87+
if (null === $r) {
88+
$r = new \ReflectionProperty(TextPart::class, 'encoding');
89+
$r->setAccessible(true);
90+
}
91+
8592
$part->setDisposition('form-data');
8693
$part->setName($name);
8794
// HTTP does not support \r\n in header values
88-
$part->getHeaders()->setMaxLineLength(1000);
95+
$part->getHeaders()->setMaxLineLength(-1);
96+
$r->setValue($part, '8bit');
8997

9098
return $part;
9199
}

src/Symfony/Component/Mime/Part/TextPart.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Mime\Encoder\Base64ContentEncoder;
1515
use Symfony\Component\Mime\Encoder\ContentEncoderInterface;
16+
use Symfony\Component\Mime\Encoder\EightBitContentEncoder;
1617
use Symfony\Component\Mime\Encoder\QpContentEncoder;
1718
use Symfony\Component\Mime\Exception\InvalidArgumentException;
1819
use Symfony\Component\Mime\Header\Headers;
@@ -31,8 +32,7 @@ class TextPart extends AbstractPart
3132
private $subtype;
3233
private $disposition;
3334
private $name;
34-
35-
protected $encoding;
35+
private $encoding;
3636

3737
/**
3838
* @param resource|string $body
@@ -49,12 +49,11 @@ public function __construct($body, ?string $charset = 'utf-8', $subtype = 'plain
4949
$this->charset = $charset;
5050
$this->subtype = $subtype;
5151

52-
// FIXME: can also be 7BIT, 8BIT, ...
5352
if (null === $encoding) {
5453
$this->encoding = $this->chooseEncoding();
5554
} else {
56-
if ('quoted-printable' !== $encoding && 'base64' !== $encoding) {
57-
throw new InvalidArgumentException(sprintf('The encoding must be one of "quoted-printable" or "base64" ("%s" given).', $encoding));
55+
if ('quoted-printable' !== $encoding && 'base64' !== $encoding && '8bit' !== $encoding) {
56+
throw new InvalidArgumentException(sprintf('The encoding must be one of "quoted-printable", "base64", or "8bit" ("%s" given).', $encoding));
5857
}
5958
$this->encoding = $encoding;
6059
}
@@ -149,8 +148,12 @@ public function getPreparedHeaders(): Headers
149148
return $headers;
150149
}
151150

152-
protected function getEncoder(): ContentEncoderInterface
151+
private function getEncoder(): ContentEncoderInterface
153152
{
153+
if ('8bit' === $this->encoding) {
154+
return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new EightBitContentEncoder());
155+
}
156+
154157
if ('quoted-printable' === $this->encoding) {
155158
return self::$encoders[$this->encoding] ?? (self::$encoders[$this->encoding] = new QpContentEncoder());
156159
}

src/Symfony/Component/Mime/Tests/Part/Multipart/FormDataPartTest.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class FormDataPartTest extends TestCase
2020
{
2121
public function testConstructor()
2222
{
23+
$r = new \ReflectionProperty(TextPart::class, 'encoding');
24+
$r->setAccessible(true);
25+
2326
$b = new TextPart('content');
2427
$c = DataPart::fromPath($file = __DIR__.'/../../Fixtures/mimetypes/test.gif');
2528
$f = new FormDataPart([
@@ -29,16 +32,35 @@ public function testConstructor()
2932
]);
3033
$this->assertEquals('multipart', $f->getMediaType());
3134
$this->assertEquals('form-data', $f->getMediaSubtype());
32-
$t = new TextPart($content);
35+
$t = new TextPart($content, 'utf-8', 'plain', '8bit');
3336
$t->setDisposition('form-data');
3437
$t->setName('foo');
35-
$t->getHeaders()->setMaxLineLength(1000);
38+
$t->getHeaders()->setMaxLineLength(-1);
3639
$b->setDisposition('form-data');
3740
$b->setName('bar');
38-
$b->getHeaders()->setMaxLineLength(1000);
41+
$b->getHeaders()->setMaxLineLength(-1);
42+
$r->setValue($b, '8bit');
3943
$c->setDisposition('form-data');
4044
$c->setName('baz');
41-
$c->getHeaders()->setMaxLineLength(1000);
45+
$c->getHeaders()->setMaxLineLength(-1);
46+
$r->setValue($c, '8bit');
4247
$this->assertEquals([$t, $b, $c], $f->getParts());
4348
}
49+
50+
public function testToString()
51+
{
52+
$p = DataPart::fromPath($file = __DIR__.'/../../Fixtures/mimetypes/test.gif');
53+
$this->assertEquals(base64_encode(file_get_contents($file)), $p->bodyToString());
54+
}
55+
56+
public function testContentLineLength()
57+
{
58+
$f = new FormDataPart([
59+
'foo' => new DataPart($foo = str_repeat('foo', 1000), 'foo.txt', 'text/plain'),
60+
'bar' => $bar = str_repeat('bar', 1000),
61+
]);
62+
$parts = $f->getParts();
63+
$this->assertEquals($foo, $parts[0]->bodyToString());
64+
$this->assertEquals($bar, $parts[1]->bodyToString());
65+
}
4466
}

0 commit comments

Comments
 (0)
0