Skip to content

Commit

Permalink
minor #35933 [Mime] strengthen is_resource() checks (nicolas-grekas)
Browse files Browse the repository at this point in the history
This PR was merged into the 5.1-dev branch.

Discussion
----------

[Mime] strengthen is_resource() checks

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

Improves seekable checks by using
`stream_get_meta_data($h)['seekable'] && 0 === fseek($h, 0, SEEK_CUR)`
instead of just
`stream_get_meta_data($h)['seekable']`

which is better when using userland stream wrappers.

Commits
-------

be9c675 [Mime] strengthen is_resource() checks
  • Loading branch information
fabpot committed Apr 5, 2020
2 parents a165ecc + be9c675 commit 6f57fcf
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 39 deletions.
5 changes: 1 addition & 4 deletions src/Symfony/Component/Mime/CharacterStream.php
Expand Up @@ -97,10 +97,7 @@ public function __construct($input, ?string $charset = 'utf-8')
}
}
if (\is_resource($input)) {
$blocks = 512;
if (stream_get_meta_data($input)['seekable'] ?? false) {
rewind($input);
}
$blocks = 16372;
while (false !== $read = fread($input, $blocks)) {
$this->write($read);
}
Expand Down
26 changes: 4 additions & 22 deletions src/Symfony/Component/Mime/Email.php
Expand Up @@ -464,14 +464,8 @@ private function prepareParts(): ?array
$htmlPart = null;
$html = $this->html;
if (null !== $this->html) {
if (\is_resource($html)) {
if (stream_get_meta_data($html)['seekable'] ?? false) {
rewind($html);
}

$html = stream_get_contents($html);
}
$htmlPart = new TextPart($html, $this->htmlCharset, 'html');
$html = $htmlPart->getBody();
preg_match_all('(<img\s+[^>]*src\s*=\s*(?:([\'"])cid:([^"]+)\\1|cid:([^>\s]+)))i', $html, $names);
$names = array_filter(array_unique(array_merge($names[2], $names[3])));
}
Expand Down Expand Up @@ -559,28 +553,16 @@ private function setListAddressHeaderBody(string $name, array $addresses)
public function __serialize(): array
{
if (\is_resource($this->text)) {
if (stream_get_meta_data($this->text)['seekable'] ?? false) {
rewind($this->text);
}

$this->text = stream_get_contents($this->text);
$this->text = (new TextPart($this->text))->getBody();
}

if (\is_resource($this->html)) {
if (stream_get_meta_data($this->html)['seekable'] ?? false) {
rewind($this->html);
}

$this->html = stream_get_contents($this->html);
$this->html = (new TextPart($this->html))->getBody();
}

foreach ($this->attachments as $i => $attachment) {
if (isset($attachment['body']) && \is_resource($attachment['body'])) {
if (stream_get_meta_data($attachment['body'])['seekable'] ?? false) {
rewind($attachment['body']);
}

$this->attachments[$i]['body'] = stream_get_contents($attachment['body']);
$this->attachments[$i]['body'] = (new TextPart($attachment['body']))->getBody();
}
}

Expand Down
5 changes: 1 addition & 4 deletions src/Symfony/Component/Mime/Encoder/Base64ContentEncoder.php
Expand Up @@ -32,11 +32,8 @@ public function encodeByteStream($stream, int $maxLineLength = 0): iterable
throw new RuntimeException('Unable to set the base64 content encoder to the filter.');
}

if (stream_get_meta_data($stream)['seekable'] ?? false) {
rewind($stream);
}
while (!feof($stream)) {
yield fread($stream, 8192);
yield fread($stream, 16372);
}
stream_filter_remove($filter);
}
Expand Down
4 changes: 0 additions & 4 deletions src/Symfony/Component/Mime/Encoder/QpContentEncoder.php
Expand Up @@ -23,10 +23,6 @@ public function encodeByteStream($stream, int $maxLineLength = 0): iterable
}

// we don't use PHP stream filters here as the content should be small enough
if (stream_get_meta_data($stream)['seekable'] ?? false) {
rewind($stream);
}

yield $this->encodeString(stream_get_contents($stream), 'utf-8', 0, $maxLineLength);
}

Expand Down
12 changes: 7 additions & 5 deletions src/Symfony/Component/Mime/Part/TextPart.php
Expand Up @@ -31,6 +31,7 @@ class TextPart extends AbstractPart
private $disposition;
private $name;
private $encoding;
private $seekable;

/**
* @param resource|string $body
Expand All @@ -46,6 +47,7 @@ public function __construct($body, ?string $charset = 'utf-8', $subtype = 'plain
$this->body = $body;
$this->charset = $charset;
$this->subtype = $subtype;
$this->seekable = \is_resource($body) ? stream_get_meta_data($body)['seekable'] && 0 === fseek($body, 0, SEEK_CUR) : null;

if (null === $encoding) {
$this->encoding = $this->chooseEncoding();
Expand Down Expand Up @@ -93,11 +95,11 @@ public function setName($name)

public function getBody(): string
{
if (!\is_resource($this->body)) {
if (null === $this->seekable) {
return $this->body;
}

if (stream_get_meta_data($this->body)['seekable'] ?? false) {
if ($this->seekable) {
rewind($this->body);
}

Expand All @@ -111,8 +113,8 @@ public function bodyToString(): string

public function bodyToIterable(): iterable
{
if (\is_resource($this->body)) {
if (stream_get_meta_data($this->body)['seekable'] ?? false) {
if (null !== $this->seekable) {
if ($this->seekable) {
rewind($this->body);
}
yield from $this->getEncoder()->encodeByteStream($this->body);
Expand Down Expand Up @@ -185,7 +187,7 @@ private function chooseEncoding(): string
public function __sleep()
{
// convert resources to strings for serialization
if (\is_resource($this->body)) {
if (null !== $this->seekable) {
$this->body = $this->getBody();
}

Expand Down

0 comments on commit 6f57fcf

Please sign in to comment.