Composer updates

This commit is contained in:
Clemens Schwaighofer
2023-05-29 16:21:31 +09:00
parent 250067927a
commit 7b5ad92e66
304 changed files with 11398 additions and 3199 deletions

View File

@@ -7,23 +7,25 @@ Psalm supports a wide range of docblock annotations.
Psalm uses the following PHPDoc tags to understand your code:
- [`@var`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/var.html)
Used for specifying the types of properties and variables@
Used for specifying the types of properties and variables
- [`@return`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/return.html)
Used for specifying the return types of functions, methods and closures
- [`@param`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/param.html)
Used for specifying types of parameters passed to functions, methods and closures
- [`@property`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/property.html)
Used to specify what properties can be accessed on an object that uses `__get` and `__set`
- [`@property-read`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/property-read.html)
- [`@property-read`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/property.html)
Used to specify what properties can be read on object that uses `__get`
- [`@property-write`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/property-write.html)
- [`@property-write`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/property.html)
Used to specify what properties can be written on object that uses `__set`
- [`@method`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/method.html)
Used to specify which magic methods are available on object that uses `__call`.
- [`@deprecated`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/deprecated.html)
Used to mark functions, methods, classes and interfaces as being deprecated
- [`@internal`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/internal.html)
used to mark classes, functions and properties that are internal to an application or library.
Used to mark classes, functions and properties that are internal to an application or library.
- [`@mixin`](#mixins)
Used to tell Psalm that the current class proxies the methods and properties of the referenced class.
### Off-label usage of the `@var` tag
@@ -46,6 +48,49 @@ function bat(): string {
return $_GET['bat'];
}
```
### @mixins
Adding `@mixin` to a classes docblock tells Psalm that the class proxies will proxy the methods and properties of the referenced class.
```php
class A
{
public string $a = 'A';
public function doA(): void
{
}
}
/**
* @mixin A
*/
class B
{
public string $b = 'B';
public function doB(): void
{
}
public function __call($name, $arguments)
{
(new A())->$name(...$arguments);
}
public function __get($name)
{
(new A())->$name;
}
}
$b = new B();
$b->doB();
$b->doA(); // works
echo $b->b;
echo $b->a; // works
```
## Psalm-specific tags
@@ -157,9 +202,10 @@ takesFoo(getFoo());
This provides the same, but for `false`. Psalm uses this internally for functions like `preg_replace`, which can return false if the given input has encoding errors, but where 99.9% of the time the function operates as expected.
### `@psalm-seal-properties`
### `@psalm-seal-properties`, `@psalm-no-seal-properties`
If you have a magic property getter/setter, you can use `@psalm-seal-properties` to instruct Psalm to disallow getting and setting any properties not contained in a list of `@property` (or `@property-read`/`@property-write`) annotations.
This is automatically enabled with the configuration option `sealAllProperties` and can be disabled for a class with `@psalm-no-seal-properties`
```php
<?php
@@ -181,6 +227,29 @@ $a = new A();
$a->bar = 5; // this call fails
```
### `@psalm-seal-methods`, `@psalm-no-seal-methods`
If you have a magic method caller, you can use `@psalm-seal-methods` to instruct Psalm to disallow calling any methods not contained in a list of `@method` annotations.
This is automatically enabled with the configuration option `sealAllMethods` and can be disabled for a class with `@psalm-no-seal-methods`
```php
<?php
/**
* @method foo(): string
* @psalm-seal-methods
*/
class A {
public function __call(string $name, array $args) {
if ($name === "foo") {
return "hello";
}
}
}
$a = new A();
$b = $a->bar(); // this call fails
```
### `@psalm-internal`
Used to mark a class, property or function as internal to a given namespace. Psalm treats this slightly differently to
@@ -446,7 +515,18 @@ $username = $_GET['username']; // prints something like "test.php:4 $username: m
```
*Note*: it throws [special low-level issue](../running_psalm/issues/Trace.md), so you have to set errorLevel to 1, override it in config or invoke Psalm with `--show-info=true`.
*Note*: it throws [special low-level issue](../running_psalm/issues/Trace.md).
To see it, you can set the global `errorLevel` to 1, or invoke Psalm with
`--show-info=true`, but both these solutions will probably result in a lot of
output. Another solution is to selectively bump the error level of the issue,
so that you only get one more error:
```xml
<!-- psalm.xml -->
<issueHandlers>
<Trace errorLevel="error"/>
</issueHandlers>
```
### `@psalm-check-type`
@@ -596,7 +676,7 @@ class Foo
}
```
When Psalm encounters variable property, it treats all properties in given class as potentially referenced.
With `@psalm-ignore-variable-property` annotation, this reference is ignored.
With `@psalm-ignore-variable-property` annotation, this reference is ignored.
While `PossiblyUnusedProperty` would be emitted in both cases, using `@psalm-ignore-variable-property`
would allow [Psalter](../manipulating_code/fixing.md) to delete `Foo::$bar`.
@@ -642,9 +722,9 @@ function (): Generator {
```
This annotation supports only generic types, meaning that e.g. `@psalm-yield string` would be ignored.
### `@psalm-api`
### `@api`, `@psalm-api`
Used to tell Psalm that a class is used, even if no references to it can be
Used to tell Psalm that a class or method is used, even if no references to it can be
found. Unused issues will be suppressed.
For example, in frameworks, controllers are often invoked "magically" without
@@ -657,6 +737,22 @@ any explicit references to them in your code. You should mark these classes with
class UnreferencedClass {}
```
### `@psalm-inheritors`
Used to tell Psalm that a class can only be extended by a certain subset of classes.
For example,
```php
<?php
/**
* @psalm-inheritors FooClass|BarClass
*/
class BaseClass {}
class FooClass extends BaseClass {}
class BarClass extends BaseClass {}
class BazClass extends BaseClass {} // this is an error
```
## Type Syntax
Psalm supports PHPDocs [type syntax](https://docs.phpdoc.org/latest/guide/guides/types.html), and also the [proposed PHPDoc PSR type syntax](https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md#appendix-a-types).

View File

@@ -203,6 +203,17 @@ $options['verbose'] = isset($options['verbose']);
handleOptions($options);
```
`...` is a shorthand for `...<array-key, mixed>` you can use other array generic types to provide more information about the open shape.
```php
// This is an open array
/** @param array{someKey: string, ...} */
// Which is the same as
/** @param array{someKey: string, ...<array-key, mixed>} */
// But it can be further locked down with a shape ...<TKey, TValue>
/** @return array{someKey: string, ...<int, bool>} */
```
## Callable arrays
An array holding a callable, like PHP's native `call_user_func()` and friends supports it:

View File

@@ -46,7 +46,7 @@ Atomic types are the basic building block of all type information used in Psalm.
* [`key-of<T>`](utility_types.md#key-oft)
* [`value-of<T>`](utility_types.md#value-oft)
* [`properties-of<T>`](utility_types.md#properties-oft)
* [`class-string-map<T as Foo, T>`](utility_types.md#class-string-mapt-as-foo-t)
* [`class-string-map<T of Foo, T>`](utility_types.md#class-string-mapt-as-foo-t)
* [`T[K]`](utility_types.md#tk)
* [Type aliases](utility_types.md#type-aliases)
* [Variable templates](utility_types.md#variable-templates)

View File

@@ -148,7 +148,7 @@ $b = asArray(new B);
/** @psalm-trace $b */; // array{foo: string, bar: int, baz: float}
```
## class-string-map&lt;T as Foo, T&gt;
## class-string-map&lt;T of Foo, T&gt;
Used to indicate an array where each value is equal an instance of the class string contained in the key:
@@ -166,11 +166,11 @@ class Foo {}
class Bar extends Foo {}
class A {
/** @var class-string-map<T as Foo, T> */
/** @var class-string-map<T of Foo, T> */
private static array $map = [];
/**
* @template U as Foo
* @template U of Foo
* @param class-string<U> $class
* @return U
*/
@@ -191,7 +191,7 @@ $bar = A::get(Bar::class);
/** @psalm-trace $bar */; // Bar
```
If we had used an `array<class-string<Foo>, Foo>` instead of a `class-string-map<T as Foo, T>` in the above example, we would've gotten some false positive `InvalidReturnStatement` issues, caused by the lack of a type assertion inside the `isset`.
If we had used an `array<class-string<Foo>, Foo>` instead of a `class-string-map<T of Foo, T>` in the above example, we would've gotten some false positive `InvalidReturnStatement` issues, caused by the lack of a type assertion inside the `isset`.
On the other hand, when using `class-string-map`, Psalm assumes that the value obtained by using a key `class-string<T>` is always equal to `T`.
Unbounded templates can also be used for unrelated classes:
@@ -250,8 +250,8 @@ Used to get the value corresponding to the specified key:
<?php
/**
* @template T as array
* @template TKey as string
* @template T of array
* @template TKey of string
* @param T $arr
* @param TKey $k
* @return T[TKey]
@@ -325,9 +325,9 @@ Variable templates allow directly using variables instead of template types, for
<?php
/**
* @template TA as string
* @template TB as string
* @template TChoose as bool
* @template TA of string
* @template TB of string
* @template TChoose of bool
* @param TA $a
* @param TB $b
* @param TChoose $choose

View File

@@ -90,6 +90,15 @@ Whether or not to use types as defined in docblocks. Defaults to `true`.
```
If not using all docblock types, you can still use docblock property types. Defaults to `false` (though only relevant if `useDocblockTypes` is `false`).
#### docblockPropertyTypesSealProperties
```xml
<psalm
docblockPropertyTypesSealProperties="[bool]"
>
```
Whether using @property in class docblocks should imply @psalm-seal-properties. Defaults to `true`.
#### usePhpDocMethodsWithoutMagicCall
```xml

View File

@@ -52,6 +52,7 @@
- [InaccessibleClassConstant](issues/InaccessibleClassConstant.md)
- [InaccessibleMethod](issues/InaccessibleMethod.md)
- [InaccessibleProperty](issues/InaccessibleProperty.md)
- [InheritorViolation](issues/InheritorViolation.md)
- [InterfaceInstantiation](issues/InterfaceInstantiation.md)
- [InternalClass](issues/InternalClass.md)
- [InternalMethod](issues/InternalMethod.md)
@@ -284,6 +285,7 @@
- [UnresolvableInclude](issues/UnresolvableInclude.md)
- [UnsafeGenericInstantiation](issues/UnsafeGenericInstantiation.md)
- [UnsafeInstantiation](issues/UnsafeInstantiation.md)
- [UnsupportedPropertyReferenceUsage](issues/UnsupportedPropertyReferenceUsage.md)
- [UnsupportedReferenceUsage](issues/UnsupportedReferenceUsage.md)
- [UnusedBaselineEntry](issues/UnusedBaselineEntry.md)
- [UnusedClass](issues/UnusedClass.md)

View File

@@ -0,0 +1,17 @@
# InheritorViolation
Emitted when a class/interface using `@psalm-inheritors` is extended/implemented
by a class that does not fulfil it's requirements.
```php
<?php
/**
* @psalm-inheritors FooClass|BarClass
*/
class BaseClass {}
class BazClass extends BaseClass {}
// InheritorViolation is emitted, as BaseClass can only be extended
// by FooClass|BarClass, which is not the case
$a = new BazClass();
```

View File

@@ -1,6 +1,6 @@
# InvalidExtendClass
Emitted when attempting to extend a final class or a class annotated with `@final`.
Emitted when attempting to extend a final class, a class annotated with `@final` or a class using @psalm-inheritors and not in the inheritor list
```php
<?php
@@ -15,4 +15,11 @@ class B extends A {}
class DoctrineA {}
class DoctrineB extends DoctrineA {}
```
/**
* @psalm-inheritors A|B
*/
class C {}
class D extends C {}
```

View File

@@ -35,6 +35,7 @@ function printName(string $name) {
- Sanitize user-input by using functions such as `htmlentities` or use an allowlist.
- Set all cookies to `HTTPOnly`.
- Consider using Content Security Policy (CSP), to limit the risk of XSS vulnerabilities.
- If user input itself is HTML, see [Sanitizing HTML User Input](../../security_analysis/avoiding_false_positives.md#sanitizing-html-user-input)
## Further resources

View File

@@ -35,6 +35,7 @@ Passing `');alert('injection');//` as a `GET` param here would cause the `alert`
- Sanitize user input by using functions such as `htmlentities` with the `ENT_QUOTES` flag or use an allowlist.
- Set all cookies to `HTTPOnly`.
- Consider using Content Security Policy (CSP), to limit the risk of XSS vulnerabilities.
- If user input itself is HTML, see [Sanitizing HTML User Input](../../security_analysis/avoiding_false_positives.md#sanitizing-html-user-input)
## Further resources

View File

@@ -1,6 +1,7 @@
# Trace
Not really an issue. Just reports type of the variable.
Not really an issue. Just reports the type of a variable when using
[`@psalm-trace`](../annotating_code/supported_annotations.md#psalm-trace).
```php
<?php

View File

@@ -0,0 +1,40 @@
# UnsupportedPropertyReferenceUsage
Psalm cannot guarantee the soundness of code that uses references to properties.
### Examples of Uncaught Errors
* Instance property assigned wrong type:
```php
<?php
class A {
public int $b = 0;
}
$a = new A();
$b = &$a->b;
$b = ''; // Fatal error
```
* Static property assigned wrong type:
```php
<?php
class A {
public static int $b = 0;
}
$b = &A::$b;
$b = ''; // Fatal error
```
* Readonly property reassigned:
```php
<?php
class A {
public function __construct(
public readonly int $b,
) {
}
}
$a = new A(0);
$b = &$a->b;
$b = 1; // Fatal error
```

View File

@@ -26,7 +26,7 @@ function echoVar(string $str) : void {
echoVar($_GET["text"]);
```
## Conditional escaping tainted input
## Conditionally escaping tainted input
A slightly modified version of the previous example is using a condition to determine whether the return value
is considered secure. Only in case function argument `$escape` is true, the corresponding annotation
@@ -50,6 +50,23 @@ echo processVar($_GET['text'], false); // detects tainted HTML
echo processVar($_GET['text'], true); // considered secure
```
## Sanitizing HTML user input
Whenever possible, applications should be designed to accept & store user input as discrete text fields, rather than blocks of HTML. This allows user input to be fully escaped via `htmlspecialchars` or `htmlentities`. In cases where HTML user input is required (e.g. rich text editors like [TinyMCE](https://www.tiny.cloud/)), a library designed specifically to filter out risky HTML is highly recommended. For example, [HTML Purifier](http://htmlpurifier.org/docs) could be used as follows:
```php
<?php
/**
* @psalm-taint-escape html
* @psalm-taint-escape has_quotes
*/
function sanitizeHTML($html){
$purifier = new HTMLPurifier();
return $purifier->purify($html);
}
```
## Specializing taints in functions
For functions, methods and classes you can use the `@psalm-taint-specialize` annotation.