| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 | 
							- <?php
 
- /*
 
-  * This file is part of the Symfony package.
 
-  *
 
-  * (c) Fabien Potencier <fabien@symfony.com>
 
-  *
 
-  * For the full copyright and license information, please view the LICENSE
 
-  * file that was distributed with this source code.
 
-  */
 
- namespace Symfony\Component\Mime\Header;
 
- use Symfony\Component\Mime\Encoder\Rfc2231Encoder;
 
- /**
 
-  * @author Chris Corbyn
 
-  */
 
- final class ParameterizedHeader extends UnstructuredHeader
 
- {
 
-     /**
 
-      * RFC 2231's definition of a token.
 
-      *
 
-      * @var string
 
-      */
 
-     public const TOKEN_REGEX = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)';
 
-     private $encoder;
 
-     private $parameters = [];
 
-     public function __construct(string $name, string $value, array $parameters = [])
 
-     {
 
-         parent::__construct($name, $value);
 
-         foreach ($parameters as $k => $v) {
 
-             $this->setParameter($k, $v);
 
-         }
 
-         if ('content-type' !== strtolower($name)) {
 
-             $this->encoder = new Rfc2231Encoder();
 
-         }
 
-     }
 
-     public function setParameter(string $parameter, ?string $value)
 
-     {
 
-         $this->setParameters(array_merge($this->getParameters(), [$parameter => $value]));
 
-     }
 
-     public function getParameter(string $parameter): string
 
-     {
 
-         return $this->getParameters()[$parameter] ?? '';
 
-     }
 
-     /**
 
-      * @param string[] $parameters
 
-      */
 
-     public function setParameters(array $parameters)
 
-     {
 
-         $this->parameters = $parameters;
 
-     }
 
-     /**
 
-      * @return string[]
 
-      */
 
-     public function getParameters(): array
 
-     {
 
-         return $this->parameters;
 
-     }
 
-     public function getBodyAsString(): string
 
-     {
 
-         $body = parent::getBodyAsString();
 
-         foreach ($this->parameters as $name => $value) {
 
-             if (null !== $value) {
 
-                 $body .= '; '.$this->createParameter($name, $value);
 
-             }
 
-         }
 
-         return $body;
 
-     }
 
-     /**
 
-      * Generate a list of all tokens in the final header.
 
-      *
 
-      * This doesn't need to be overridden in theory, but it is for implementation
 
-      * reasons to prevent potential breakage of attributes.
 
-      */
 
-     protected function toTokens(?string $string = null): array
 
-     {
 
-         $tokens = parent::toTokens(parent::getBodyAsString());
 
-         // Try creating any parameters
 
-         foreach ($this->parameters as $name => $value) {
 
-             if (null !== $value) {
 
-                 // Add the semi-colon separator
 
-                 $tokens[\count($tokens) - 1] .= ';';
 
-                 $tokens = array_merge($tokens, $this->generateTokenLines(' '.$this->createParameter($name, $value)));
 
-             }
 
-         }
 
-         return $tokens;
 
-     }
 
-     /**
 
-      * Render an RFC 2047 compliant header parameter from the $name and $value.
 
-      */
 
-     private function createParameter(string $name, string $value): string
 
-     {
 
-         $origValue = $value;
 
-         $encoded = false;
 
-         // Allow room for parameter name, indices, "=" and DQUOTEs
 
-         $maxValueLength = $this->getMaxLineLength() - \strlen($name.'=*N"";') - 1;
 
-         $firstLineOffset = 0;
 
-         // If it's not already a valid parameter value...
 
-         if (!preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) {
 
-             // TODO: text, or something else??
 
-             // ... and it's not ascii
 
-             if (!preg_match('/^[\x00-\x08\x0B\x0C\x0E-\x7F]*$/D', $value)) {
 
-                 $encoded = true;
 
-                 // Allow space for the indices, charset and language
 
-                 $maxValueLength = $this->getMaxLineLength() - \strlen($name.'*N*="";') - 1;
 
-                 $firstLineOffset = \strlen($this->getCharset()."'".$this->getLanguage()."'");
 
-             }
 
-             if (\in_array($name, ['name', 'filename'], true) && 'form-data' === $this->getValue() && 'content-disposition' === strtolower($this->getName()) && preg_match('//u', $value)) {
 
-                 // WHATWG HTML living standard 4.10.21.8 2 specifies:
 
-                 // For field names and filenames for file fields, the result of the
 
-                 // encoding in the previous bullet point must be escaped by replacing
 
-                 // any 0x0A (LF) bytes with the byte sequence `%0A`, 0x0D (CR) with `%0D`
 
-                 // and 0x22 (") with `%22`.
 
-                 // The user agent must not perform any other escapes.
 
-                 $value = str_replace(['"', "\r", "\n"], ['%22', '%0D', '%0A'], $value);
 
-                 if (\strlen($value) <= $maxValueLength) {
 
-                     return $name.'="'.$value.'"';
 
-                 }
 
-                 $value = $origValue;
 
-             }
 
-         }
 
-         // Encode if we need to
 
-         if ($encoded || \strlen($value) > $maxValueLength) {
 
-             if (null !== $this->encoder) {
 
-                 $value = $this->encoder->encodeString($origValue, $this->getCharset(), $firstLineOffset, $maxValueLength);
 
-             } else {
 
-                 // We have to go against RFC 2183/2231 in some areas for interoperability
 
-                 $value = $this->getTokenAsEncodedWord($origValue);
 
-                 $encoded = false;
 
-             }
 
-         }
 
-         $valueLines = $this->encoder ? explode("\r\n", $value) : [$value];
 
-         // Need to add indices
 
-         if (\count($valueLines) > 1) {
 
-             $paramLines = [];
 
-             foreach ($valueLines as $i => $line) {
 
-                 $paramLines[] = $name.'*'.$i.$this->getEndOfParameterValue($line, true, 0 === $i);
 
-             }
 
-             return implode(";\r\n ", $paramLines);
 
-         } else {
 
-             return $name.$this->getEndOfParameterValue($valueLines[0], $encoded, true);
 
-         }
 
-     }
 
-     /**
 
-      * Returns the parameter value from the "=" and beyond.
 
-      *
 
-      * @param string $value to append
 
-      */
 
-     private function getEndOfParameterValue(string $value, bool $encoded = false, bool $firstLine = false): string
 
-     {
 
-         $forceHttpQuoting = 'form-data' === $this->getValue() && 'content-disposition' === strtolower($this->getName());
 
-         if ($forceHttpQuoting || !preg_match('/^'.self::TOKEN_REGEX.'$/D', $value)) {
 
-             $value = '"'.$value.'"';
 
-         }
 
-         $prepend = '=';
 
-         if ($encoded) {
 
-             $prepend = '*=';
 
-             if ($firstLine) {
 
-                 $prepend = '*='.$this->getCharset()."'".$this->getLanguage()."'";
 
-             }
 
-         }
 
-         return $prepend.$value;
 
-     }
 
- }
 
 
  |