Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/develop' into 4.5
Browse files Browse the repository at this point in the history
  • Loading branch information
kenjis committed Nov 18, 2023
2 parents de116cc + 79c1b2f commit 5de7742
Show file tree
Hide file tree
Showing 15 changed files with 136 additions and 30 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/test-phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,17 @@ jobs:
- SQLSRV
- SQLite3
mysql-version:
- '5.7'
- '8.0'
include:
- php-version: '8.1'
db-platform: MySQLi
mysql-version: '8.0'
mysql-version: '5.7'
- php-version: '8.3'
composer-option: '--ignore-platform-req=php'

uses: ./.github/workflows/reusable-phpunit-test.yml # @TODO Extract to codeigniter4/.github repo
with:
job-name:
job-name: ''
php-version: ${{ matrix.php-version }}
job-id: database-live-tests
db-platform: ${{ matrix.db-platform }}
Expand Down Expand Up @@ -135,7 +135,7 @@ jobs:

uses: ./.github/workflows/reusable-phpunit-test.yml # @TODO Extract to codeigniter4/.github repo
with:
job-name:
job-name: ''
php-version: ${{ matrix.php-version }}
job-id: separate-process-tests
group-name: SeparateProcess
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"phpunit/phpcov": "^8.2",
"phpunit/phpunit": "^9.1",
"predis/predis": "^1.1 || ^2.0",
"rector/rector": "0.18.8",
"rector/rector": "0.18.10",
"vimeo/psalm": "^5.0"
},
"suggest": {
Expand Down
2 changes: 0 additions & 2 deletions system/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\Response;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\URI;
use CodeIgniter\Model;
use CodeIgniter\Session\Session;
use CodeIgniter\Test\TestLogger;
Expand Down
13 changes: 13 additions & 0 deletions system/HTTP/Exceptions/HTTPException.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ public static function forInvalidNegotiationType(string $type)
return new static(lang('HTTP.invalidNegotiationType', [$type]));
}

/**
* Thrown in IncomingRequest when the json_decode() produces
* an error code other than JSON_ERROR_NONE.
*
* @param string $error The error message
*
* @return static
*/
public static function forInvalidJSON(?string $error = null)
{
return new static(lang('HTTP.invalidJSON', [$error]));
}

/**
* For Message
*
Expand Down
14 changes: 13 additions & 1 deletion system/HTTP/IncomingRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -569,10 +569,22 @@ public function getVar($index = null, $filter = null, $flags = null)
* @see http://php.net/manual/en/function.json-decode.php
*
* @return array|bool|float|int|stdClass|null
*
* @throws HTTPException When the body is invalid as JSON.
*/
public function getJSON(bool $assoc = false, int $depth = 512, int $options = 0)
{
return json_decode($this->body ?? '', $assoc, $depth, $options);
if ($this->body === null) {
return null;
}

$result = json_decode($this->body, $assoc, $depth, $options);

if (json_last_error() !== JSON_ERROR_NONE) {
throw HTTPException::forInvalidJSON(json_last_error_msg());
}

return $result;
}

/**
Expand Down
1 change: 1 addition & 0 deletions system/Images/Handlers/GDHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ public function save(?string $target = null, int $quality = 90): bool

// for png and webp we can actually preserve transparency
if (in_array($this->image()->imageType, $this->supportTransparency, true)) {
imagepalettetotruecolor($this->resource);
imagealphablending($this->resource, false);
imagesavealpha($this->resource, true);
}
Expand Down
1 change: 1 addition & 0 deletions system/Language/en/HTTP.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

// IncomingRequest
'invalidNegotiationType' => '"{0}" is not a valid negotiation type. Must be one of: media, charset, encoding, language.',
'invalidJSON' => 'Failed to parse JSON string. Error: {0}',

// Message
'invalidHTTPProtocol' => 'Invalid HTTP Protocol Version: {0}',
Expand Down
37 changes: 21 additions & 16 deletions system/Test/FilterTestTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,35 +125,42 @@ protected function getFilterCaller($filter, string $position): Closure
throw new InvalidArgumentException('Invalid filter position passed: ' . $position);
}

if ($filter instanceof FilterInterface) {
$filterInstances = [$filter];
}

if (is_string($filter)) {
// Check for an alias (no namespace)
if (strpos($filter, '\\') === false) {
if (! isset($this->filtersConfig->aliases[$filter])) {
throw new RuntimeException("No filter found with alias '{$filter}'");
}

$filterClasses = $this->filtersConfig->aliases[$filter];
$filterClasses = (array) $this->filtersConfig->aliases[$filter];
} else {
// FQCN
$filterClasses = [$filter];
}

$filterClasses = (array) $filterClasses;
}
$filterInstances = [];

foreach ($filterClasses as $class) {
// Get an instance
$filter = new $class();
foreach ($filterClasses as $class) {
// Get an instance
$filter = new $class();

if (! $filter instanceof FilterInterface) {
throw FilterException::forIncorrectInterface(get_class($filter));
if (! $filter instanceof FilterInterface) {
throw FilterException::forIncorrectInterface(get_class($filter));
}

$filterInstances[] = $filter;
}
}

$request = clone $this->request;

if ($position === 'before') {
return static function (?array $params = null) use ($filterClasses, $request) {
foreach ($filterClasses as $class) {
$filter = new $class();

return static function (?array $params = null) use ($filterInstances, $request) {
foreach ($filterInstances as $filter) {
$result = $filter->before($request, $params);

// @TODO The following logic is in Filters class.
Expand All @@ -177,10 +184,8 @@ protected function getFilterCaller($filter, string $position): Closure

$response = clone $this->response;

return static function (?array $params = null) use ($filterClasses, $request, $response) {
foreach ($filterClasses as $class) {
$filter = new $class();

return static function (?array $params = null) use ($filterInstances, $request, $response) {
foreach ($filterInstances as $filter) {
$result = $filter->after($request, $response, $params);

// @TODO The following logic is in Filters class.
Expand Down
Binary file added tests/_support/Images/rocket.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions tests/system/HTTP/IncomingRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use CodeIgniter\Test\CIUnitTestCase;
use Config\App;
use InvalidArgumentException;
use JsonException;
use TypeError;

/**
Expand Down Expand Up @@ -528,6 +529,32 @@ public function testGetJSONReturnsNullFromNullBody(): void
$this->assertNull($request->getJSON());
}

public function testGetJSONWithInvalidJSONString(): void
{
$this->expectException(HTTPException::class);
$this->expectExceptionMessage('Failed to parse JSON string. Error: Syntax error');

$config = new App();
$config->baseURL = 'http://example.com/';
$json = 'Invalid JSON string';
$request = $this->createRequest($config, $json);

$request->getJSON();
}

public function testGetJSONWithJsonThrowOnErrorAndInvalidJSONString(): void
{
$this->expectException(JsonException::class);
$this->expectExceptionMessage('Syntax error');

$config = new App();
$config->baseURL = 'http://example.com/';
$json = 'Invalid JSON string';
$request = $this->createRequest($config, $json);

$request->getJSON(false, 512, JSON_THROW_ON_ERROR);
}

public function testCanGrabGetRawInput(): void
{
$rawstring = 'username=admin001&role=administrator&usepass=0';
Expand Down
9 changes: 9 additions & 0 deletions tests/system/Images/GDHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,15 @@ public function testImageConvert(): void
$this->assertSame(exif_imagetype($this->start . 'work/ci-logo.png'), IMAGETYPE_PNG);
}

public function testImageConvertPngToWebp(): void
{
$this->handler->withFile($this->origin . 'rocket.png');
$this->handler->convert(IMAGETYPE_WEBP);
$saved = $this->start . 'work/rocket.webp';
$this->handler->save($saved);
$this->assertSame(exif_imagetype($saved), IMAGETYPE_WEBP);
}

public function testImageReorientLandscape(): void
{
for ($i = 0; $i <= 8; $i++) {
Expand Down
18 changes: 17 additions & 1 deletion tests/system/Test/FilterTestTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function testGetCallerInvalidPosition(): void
$this->getFilterCaller('test-customfilter', 'banana');
}

public function testCallerSupportArray(): void
public function testCallerSupportsArray(): void
{
$this->filtersConfig->aliases['test-customfilter'] = [Customfilter::class];

Expand All @@ -73,6 +73,22 @@ public function testCallerSupportArray(): void
$this->assertSame('http://hellowworld.com', $result->getBody());
}

public function testCallerSupportsClassname(): void
{
$caller = $this->getFilterCaller(Customfilter::class, 'before');
$result = $caller();

$this->assertSame('http://hellowworld.com', $result->getBody());
}

public function testCallerSupportsFilterInstance(): void
{
$caller = $this->getFilterCaller(new Customfilter(), 'before');
$result = $caller();

$this->assertSame('http://hellowworld.com', $result->getBody());
}

public function testCallerUsesClonedInstance(): void
{
$caller = $this->getFilterCaller('test-customfilter', 'before');
Expand Down
20 changes: 20 additions & 0 deletions tests/system/Validation/ValidationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CodeIgniter\Validation;

use CodeIgniter\HTTP\Exceptions\HTTPException;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\SiteURI;
use CodeIgniter\HTTP\UserAgent;
Expand Down Expand Up @@ -884,6 +885,25 @@ public function testJsonInput(): void
unset($_SERVER['CONTENT_TYPE']);
}

public function testJsonInputInvalid(): void
{
$this->expectException(HTTPException::class);
$this->expectExceptionMessage('Failed to parse JSON string. Error: Syntax error');

$config = new App();
$json = 'invalid';
$request = new IncomingRequest($config, new URI(), $json, new UserAgent());

Check failure on line 895 in tests/system/Validation/ValidationTest.php

View workflow job for this annotation

GitHub Actions / Psalm Analysis

UndefinedClass

tests/system/Validation/ValidationTest.php:895:53: UndefinedClass: Class, interface or enum named CodeIgniter\Validation\URI does not exist (see https://psalm.dev/019)
$request->setHeader('Content-Type', 'application/json');

$rules = [
'role' => 'if_exist|max_length[5]',
];
$this->validation
->withRequest($request->withMethod('POST'))
->setRules($rules)
->run();
}

/**
* @see https://github.com/codeigniter4/CodeIgniter4/issues/6466
*/
Expand Down
2 changes: 2 additions & 0 deletions user_guide_src/source/changelogs/v4.4.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ and Traditional rules validate data of non-string types.
Message Changes
***************

- Added ``HTTP.invalidJSON`` error message.

*******
Changes
*******
Expand Down
12 changes: 7 additions & 5 deletions user_guide_src/source/libraries/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,13 @@ valid_cc_number Yes Verifies that the credit card number matches
Rules for File Uploads
======================

These validation rules enable you to do the basic checks you might need to verify that uploaded files meet your business needs.
When you validate uploaded files, you must use the rules specifically created for
file validation.

.. important:: Only rules that listed in the table below can be used to validate
files. Therefore, adding any general rules, like ``permit_empty``, to file
validation rules array or string, the file validation will not work correctly.

Since the value of a file upload HTML field doesn't exist, and is stored in the ``$_FILES`` global, the name of the input field will
need to be used twice. Once to specify the field name as you would for any other rule, but again as the first parameter of all
file upload related rules::
Expand Down Expand Up @@ -1054,7 +1060,3 @@ is_image Yes Fails if the file cannot be determined to be
======================= ========== ============================================= ===================================================

The file validation rules apply for both single and multiple file uploads.

.. note:: Only rules specifically created for file validation (like the ones listed in the table above) can be used to validate files.
Therefore, adding any general rules, like ``permit_empty``, to file validation rules array or string, the file validation will not
work correctly.

0 comments on commit 5de7742

Please sign in to comment.