Skip to content

Commit 5de7742

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into 4.5
2 parents de116cc + 79c1b2f commit 5de7742

File tree

15 files changed

+136
-30
lines changed

15 files changed

+136
-30
lines changed

.github/workflows/test-phpunit.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,17 @@ jobs:
9595
- SQLSRV
9696
- SQLite3
9797
mysql-version:
98-
- '5.7'
98+
- '8.0'
9999
include:
100100
- php-version: '8.1'
101101
db-platform: MySQLi
102-
mysql-version: '8.0'
102+
mysql-version: '5.7'
103103
- php-version: '8.3'
104104
composer-option: '--ignore-platform-req=php'
105105

106106
uses: ./.github/workflows/reusable-phpunit-test.yml # @TODO Extract to codeigniter4/.github repo
107107
with:
108-
job-name:
108+
job-name: ''
109109
php-version: ${{ matrix.php-version }}
110110
job-id: database-live-tests
111111
db-platform: ${{ matrix.db-platform }}
@@ -135,7 +135,7 @@ jobs:
135135

136136
uses: ./.github/workflows/reusable-phpunit-test.yml # @TODO Extract to codeigniter4/.github repo
137137
with:
138-
job-name:
138+
job-name: ''
139139
php-version: ${{ matrix.php-version }}
140140
job-id: separate-process-tests
141141
group-name: SeparateProcess

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"phpunit/phpcov": "^8.2",
3434
"phpunit/phpunit": "^9.1",
3535
"predis/predis": "^1.1 || ^2.0",
36-
"rector/rector": "0.18.8",
36+
"rector/rector": "0.18.10",
3737
"vimeo/psalm": "^5.0"
3838
},
3939
"suggest": {

system/Common.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525
use CodeIgniter\HTTP\IncomingRequest;
2626
use CodeIgniter\HTTP\RedirectResponse;
2727
use CodeIgniter\HTTP\RequestInterface;
28-
use CodeIgniter\HTTP\Response;
2928
use CodeIgniter\HTTP\ResponseInterface;
30-
use CodeIgniter\HTTP\URI;
3129
use CodeIgniter\Model;
3230
use CodeIgniter\Session\Session;
3331
use CodeIgniter\Test\TestLogger;

system/HTTP/Exceptions/HTTPException.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,19 @@ public static function forInvalidNegotiationType(string $type)
7272
return new static(lang('HTTP.invalidNegotiationType', [$type]));
7373
}
7474

75+
/**
76+
* Thrown in IncomingRequest when the json_decode() produces
77+
* an error code other than JSON_ERROR_NONE.
78+
*
79+
* @param string $error The error message
80+
*
81+
* @return static
82+
*/
83+
public static function forInvalidJSON(?string $error = null)
84+
{
85+
return new static(lang('HTTP.invalidJSON', [$error]));
86+
}
87+
7588
/**
7689
* For Message
7790
*

system/HTTP/IncomingRequest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,10 +569,22 @@ public function getVar($index = null, $filter = null, $flags = null)
569569
* @see http://php.net/manual/en/function.json-decode.php
570570
*
571571
* @return array|bool|float|int|stdClass|null
572+
*
573+
* @throws HTTPException When the body is invalid as JSON.
572574
*/
573575
public function getJSON(bool $assoc = false, int $depth = 512, int $options = 0)
574576
{
575-
return json_decode($this->body ?? '', $assoc, $depth, $options);
577+
if ($this->body === null) {
578+
return null;
579+
}
580+
581+
$result = json_decode($this->body, $assoc, $depth, $options);
582+
583+
if (json_last_error() !== JSON_ERROR_NONE) {
584+
throw HTTPException::forInvalidJSON(json_last_error_msg());
585+
}
586+
587+
return $result;
576588
}
577589

578590
/**

system/Images/Handlers/GDHandler.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ public function save(?string $target = null, int $quality = 90): bool
227227

228228
// for png and webp we can actually preserve transparency
229229
if (in_array($this->image()->imageType, $this->supportTransparency, true)) {
230+
imagepalettetotruecolor($this->resource);
230231
imagealphablending($this->resource, false);
231232
imagesavealpha($this->resource, true);
232233
}

system/Language/en/HTTP.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

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

2324
// Message
2425
'invalidHTTPProtocol' => 'Invalid HTTP Protocol Version: {0}',

system/Test/FilterTestTrait.php

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -125,35 +125,42 @@ protected function getFilterCaller($filter, string $position): Closure
125125
throw new InvalidArgumentException('Invalid filter position passed: ' . $position);
126126
}
127127

128+
if ($filter instanceof FilterInterface) {
129+
$filterInstances = [$filter];
130+
}
131+
128132
if (is_string($filter)) {
129133
// Check for an alias (no namespace)
130134
if (strpos($filter, '\\') === false) {
131135
if (! isset($this->filtersConfig->aliases[$filter])) {
132136
throw new RuntimeException("No filter found with alias '{$filter}'");
133137
}
134138

135-
$filterClasses = $this->filtersConfig->aliases[$filter];
139+
$filterClasses = (array) $this->filtersConfig->aliases[$filter];
140+
} else {
141+
// FQCN
142+
$filterClasses = [$filter];
136143
}
137144

138-
$filterClasses = (array) $filterClasses;
139-
}
145+
$filterInstances = [];
140146

141-
foreach ($filterClasses as $class) {
142-
// Get an instance
143-
$filter = new $class();
147+
foreach ($filterClasses as $class) {
148+
// Get an instance
149+
$filter = new $class();
144150

145-
if (! $filter instanceof FilterInterface) {
146-
throw FilterException::forIncorrectInterface(get_class($filter));
151+
if (! $filter instanceof FilterInterface) {
152+
throw FilterException::forIncorrectInterface(get_class($filter));
153+
}
154+
155+
$filterInstances[] = $filter;
147156
}
148157
}
149158

150159
$request = clone $this->request;
151160

152161
if ($position === 'before') {
153-
return static function (?array $params = null) use ($filterClasses, $request) {
154-
foreach ($filterClasses as $class) {
155-
$filter = new $class();
156-
162+
return static function (?array $params = null) use ($filterInstances, $request) {
163+
foreach ($filterInstances as $filter) {
157164
$result = $filter->before($request, $params);
158165

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

178185
$response = clone $this->response;
179186

180-
return static function (?array $params = null) use ($filterClasses, $request, $response) {
181-
foreach ($filterClasses as $class) {
182-
$filter = new $class();
183-
187+
return static function (?array $params = null) use ($filterInstances, $request, $response) {
188+
foreach ($filterInstances as $filter) {
184189
$result = $filter->after($request, $response, $params);
185190

186191
// @TODO The following logic is in Filters class.

tests/_support/Images/rocket.png

55.6 KB
Loading

tests/system/HTTP/IncomingRequestTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use CodeIgniter\Test\CIUnitTestCase;
1919
use Config\App;
2020
use InvalidArgumentException;
21+
use JsonException;
2122
use TypeError;
2223

2324
/**
@@ -528,6 +529,32 @@ public function testGetJSONReturnsNullFromNullBody(): void
528529
$this->assertNull($request->getJSON());
529530
}
530531

532+
public function testGetJSONWithInvalidJSONString(): void
533+
{
534+
$this->expectException(HTTPException::class);
535+
$this->expectExceptionMessage('Failed to parse JSON string. Error: Syntax error');
536+
537+
$config = new App();
538+
$config->baseURL = 'http://example.com/';
539+
$json = 'Invalid JSON string';
540+
$request = $this->createRequest($config, $json);
541+
542+
$request->getJSON();
543+
}
544+
545+
public function testGetJSONWithJsonThrowOnErrorAndInvalidJSONString(): void
546+
{
547+
$this->expectException(JsonException::class);
548+
$this->expectExceptionMessage('Syntax error');
549+
550+
$config = new App();
551+
$config->baseURL = 'http://example.com/';
552+
$json = 'Invalid JSON string';
553+
$request = $this->createRequest($config, $json);
554+
555+
$request->getJSON(false, 512, JSON_THROW_ON_ERROR);
556+
}
557+
531558
public function testCanGrabGetRawInput(): void
532559
{
533560
$rawstring = 'username=admin001&role=administrator&usepass=0';

0 commit comments

Comments
 (0)