Skip to content

Commit fc62f96

Browse files
authored
Merge pull request #8401 from michalsn/fix/highlightFile
fix: `highlightFile()` in `BaseExceptionHandler` for PHP 8.3
2 parents 766f76b + d558f09 commit fc62f96

File tree

7 files changed

+168
-3
lines changed

7 files changed

+168
-3
lines changed

system/Debug/BaseExceptionHandler.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,15 @@ protected static function highlightFile(string $file, int $lineNumber, int $line
182182

183183
$source = str_replace(["\r\n", "\r"], "\n", $source);
184184
$source = explode("\n", highlight_string($source, true));
185-
$source = str_replace('<br />', "\n", $source[1]);
186-
$source = explode("\n", str_replace("\r\n", "\n", $source));
185+
186+
if (PHP_VERSION_ID < 80300) {
187+
$source = str_replace('<br />', "\n", $source[1]);
188+
$source = explode("\n", str_replace("\r\n", "\n", $source));
189+
} else {
190+
// We have to remove these tags since we're preparing the result
191+
// ourselves and these tags are added manually at the end.
192+
$source = str_replace(['<pre><code>', '</code></pre>'], '', $source);
193+
}
187194

188195
// Get just the part to show
189196
$start = max($lineNumber - (int) round($lines / 2), 0);
@@ -199,7 +206,7 @@ protected static function highlightFile(string $file, int $lineNumber, int $line
199206
// of open and close span tags on one line, we need
200207
// to ensure we can close them all to get the lines
201208
// showing correctly.
202-
$spans = 1;
209+
$spans = 0;
203210

204211
foreach ($source as $n => $row) {
205212
$spans += substr_count($row, '<span') - substr_count($row, '</span');
@@ -216,6 +223,9 @@ protected static function highlightFile(string $file, int $lineNumber, int $line
216223
);
217224
} else {
218225
$out .= sprintf('<span class="line"><span class="number">' . $format . '</span> %s', $n + $start + 1, $row) . "\n";
226+
// We're closing only one span tag we added manually line before,
227+
// so we have to increment $spans count to close this tag later.
228+
$spans++;
219229
}
220230
}
221231

system/Test/IniTestTrait.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\Test;
13+
14+
trait IniTestTrait
15+
{
16+
private array $iniSettings = [];
17+
18+
private function backupIniValues(array $keys): void
19+
{
20+
foreach ($keys as $key) {
21+
$this->iniSettings[$key] = ini_get($key);
22+
}
23+
}
24+
25+
private function restoreIniValues(): void
26+
{
27+
foreach ($this->iniSettings as $key => $value) {
28+
ini_set($key, $value);
29+
}
30+
31+
$this->iniSettings = [];
32+
}
33+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<pre><code><span class="line"><span class="number"> 9</span> * the LICENSE file that was distributed with this source code.
2+
<span class="line"><span class="number">10</span> */
3+
<span class="line"><span class="number">11</span>
4+
<span class="line"><span class="number">12</span> </span><span style="color: #f1ce61;">namespace </span><span style="color: #c7c7c7">Tests\Support\Controllers</span><span style="color: #f1ce61;">;
5+
<span class="line"><span class="number">13</span>
6+
<span class="line"><span class="number">14</span> use </span><span style="color: #c7c7c7">CodeIgniter\Controller</span><span style="color: #f1ce61;">;
7+
<span class="line"><span class="number">15</span>
8+
<span class='line highlight'><span class='number'>16</span> class Hello extends Controller
9+
</span></span><span style="color: #c7c7c7"></span><span style="color: #f1ce61;"></span><span style="color: #c7c7c7"><span class="line"><span class="number">17</span> </span><span style="color: #f1ce61;">{
10+
<span class="line"><span class="number">18</span> public function </span><span style="color: #c7c7c7">index</span><span style="color: #f1ce61;">()
11+
<span class="line"><span class="number">19</span> {
12+
<span class="line"><span class="number">20</span> return </span><span style="color: #869d6a">'Hello'</span><span style="color: #f1ce61;">;
13+
<span class="line"><span class="number">21</span> }
14+
<span class="line"><span class="number">22</span> }
15+
<span class="line"><span class="number">23</span> </span>
16+
</span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<pre><code><span class="line"><span class="number"> 9</span> &nbsp;*&nbsp;the&nbsp;LICENSE&nbsp;file&nbsp;that&nbsp;was&nbsp;distributed&nbsp;with&nbsp;this&nbsp;source&nbsp;code.
2+
<span class="line"><span class="number">10</span> &nbsp;*/
3+
<span class="line"><span class="number">11</span>
4+
<span class="line"><span class="number">12</span> </span><span style="color: #f1ce61;">namespace&nbsp;</span><span style="color: #c7c7c7">Tests</span><span style="color: #f1ce61;">\</span><span style="color: #c7c7c7">Support</span><span style="color: #f1ce61;">\</span><span style="color: #c7c7c7">Controllers</span><span style="color: #f1ce61;">;
5+
<span class="line"><span class="number">13</span>
6+
<span class="line"><span class="number">14</span> use&nbsp;</span><span style="color: #c7c7c7">CodeIgniter</span><span style="color: #f1ce61;">\</span><span style="color: #c7c7c7">Controller</span><span style="color: #f1ce61;">;
7+
<span class="line"><span class="number">15</span>
8+
<span class='line highlight'><span class='number'>16</span> class&nbsp;Hello&nbsp;extends&nbsp;Controller
9+
</span></span><span style="color: #c7c7c7"></span><span style="color: #f1ce61;"></span><span style="color: #c7c7c7"><span class="line"><span class="number">17</span> </span><span style="color: #f1ce61;">{
10+
<span class="line"><span class="number">18</span> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;</span><span style="color: #c7c7c7">index</span><span style="color: #f1ce61;">()
11+
<span class="line"><span class="number">19</span> &nbsp;&nbsp;&nbsp;&nbsp;{
12+
<span class="line"><span class="number">20</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #869d6a">'Hello'</span><span style="color: #f1ce61;">;
13+
<span class="line"><span class="number">21</span> &nbsp;&nbsp;&nbsp;&nbsp;}
14+
<span class="line"><span class="number">22</span> }
15+
<span class="line"><span class="number">23</span> </span>
16+
</span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<pre><code><span class="line"><span class="number"> 9</span> &nbsp;*&nbsp;the&nbsp;LICENSE&nbsp;file&nbsp;that&nbsp;was&nbsp;distributed&nbsp;with&nbsp;this&nbsp;source&nbsp;code.
2+
<span class="line"><span class="number">10</span> &nbsp;*/
3+
<span class="line"><span class="number">11</span>
4+
<span class="line"><span class="number">12</span> </span><span style="color: #f1ce61;">namespace&nbsp;</span><span style="color: #c7c7c7">Tests\Support\Controllers</span><span style="color: #f1ce61;">;
5+
<span class="line"><span class="number">13</span>
6+
<span class="line"><span class="number">14</span> use&nbsp;</span><span style="color: #c7c7c7">CodeIgniter\Controller</span><span style="color: #f1ce61;">;
7+
<span class="line"><span class="number">15</span>
8+
<span class='line highlight'><span class='number'>16</span> class&nbsp;Hello&nbsp;extends&nbsp;Controller
9+
</span></span><span style="color: #c7c7c7"></span><span style="color: #f1ce61;"></span><span style="color: #c7c7c7"><span class="line"><span class="number">17</span> </span><span style="color: #f1ce61;">{
10+
<span class="line"><span class="number">18</span> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;function&nbsp;</span><span style="color: #c7c7c7">index</span><span style="color: #f1ce61;">()
11+
<span class="line"><span class="number">19</span> &nbsp;&nbsp;&nbsp;&nbsp;{
12+
<span class="line"><span class="number">20</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #869d6a">'Hello'</span><span style="color: #f1ce61;">;
13+
<span class="line"><span class="number">21</span> &nbsp;&nbsp;&nbsp;&nbsp;}
14+
<span class="line"><span class="number">22</span> }
15+
<span class="line"><span class="number">23</span> </span>
16+
</span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>

tests/system/Debug/ExceptionHandlerTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use App\Controllers\Home;
1515
use CodeIgniter\Exceptions\PageNotFoundException;
1616
use CodeIgniter\Test\CIUnitTestCase;
17+
use CodeIgniter\Test\IniTestTrait;
1718
use CodeIgniter\Test\StreamFilterTrait;
1819
use Config\Exceptions as ExceptionsConfig;
1920
use Config\Services;
@@ -27,6 +28,7 @@
2728
final class ExceptionHandlerTest extends CIUnitTestCase
2829
{
2930
use StreamFilterTrait;
31+
use IniTestTrait;
3032

3133
private ExceptionHandler $handler;
3234

@@ -237,4 +239,33 @@ public function testMaskSensitiveDataTraceDataKey(): void
237239

238240
$this->assertSame('/var/www/CodeIgniter4/app/Controllers/Home.php', $newTrace[0]['file']);
239241
}
242+
243+
public function testHighlightFile(): void
244+
{
245+
$this->backupIniValues([
246+
'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string',
247+
]);
248+
249+
$highlightFile = $this->getPrivateMethodInvoker($this->handler, 'highlightFile');
250+
$result = $highlightFile(SUPPORTPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Hello.php', 16);
251+
252+
switch (true) {
253+
case PHP_VERSION_ID < 80000:
254+
$resultFile = 'highlightFile_pre_80000.html';
255+
break;
256+
257+
case PHP_VERSION_ID < 80300:
258+
$resultFile = 'highlightFile_pre_80300.html';
259+
break;
260+
261+
default:
262+
$resultFile = 'highlightFile.html';
263+
}
264+
265+
$expected = file_get_contents(SUPPORTPATH . 'Debug' . DIRECTORY_SEPARATOR . $resultFile);
266+
267+
$this->assertSame($expected, $result);
268+
269+
$this->restoreIniValues();
270+
}
240271
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\Test;
13+
14+
use ReflectionException;
15+
16+
/**
17+
* @internal
18+
*
19+
* @group Others
20+
*/
21+
final class IniTestTraitTest extends CIUnitTestCase
22+
{
23+
use IniTestTrait;
24+
25+
/**
26+
* @throws ReflectionException
27+
*/
28+
public function testBackupAndRestoreIniValues(): void
29+
{
30+
$this->backupIniValues(['highlight.default']);
31+
$backup = $this->getPrivateProperty($this, 'iniSettings');
32+
$this->assertSame('#0000BB', $backup['highlight.default']);
33+
34+
ini_set('highlight.default', '#FFFFFF');
35+
$this->assertSame('#FFFFFF', ini_get('highlight.default'));
36+
37+
$this->restoreIniValues();
38+
$this->assertSame('#0000BB', ini_get('highlight.default'));
39+
40+
$backup = $this->getPrivateProperty($this, 'iniSettings');
41+
$this->assertSame([], $backup);
42+
}
43+
}

0 commit comments

Comments
 (0)