},
{
"name": "guzzlehttp/psr7",
- "version": "2.2.1",
+ "version": "2.2.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2"
+ "reference": "a119247127ff95789a2d95c347cd74721fbedaa4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/c94a94f120803a18554c1805ef2e539f8285f9a2",
- "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/a119247127ff95789a2d95c347cd74721fbedaa4",
+ "reference": "a119247127ff95789a2d95c347cd74721fbedaa4",
"shasum": ""
},
"require": {
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/2.2.1"
+ "source": "https://github.com/guzzle/psr7/tree/2.2.2"
},
"funding": [
{
"type": "tidelift"
}
],
- "time": "2022-03-20T21:55:58+00:00"
+ "time": "2022-06-08T19:55:23+00:00"
},
{
"name": "laminas/laminas-diactoros",
},
{
"name": "laminas/laminas-stdlib",
- "version": "3.7.1",
+ "version": "3.9.1",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-stdlib.git",
- "reference": "bcd869e2fe88d567800057c1434f2380354fe325"
+ "reference": "1df1cc0b9c2b8c7d1e322da1669a576386b5da46"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/bcd869e2fe88d567800057c1434f2380354fe325",
- "reference": "bcd869e2fe88d567800057c1434f2380354fe325",
+ "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/1df1cc0b9c2b8c7d1e322da1669a576386b5da46",
+ "reference": "1df1cc0b9c2b8c7d1e322da1669a576386b5da46",
"shasum": ""
},
"require": {
"type": "community_bridge"
}
],
- "time": "2022-01-21T15:50:46+00:00"
+ "time": "2022-06-08T11:33:13+00:00"
},
{
"name": "paragonie/constant_time_encoding",
},
{
"name": "guzzlehttp/psr7",
- "version": "2.2.1",
- "version_normalized": "2.2.1.0",
+ "version": "2.2.2",
+ "version_normalized": "2.2.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2"
+ "reference": "a119247127ff95789a2d95c347cd74721fbedaa4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/c94a94f120803a18554c1805ef2e539f8285f9a2",
- "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/a119247127ff95789a2d95c347cd74721fbedaa4",
+ "reference": "a119247127ff95789a2d95c347cd74721fbedaa4",
"shasum": ""
},
"require": {
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
- "time": "2022-03-20T21:55:58+00:00",
+ "time": "2022-06-08T19:55:23+00:00",
"type": "library",
"extra": {
"branch-alias": {
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/2.2.1"
+ "source": "https://github.com/guzzle/psr7/tree/2.2.2"
},
"funding": [
{
},
{
"name": "laminas/laminas-stdlib",
- "version": "3.7.1",
- "version_normalized": "3.7.1.0",
+ "version": "3.9.1",
+ "version_normalized": "3.9.1.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-stdlib.git",
- "reference": "bcd869e2fe88d567800057c1434f2380354fe325"
+ "reference": "1df1cc0b9c2b8c7d1e322da1669a576386b5da46"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/bcd869e2fe88d567800057c1434f2380354fe325",
- "reference": "bcd869e2fe88d567800057c1434f2380354fe325",
+ "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/1df1cc0b9c2b8c7d1e322da1669a576386b5da46",
+ "reference": "1df1cc0b9c2b8c7d1e322da1669a576386b5da46",
"shasum": ""
},
"require": {
"psalm/plugin-phpunit": "^0.16.0",
"vimeo/psalm": "^4.7"
},
- "time": "2022-01-21T15:50:46+00:00",
+ "time": "2022-06-08T11:33:13+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"install-path": "../symfony/polyfill-php82"
}
],
- "dev": true,
+ "dev": false,
"dev-package-names": []
}
'aliases' => array(),
'reference' => NULL,
'name' => '__root__',
- 'dev' => true,
+ 'dev' => false,
),
'versions' => array(
'__root__' => array(
'dev_requirement' => false,
),
'guzzlehttp/psr7' => array(
- 'pretty_version' => '2.2.1',
- 'version' => '2.2.1.0',
+ 'pretty_version' => '2.2.2',
+ 'version' => '2.2.2.0',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
'aliases' => array(),
- 'reference' => 'c94a94f120803a18554c1805ef2e539f8285f9a2',
+ 'reference' => 'a119247127ff95789a2d95c347cd74721fbedaa4',
'dev_requirement' => false,
),
'laminas/laminas-diactoros' => array(
'dev_requirement' => false,
),
'laminas/laminas-stdlib' => array(
- 'pretty_version' => '3.7.1',
- 'version' => '3.7.1.0',
+ 'pretty_version' => '3.9.1',
+ 'version' => '3.9.1.0',
'type' => 'library',
'install_path' => __DIR__ . '/../laminas/laminas-stdlib',
'aliases' => array(),
- 'reference' => 'bcd869e2fe88d567800057c1434f2380354fe325',
+ 'reference' => '1df1cc0b9c2b8c7d1e322da1669a576386b5da46',
'dev_requirement' => false,
),
'paragonie/constant_time_encoding' => array(
## Unreleased
+## 2.2.2 - 2022-06-08
+
+### Fixed
+
+- Fix `Message::parseRequestUri()` for numeric headers
+- Re-wrap exceptions thrown in `fread` into runtime exceptions
+- Throw an exception when multipart options is misformatted
+
## 2.2.1 - 2022-03-20
### Fixed
This of course assumes they will be resolved against the same base URI. If this is not the case, determination of
equivalence or difference of relative references does not mean anything.
+## Version Guidance
+
+| Version | Status | PHP Version |
+|---------|----------------|------------------|
+| 1.x | Security fixes | >= 5.4, < 8.2 |
+| 2.x | Latest | ^7.2.5 \|\| ^8.0 |
## Security
"bamarni/composer-bin-plugin": true
},
"preferred-install": "dist",
- "sort-packages": true,
- "allow-plugins": {
- "bamarni/composer-bin-plugin": true
- }
+ "sort-packages": true
}
}
public static function parseRequestUri(string $path, array $headers): string
{
$hostKey = array_filter(array_keys($headers), function ($k) {
+ // Numeric array keys are converted to int by PHP.
+ $k = (string) $k;
+
return strtolower($k) === 'host';
});
{
$this->headerNames = $this->headers = [];
foreach ($headers as $header => $value) {
- if (is_int($header)) {
- // Numeric array keys are converted to int by PHP but having a header name '123' is not forbidden by the spec
- // and also allowed in withHeader(). So we need to cast it to string again for the following assertion to pass.
- $header = (string) $header;
- }
+ // Numeric array keys are converted to int by PHP.
+ $header = (string) $header;
+
$this->assertHeader($header);
$value = $this->normalizeHeaderValue($value);
$normalized = strtolower($header);
$stream = new AppendStream();
foreach ($elements as $element) {
+ if (!is_array($element)) {
+ throw new \UnexpectedValueException("An array is expected");
+ }
$this->addElement($stream, $element);
}
return '';
}
- $string = fread($this->stream, $length);
+ try {
+ $string = fread($this->stream, $length);
+ } catch (\Exception $e) {
+ throw new \RuntimeException('Unable to read from stream', 0, $e);
+ }
+
if (false === $string) {
throw new \RuntimeException('Unable to read from stream');
}
[![Build Status](https://github.com/laminas/laminas-stdlib/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/laminas/laminas-stdlib/actions/workflows/continuous-integration.yml)
[![Coverage Status](https://coveralls.io/repos/github/laminas/laminas-stdlib/badge.svg?branch=master)](https://coveralls.io/github/laminas/laminas-stdlib?branch=master)
+> ## 🇷🇺 Русским гражданам
+>
+> Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм.
+>
+> У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую.
+>
+> Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!"
+>
+> ## 🇺🇸 To Citizens of Russia
+>
+> We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism.
+>
+> One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences.
+>
+> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!"
+
`Laminas\Stdlib` is a set of components that implements general purpose utility
class for different scopes like:
<code>(int) $priority</code>
</RedundantCastGivenDocblockType>
</file>
- <file src="src/PriorityQueue.php">
- <DocblockTypeContradiction occurrences="1">
- <code>null === $this->queue</code>
- </DocblockTypeContradiction>
- <InvalidStringClass occurrences="1">
- <code>new $this->queueClass()</code>
- </InvalidStringClass>
- <LessSpecificReturnStatement occurrences="1">
- <code>$this->queue</code>
- </LessSpecificReturnStatement>
- <MissingClosureReturnType occurrences="2">
- <code>function ($item) {</code>
- <code>function ($item) {</code>
- </MissingClosureReturnType>
- <MissingConstructor occurrences="1">
- <code>$queue</code>
- </MissingConstructor>
- <MixedArgument occurrences="1">
- <code>$item['priority']</code>
- </MixedArgument>
- <MixedArrayAccess occurrences="13">
- <code>$item['data']</code>
- <code>$item['data']</code>
- <code>$item['data']</code>
- <code>$item['data']</code>
- <code>$item['data']</code>
- <code>$item['data']</code>
- <code>$item['priority']</code>
- <code>$item['priority']</code>
- <code>$item['priority']</code>
- <code>$item['priority']</code>
- <code>$item['priority']</code>
- <code>$item['priority']</code>
- <code>$item['priority']</code>
- </MixedArrayAccess>
- <MixedArrayOffset occurrences="1">
- <code>$this->items[$key]</code>
- </MixedArrayOffset>
- <MixedAssignment occurrences="9">
- <code>$highestPriority</code>
- <code>$highestPriority</code>
- <code>$item</code>
- <code>$item</code>
- <code>$item</code>
- <code>$item</code>
- <code>$item</code>
- <code>$item</code>
- <code>$value</code>
- </MixedAssignment>
- <MoreSpecificReturnType occurrences="1">
- <code>SplPriorityQueue</code>
- </MoreSpecificReturnType>
- <PossiblyNullPropertyAssignmentValue occurrences="1">
- <code>null</code>
- </PossiblyNullPropertyAssignmentValue>
- <PossiblyUndefinedVariable occurrences="1">
- <code>$key</code>
- </PossiblyUndefinedVariable>
- <PropertyTypeCoercion occurrences="1">
- <code>new $this->queueClass()</code>
- </PropertyTypeCoercion>
- <RedundantCastGivenDocblockType occurrences="2">
- <code>(int) $priority</code>
- <code>(string) $class</code>
- </RedundantCastGivenDocblockType>
- <RedundantConditionGivenDocblockType occurrences="1">
- <code>null !== $this->queue</code>
- </RedundantConditionGivenDocblockType>
- </file>
<file src="src/SplPriorityQueue.php">
<ImplementedReturnTypeMismatch occurrences="1">
<code>void</code>
<MethodSignatureMismatch occurrences="1">
<code>public function insert($datum, $priority)</code>
</MethodSignatureMismatch>
- <MixedAssignment occurrences="4">
- <code>$array[]</code>
- <code>$data[]</code>
- <code>$item</code>
- <code>$item</code>
- </MixedAssignment>
</file>
<file src="src/StringUtils.php">
<DocblockTypeContradiction occurrences="1">
* This class aggregates items for the queue itself, but also composes an
* "inner" iterator in the form of an SplPriorityQueue object for performing
* the actual iteration.
+ *
+ * @template T
+ * @template TPriority of int
+ * @implements IteratorAggregate<array-key, T>
*/
class PriorityQueue implements Countable, IteratorAggregate, Serializable
{
/**
* Inner queue class to use for iteration
*
- * @var string
+ * @var class-string<\SplPriorityQueue>
*/
protected $queueClass = SplPriorityQueue::class;
* Actual items aggregated in the priority queue. Each item is an array
* with keys "data" and "priority".
*
- * @var array
+ * @var list<array{data: T, priority: TPriority}>
*/
protected $items = [];
/**
* Inner queue object
*
- * @var SplPriorityQueue
+ * @var \SplPriorityQueue<TPriority, T>|null
*/
protected $queue;
*
* Priority defaults to 1 (low priority) if none provided.
*
- * @param mixed $data
- * @param int $priority
- * @return PriorityQueue
+ * @param T $data
+ * @param TPriority $priority
+ * @return $this
*/
public function insert($data, $priority = 1)
{
+ /** @psalm-var TPriority $priority */
$priority = (int) $priority;
$this->items[] = [
'data' => $data,
public function remove($datum)
{
$found = false;
+ $key = null;
foreach ($this->items as $key => $item) {
if ($item['data'] === $datum) {
$found = true;
break;
}
}
- if ($found) {
+ if ($found && $key !== null) {
unset($this->items[$key]);
$this->queue = null;
/**
* Peek at the top node in the queue, based on priority.
*
- * @return mixed
+ * @return T
*/
public function top()
{
- return $this->getIterator()->top();
+ $queue = clone $this->getQueue();
+
+ return $queue->top();
}
/**
* Extract a node from the inner queue and sift up
*
- * @return mixed
+ * @return T
*/
public function extract()
{
* retrieves the inner queue object, and clones it for purposes of
* iteration.
*
- * @return SplPriorityQueue
+ * @return \SplPriorityQueue<TPriority, T>
*/
#[ReturnTypeWillChange]
public function getIterator()
/**
* Magic method used for serializing of an instance.
*
- * @return array
+ * @return list<array{data: T, priority: TPriority}>
*/
public function __serialize()
{
/**
* Unserialize a string into a PriorityQueue object
*
- * Serialization format is compatible with {@link Laminas\Stdlib\SplPriorityQueue}
+ * Serialization format is compatible with {@link SplPriorityQueue}
*
* @param string $data
* @return void
));
}
+ /** @psalm-var list<array{data: T, priority: TPriority}> $toUnserialize */
+
$this->__unserialize($toUnserialize);
}
/**
* Magic method used to rebuild an instance.
*
- * @param array $data Data array.
+ * @param list<array{data: T, priority: TPriority}> $data Data array.
* @return void
*/
public function __unserialize($data)
/**
* Serialize to an array
- *
* By default, returns only the item data, and in the order registered (not
* sorted). You may provide one of the EXTR_* flags as an argument, allowing
* the ability to return priorities or both data and priority.
*
* @param int $flag
- * @return array
+ * @return array<array-key, mixed>
+ * @psalm-return ($flag is self::EXTR_BOTH
+ * ? list<array{data: T, priority: TPriority}>
+ * : $flag is self::EXTR_PRIORITY
+ * ? list<TPriority>
+ * : list<T>
+ * )
*/
public function toArray($flag = self::EXTR_DATA)
{
* Please see {@link getIterator()} for details on the necessity of an
* internal queue class. The class provided should extend SplPriorityQueue.
*
- * @param string $class
- * @return PriorityQueue
+ * @param class-string<\SplPriorityQueue> $class
+ * @return $this
*/
public function setInternalQueueClass($class)
{
+ /** @psalm-suppress RedundantCastGivenDocblockType */
$this->queueClass = (string) $class;
return $this;
}
/**
* Does the queue contain the given datum?
*
- * @param mixed $datum
+ * @param T $datum
* @return bool
*/
public function contains($datum)
/**
* Does the queue have an item with the given priority?
*
- * @param int $priority
+ * @param TPriority $priority
* @return bool
*/
public function hasPriority($priority)
* Get the inner priority queue instance
*
* @throws Exception\DomainException
- * @return SplPriorityQueue
+ * @return \SplPriorityQueue<TPriority, T>
+ * @psalm-assert !null $this->queue
*/
protected function getQueue()
{
if (null === $this->queue) {
- $this->queue = new $this->queueClass();
+ /** @psalm-suppress UnsafeInstantiation */
+ $queue = new $this->queueClass();
+ /** @psalm-var \SplPriorityQueue<TPriority, T> $queue */
+ $this->queue = $queue;
+ /** @psalm-suppress DocblockTypeContradiction, MixedArgument */
if (! $this->queue instanceof \SplPriorityQueue) {
throw new Exception\DomainException(sprintf(
'PriorityQueue expects an internal queue of type SplPriorityQueue; received "%s"',
));
}
}
+
return $this->queue;
}
*
* Also, provides predictable heap order for datums added with the same priority
* (i.e., they will be emitted in the same order they are enqueued).
+ *
+ * @psalm-type InternalPriority = array{0: mixed, 1: int}
+ * @template TValue
+ * @template TPriority of InternalPriority
+ * @extends \SplPriorityQueue<TPriority, TValue>
*/
class SplPriorityQueue extends \SplPriorityQueue implements Serializable
{
* Utilizes {@var $serial} to ensure that values of equal priority are
* emitted in the same order in which they are inserted.
*
- * @param mixed $datum
- * @param mixed $priority
+ * @param TValue $datum
+ * @param TPriority|mixed $priority
* @return void
*/
public function insert($datum, $priority)
if (! is_array($priority)) {
$priority = [$priority, $this->serial--];
}
+
+ /** @psalm-var TPriority $priority */
+
parent::insert($datum, $priority);
}
*
* Array will be priority => data pairs
*
- * @return array
+ * @return list<TValue>
*/
public function toArray()
{
$priority = (int) $item['priority'];
}
+ /** @psalm-var TValue $item['data'] */
+
$this->insert($item['data'], $priority);
}
}