Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/bc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
on:
pull_request:
paths-ignore:
- 'docs/**'
- 'README.md'
- 'CHANGELOG.md'
- '.gitignore'
- '.gitattributes'
- 'infection.json.dist'
- 'phpunit.xml.dist'
- 'psalm.xml'
push:
branches: ['master']
paths-ignore:
- 'docs/**'
- 'README.md'
- 'CHANGELOG.md'
- '.gitignore'
- '.gitattributes'
- 'infection.json.dist'
- 'phpunit.xml.dist'
- 'psalm.xml'

name: backwards compatibility

jobs:
roave_bc_check:
uses: yiisoft/actions/.github/workflows/bc.yml@master
with:
os: >-
['ubuntu-latest']
php: >-
['8.4']
Comment on lines +28 to +33

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copilot Autofix

AI 5 months ago

To fix the problem, you should add a permissions block that explicitly limits the permissions available to the workflow. The best approach is to add this block at the workflow (top) level unless you know the job requires more elevated permissions than read-only. Since the job appears to merely check backward compatibility via a reusable workflow and likely does not need to write to the repository or create/update pull requests, a minimal contents: read permission is the least privileged and safest starting point. You should insert the following block near the top of the file, immediately after the name: property (line 25), so it applies to all jobs in the workflow:

permissions:
  contents: read

No additional methods, definitions, or library installations are necessary—just this single insertion.

Suggested changeset 1
.github/workflows/bc.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/bc.yml b/.github/workflows/bc.yml
--- a/.github/workflows/bc.yml
+++ b/.github/workflows/bc.yml
@@ -22,6 +22,8 @@
       - 'psalm.xml'
 
 name: backwards compatibility
+permissions:
+  contents: read
 
 jobs:
   roave_bc_check:
EOF
@@ -22,6 +22,8 @@
- 'psalm.xml'

name: backwards compatibility
permissions:
contents: read

jobs:
roave_bc_check:
Copilot is powered by AI and may make mistakes. Always verify output.
15 changes: 0 additions & 15 deletions .github/workflows/bc.yml_

This file was deleted.

5 changes: 4 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- 'psalm.xml'

push:
branches: ['master']
paths-ignore:
- 'docs/**'
- 'README.md'
Expand All @@ -24,8 +25,10 @@ name: build
jobs:
phpunit:
uses: yiisoft/actions/.github/workflows/phpunit.yml@master
secrets:
codecovToken: ${{ secrets.CODECOV_TOKEN }}
with:
os: >-
['ubuntu-latest', 'windows-latest']
php: >-
['7.4', '8.0', '8.1']
['8.1', '8.2', '8.3', '8.4']
5 changes: 3 additions & 2 deletions .github/workflows/mutation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- 'psalm.xml'

push:
branches: ['master']
paths-ignore:
- 'docs/**'
- 'README.md'
Expand All @@ -21,11 +22,11 @@

jobs:
mutation:
uses: yiisoft/actions/.github/workflows/roave-infection.yml@master
uses: yiisoft/actions/.github/workflows/infection.yml@master
with:
os: >-
['ubuntu-latest']
php: >-
['8.1']
['8.2']
secrets:
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}
3 changes: 2 additions & 1 deletion .github/workflows/static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- 'phpunit.xml.dist'

push:
branches: ['master']
paths-ignore:
- 'docs/**'
- 'README.md'
Expand All @@ -28,4 +29,4 @@ jobs:
os: >-
['ubuntu-latest']
php: >-
['7.4', '8.0', '8.1']
['8.1', '8.2', '8.3', '8.4']
11 changes: 3 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,8 @@ composer.phar
# Mac DS_Store Files
.DS_Store

# phpunit itself is not needed
phpunit.phar
# local phpunit config
# PhpUnit
/phpunit.phar
/phpunit.xml
# phpunit cache
.phpunit.result.cache

# Phan
analysis.txt
/.phpunit.cache

5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

## 1.1.2 under development

- no changes in this release.
- Chg #44: Bump minimum PHP version to 8.1 (@vjik)
- Chg #44: Change PHP constraint in composer.json to `8.1 - 8.4` (@vjik)
- Enh #44: Add psalm type `int<1, 2147483647>` to `depth` parameter in `JsonParser` constructor (@vjik)
- Bug #44: Explicitly mark nullable parameters (@vjik)

## 1.1.1 June 03, 2024

Expand Down
18 changes: 9 additions & 9 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,22 @@
}
],
"require": {
"php": "^7.4|^8.0",
"php": "8.1 - 8.4",
"ext-json": "*",
"psr/container": "^1.0|^2.0",
"psr/http-message": "^1.0|^2.0",
"psr/container": "^1.0 || ^2.0",
"psr/http-message": "^1.0 || ^2.0",
"psr/http-message-implementation": "1.0",
"psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0",
"yiisoft/http": "^1.2"
},
"require-dev": {
"nyholm/psr7": "^1.0",
"phpunit/phpunit": "^9.5",
"roave/infection-static-analysis-plugin": "^1.16",
"spatie/phpunit-watcher": "^1.23",
"vimeo/psalm": "^4.18",
"yiisoft/test-support": "^1.3"
"httpsoft/http-message": "^1.1",
"infection/infection": "^0.29.8",
"phpunit/phpunit": "^10.5.55",
"spatie/phpunit-watcher": "^1.24",
"vimeo/psalm": "^6.13.1",
"yiisoft/test-support": "^3.0.2"
},
"autoload": {
"psr-4": {
Expand Down
5 changes: 2 additions & 3 deletions docs/internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ The package is tested with [PHPUnit](https://phpunit.de/). To run tests:

## Mutation testing

The package tests are checked with [Infection](https://infection.github.io/) mutation framework with
[Infection Static Analysis Plugin](https://github.com/Roave/infection-static-analysis-plugin). To run it:
The package tests are checked with [Infection](https://infection.github.io/) mutation framework. To run it:

```shell
./vendor/bin/roave-infection-static-analysis-plugin
./vendor/bin/infection
```

## Static analysis
Expand Down
7 changes: 6 additions & 1 deletion infection.json.dist
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
}
},
"mutators": {
"@default": true
"@default": true,
"IncrementInteger": {
"ignoreSourceCodeByRegex": [
".* explode\\(';', \\$contentType, 2\\);$"
]
}
}
}
25 changes: 16 additions & 9 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
colors="true"
verbose="true"
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheDirectory=".phpunit.cache"
requireCoverageMetadata="false"
beStrictAboutCoverageMetadata="true"
beStrictAboutOutputDuringTests="true"
executionOrder="random"
failOnRisky="true"
failOnWarning="true">
failOnWarning="true"
stopOnFailure="false"
colors="true"
displayDetailsOnPhpunitDeprecations="true"
>
<php>
<ini name="error_reporting" value="-1"/>
</php>

<testsuites>
<testsuite name="Yii Request body parsers tests">
<testsuite name="Yii Request Body Parser tests">
<directory>./tests</directory>
</testsuite>
</testsuites>

<coverage>
<source>
<include>
<directory>./src</directory>
<directory suffix=".php">./src</directory>
</include>
</coverage>
</source>
</phpunit>
8 changes: 7 additions & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<?xml version="1.0"?>
<psalm
errorLevel="1"
resolveFromConfigFile="true"
findUnusedBaselineEntry="true"
findUnusedCode="false"
ensureOverrideAttribute="false"
strictBinaryOperands="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
Expand All @@ -12,4 +15,7 @@
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
<issueHandlers>
<MixedAssignment errorLevel="suppress" />
</issueHandlers>
</psalm>
1 change: 0 additions & 1 deletion src/BadRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

use Yiisoft\Http\Status;

/**
Expand Down Expand Up @@ -41,7 +40,7 @@

public function withParserException(ParserException $e): BadRequestHandlerInterface
{
$new = clone $this;

Check warning on line 43 in src/BadRequestHandler.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "CloneRemoval": @@ @@ } public function withParserException(ParserException $e): BadRequestHandlerInterface { - $new = clone $this; + $new = $this; $new->parserException = $e; return $new; } }
$new->parserException = $e;
return $new;
}
Expand Down
4 changes: 3 additions & 1 deletion src/Parser/JsonParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@
final class JsonParser implements ParserInterface
{
private bool $convertToAssociativeArray;
/** @psalm-var int<1, 2147483647> */
private int $depth;
private int $options;

/**
* @param bool $convertToAssociativeArray Whether objects should be converted to associative array during parsing.
* @param int $depth Maximum JSON recursion depth.
* @param int $options JSON decoding options. {@see json_decode()}.
*
* @psalm-param int<1, 2147483647> $depth
*/
public function __construct(
bool $convertToAssociativeArray = true,
int $depth = 512,

Check warning on line 34 in src/Parser/JsonParser.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "IncrementInteger": @@ @@ * * @psalm-param int<1, 2147483647> $depth */ - public function __construct(bool $convertToAssociativeArray = true, int $depth = 512, int $options = JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_IGNORE) + public function __construct(bool $convertToAssociativeArray = true, int $depth = 513, int $options = JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_IGNORE) { $this->convertToAssociativeArray = $convertToAssociativeArray; $this->depth = $depth;

Check warning on line 34 in src/Parser/JsonParser.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "DecrementInteger": @@ @@ * * @psalm-param int<1, 2147483647> $depth */ - public function __construct(bool $convertToAssociativeArray = true, int $depth = 512, int $options = JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_IGNORE) + public function __construct(bool $convertToAssociativeArray = true, int $depth = 511, int $options = JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_IGNORE) { $this->convertToAssociativeArray = $convertToAssociativeArray; $this->depth = $depth;
int $options = JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_IGNORE
) {
$this->convertToAssociativeArray = $convertToAssociativeArray;
Expand All @@ -43,7 +46,6 @@
}

try {
/** @var mixed $result */
$result = json_decode($rawBody, $this->convertToAssociativeArray, $this->depth, $this->options);
if (is_array($result) || is_object($result)) {
return $result;
Expand Down
2 changes: 2 additions & 0 deletions src/ParserException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

/**
* Exception during parsing request.
*
* @psalm-suppress ClassMustBeFinal We want to allow extending this exception.
*/
class ParserException extends \RuntimeException
{
Expand Down
2 changes: 1 addition & 1 deletion src/RequestBodyParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
public function __construct(
ResponseFactoryInterface $responseFactory,
ContainerInterface $container,
BadRequestHandlerInterface $badRequestHandler = null
BadRequestHandlerInterface|null $badRequestHandler = null
) {
$this->container = $container;
$this->badRequestHandler = $badRequestHandler ?? new BadRequestHandler($responseFactory);
Expand Down Expand Up @@ -89,7 +89,7 @@
return $new;
}
foreach ($mimeTypes as $mimeType) {
$this->validateMimeType($mimeType);

Check warning on line 92 in src/RequestBodyParser.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ return $new; } foreach ($mimeTypes as $mimeType) { - $this->validateMimeType($mimeType); + unset($new->parsers[$this->normalizeMimeType($mimeType)]); } return $new;
unset($new->parsers[$this->normalizeMimeType($mimeType)]);
}
return $new;
Expand All @@ -114,7 +114,7 @@
try {
/** @var mixed $parsed */
$parsed = $parser->parse((string)$request->getBody());
if ($parsed !== null && !is_object($parsed) && !is_array($parsed)) {

Check warning on line 117 in src/RequestBodyParser.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndAllSubExprNegation": @@ @@ try { /** @var mixed $parsed */ $parsed = $parser->parse((string) $request->getBody()); - if ($parsed !== null && !is_object($parsed) && !is_array($parsed)) { + if (!($parsed !== null) && is_object($parsed) && is_array($parsed)) { $parserClass = get_class($parser); throw new RuntimeException("{$parserClass}::parse() return value must be an array, an object, or null."); }

Check warning on line 117 in src/RequestBodyParser.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "LogicalAnd": @@ @@ try { /** @var mixed $parsed */ $parsed = $parser->parse((string) $request->getBody()); - if ($parsed !== null && !is_object($parsed) && !is_array($parsed)) { + if (($parsed !== null || !is_object($parsed)) && !is_array($parsed)) { $parserClass = get_class($parser); throw new RuntimeException("{$parserClass}::parse() return value must be an array, an object, or null."); }

Check warning on line 117 in src/RequestBodyParser.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "LogicalNot": @@ @@ try { /** @var mixed $parsed */ $parsed = $parser->parse((string) $request->getBody()); - if ($parsed !== null && !is_object($parsed) && !is_array($parsed)) { + if ($parsed !== null && is_object($parsed) && !is_array($parsed)) { $parserClass = get_class($parser); throw new RuntimeException("{$parserClass}::parse() return value must be an array, an object, or null."); }

Check warning on line 117 in src/RequestBodyParser.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "NotIdentical": @@ @@ try { /** @var mixed $parsed */ $parsed = $parser->parse((string) $request->getBody()); - if ($parsed !== null && !is_object($parsed) && !is_array($parsed)) { + if ($parsed === null && !is_object($parsed) && !is_array($parsed)) { $parserClass = get_class($parser); throw new RuntimeException("{$parserClass}::parse() return value must be an array, an object, or null."); }
$parserClass = get_class($parser);
throw new RuntimeException(
"$parserClass::parse() return value must be an array, an object, or null."
Expand Down Expand Up @@ -147,12 +147,12 @@
private function getContentType(ServerRequestInterface $request): ?string
{
$contentType = $request->getHeaderLine(Header::CONTENT_TYPE);
if (trim($contentType) !== '') {

Check warning on line 150 in src/RequestBodyParser.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "UnwrapTrim": @@ @@ private function getContentType(ServerRequestInterface $request): ?string { $contentType = $request->getHeaderLine(Header::CONTENT_TYPE); - if (trim($contentType) !== '') { + if ($contentType !== '') { if (str_contains($contentType, ';')) { $contentTypeParts = explode(';', $contentType, 2); return strtolower(trim($contentTypeParts[0]));
if (str_contains($contentType, ';')) {
$contentTypeParts = explode(';', $contentType, 2);
return strtolower(trim($contentTypeParts[0]));
}
return strtolower(trim($contentType));

Check warning on line 155 in src/RequestBodyParser.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "UnwrapTrim": @@ @@ $contentTypeParts = explode(';', $contentType, 2); return strtolower(trim($contentTypeParts[0])); } - return strtolower(trim($contentType)); + return strtolower($contentType); } return null; }
}
return null;
}
Expand Down
9 changes: 4 additions & 5 deletions tests/BadRequestHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

namespace Yiisoft\Request\Body\Tests;

use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7\ServerRequest;
use HttpSoft\Message\ResponseFactory;
use HttpSoft\Message\ServerRequest;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ServerRequestInterface;
use Yiisoft\Http\Method;
use Yiisoft\Http\Status;
use Yiisoft\Request\Body\BadRequestHandler;

Expand All @@ -32,11 +31,11 @@ public function testShouldReturnCorrectErrorInBody(): void

private function createHandler(): BadRequestHandler
{
return new BadRequestHandler(new Psr17Factory());
return new BadRequestHandler(new ResponseFactory());
}

private function createRequest(string $uri = '/'): ServerRequestInterface
{
return new ServerRequest(Method::GET, $uri);
return new ServerRequest(uri: $uri);
}
}
Loading
Loading