From 688c8bab17bb59bde9d09e9ae0342bc6503074e1 Mon Sep 17 00:00:00 2001 From: michalsn Date: Fri, 5 Jan 2024 10:47:43 +0100 Subject: [PATCH 1/6] fix: highlightFile() in BaseExceptionHandler --- system/Debug/BaseExceptionHandler.php | 18 ++++++++++++++---- tests/_support/Debug/highlightFile.html | 16 ++++++++++++++++ .../Debug/highlightFile_pre_8_3_0.html | 16 ++++++++++++++++ tests/system/Debug/ExceptionHandlerTest.php | 13 +++++++++++++ 4 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 tests/_support/Debug/highlightFile.html create mode 100644 tests/_support/Debug/highlightFile_pre_8_3_0.html diff --git a/system/Debug/BaseExceptionHandler.php b/system/Debug/BaseExceptionHandler.php index 33dd126ff1ec..a751aed3a1f2 100644 --- a/system/Debug/BaseExceptionHandler.php +++ b/system/Debug/BaseExceptionHandler.php @@ -180,9 +180,16 @@ protected static function highlightFile(string $file, int $lineNumber, int $line return false; } - $source = str_replace(["\r\n", "\r"], "\n", $source); - $source = explode("\n", highlight_string($source, true)); - $source = str_replace('
', "\n", $source[1]); + if (version_compare(PHP_VERSION, '8.3.0', '<')) { + $source = str_replace(["\r\n", "\r"], "\n", $source); + $source = explode("\n", highlight_string($source, true)); + $source = str_replace('
', "\n", $source[1]); + } else { + $source = highlight_string($source, true); + // We have to remove these tags since we're preparing the result + // ourselves and these tags are added manually at the end. + $source = str_replace(['
', '
'], '', $source); + } $source = explode("\n", str_replace("\r\n", "\n", $source)); // Get just the part to show @@ -199,7 +206,7 @@ protected static function highlightFile(string $file, int $lineNumber, int $line // of open and close span tags on one line, we need // to ensure we can close them all to get the lines // showing correctly. - $spans = 1; + $spans = 0; foreach ($source as $n => $row) { $spans += substr_count($row, '' . $format . ' %s', $n + $start + 1, $row) . "\n"; + // We're closing only one span tag we added manually line before, + // so we have to increment $spans count to close this tag later. + $spans++; } } diff --git a/tests/_support/Debug/highlightFile.html b/tests/_support/Debug/highlightFile.html new file mode 100644 index 000000000000..a9eef9fe5b2c --- /dev/null +++ b/tests/_support/Debug/highlightFile.html @@ -0,0 +1,16 @@ +
 9  * the LICENSE file that was distributed with this source code.
+10  */
+11 
+12 namespace Tests\Support\Controllers;
+13 
+14 use CodeIgniter\Controller;
+15 
+16 class Hello extends Controller
+17 {
+18     public function index()
+19     {
+20         return 'Hello';
+21     }
+22 }
+23 
+
\ No newline at end of file diff --git a/tests/_support/Debug/highlightFile_pre_8_3_0.html b/tests/_support/Debug/highlightFile_pre_8_3_0.html new file mode 100644 index 000000000000..4fb3633f2861 --- /dev/null +++ b/tests/_support/Debug/highlightFile_pre_8_3_0.html @@ -0,0 +1,16 @@ +
 9  * the LICENSE file that was distributed with this source code.
+10  */
+11 
+12 namespace Tests\Support\Controllers;
+13 
+14 use CodeIgniter\Controller;
+15 
+16 class Hello extends Controller
+17 {
+18     public function index()
+19     {
+20         return 'Hello';
+21     }
+22 }
+23 
+
\ No newline at end of file diff --git a/tests/system/Debug/ExceptionHandlerTest.php b/tests/system/Debug/ExceptionHandlerTest.php index 1321f67195f3..dba00a6952af 100644 --- a/tests/system/Debug/ExceptionHandlerTest.php +++ b/tests/system/Debug/ExceptionHandlerTest.php @@ -237,4 +237,17 @@ public function testMaskSensitiveDataTraceDataKey(): void $this->assertSame('/var/www/CodeIgniter4/app/Controllers/Home.php', $newTrace[0]['file']); } + + public function testHighlightFile(): void + { + $highlightFile = $this->getPrivateMethodInvoker($this->handler, 'highlightFile'); + $result = $highlightFile(SUPPORTPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Hello.php', 16); + $resultFile = version_compare(PHP_VERSION, '8.3.0', '<') ? + 'highlightFile_pre_8_3_0.html' : + 'highlightFile.html'; + + $expected = file_get_contents(SUPPORTPATH . 'Debug' . DIRECTORY_SEPARATOR . $resultFile); + + $this->assertSame($expected, $result); + } } From 0cf729d15af4d9e83a44adb66f3583632c8e07a8 Mon Sep 17 00:00:00 2001 From: michalsn Date: Fri, 5 Jan 2024 10:56:11 +0100 Subject: [PATCH 2/6] updates for $source handling based on kenjis PR --- system/Debug/BaseExceptionHandler.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/system/Debug/BaseExceptionHandler.php b/system/Debug/BaseExceptionHandler.php index a751aed3a1f2..6a5b5e47e5c7 100644 --- a/system/Debug/BaseExceptionHandler.php +++ b/system/Debug/BaseExceptionHandler.php @@ -180,17 +180,17 @@ protected static function highlightFile(string $file, int $lineNumber, int $line return false; } - if (version_compare(PHP_VERSION, '8.3.0', '<')) { - $source = str_replace(["\r\n", "\r"], "\n", $source); - $source = explode("\n", highlight_string($source, true)); + $source = str_replace(["\r\n", "\r"], "\n", $source); + $source = explode("\n", highlight_string($source, true)); + + if (PHP_VERSION_ID < 80300) { $source = str_replace('
', "\n", $source[1]); + $source = explode("\n", str_replace("\r\n", "\n", $source)); } else { - $source = highlight_string($source, true); // We have to remove these tags since we're preparing the result // ourselves and these tags are added manually at the end. $source = str_replace(['
', '
'], '', $source); } - $source = explode("\n", str_replace("\r\n", "\n", $source)); // Get just the part to show $start = max($lineNumber - (int) round($lines / 2), 0); From 3eac5abce733f394ec0f7a0635d23f9d54b950d5 Mon Sep 17 00:00:00 2001 From: michalsn Date: Fri, 5 Jan 2024 13:37:58 +0100 Subject: [PATCH 3/6] add IniTestTrait to easy backup ini values --- system/Test/IniTestTrait.php | 33 +++++++++++++++ ..._3_0.html => highlightFile_pre_80300.html} | 0 tests/system/Debug/ExceptionHandlerTest.php | 12 +++++- tests/system/Test/IniTestTraitTest.php | 41 +++++++++++++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 system/Test/IniTestTrait.php rename tests/_support/Debug/{highlightFile_pre_8_3_0.html => highlightFile_pre_80300.html} (100%) create mode 100644 tests/system/Test/IniTestTraitTest.php diff --git a/system/Test/IniTestTrait.php b/system/Test/IniTestTrait.php new file mode 100644 index 000000000000..5820cfc1a71e --- /dev/null +++ b/system/Test/IniTestTrait.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Test; + +trait IniTestTrait +{ + private array $iniSettings = []; + + private function backupIniValues(array $keys): void + { + foreach ($keys as $key) { + $this->iniSettings[$key] = ini_get($key); + } + } + + private function restoreIniValues(): void + { + foreach ($this->iniSettings as $key => $value) { + ini_set($key, $value); + } + + $this->iniSettings = []; + } +} diff --git a/tests/_support/Debug/highlightFile_pre_8_3_0.html b/tests/_support/Debug/highlightFile_pre_80300.html similarity index 100% rename from tests/_support/Debug/highlightFile_pre_8_3_0.html rename to tests/_support/Debug/highlightFile_pre_80300.html diff --git a/tests/system/Debug/ExceptionHandlerTest.php b/tests/system/Debug/ExceptionHandlerTest.php index dba00a6952af..f5eba44ed591 100644 --- a/tests/system/Debug/ExceptionHandlerTest.php +++ b/tests/system/Debug/ExceptionHandlerTest.php @@ -14,6 +14,7 @@ use App\Controllers\Home; use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\Test\CIUnitTestCase; +use CodeIgniter\Test\IniTestTrait; use CodeIgniter\Test\StreamFilterTrait; use Config\Exceptions as ExceptionsConfig; use Config\Services; @@ -27,6 +28,7 @@ final class ExceptionHandlerTest extends CIUnitTestCase { use StreamFilterTrait; + use IniTestTrait; private ExceptionHandler $handler; @@ -240,14 +242,20 @@ public function testMaskSensitiveDataTraceDataKey(): void public function testHighlightFile(): void { + $this->backupIniValues([ + 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string', + ]); + $highlightFile = $this->getPrivateMethodInvoker($this->handler, 'highlightFile'); $result = $highlightFile(SUPPORTPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Hello.php', 16); - $resultFile = version_compare(PHP_VERSION, '8.3.0', '<') ? - 'highlightFile_pre_8_3_0.html' : + $resultFile = PHP_VERSION_ID < 80300 ? + 'highlightFile_pre_80300.html' : 'highlightFile.html'; $expected = file_get_contents(SUPPORTPATH . 'Debug' . DIRECTORY_SEPARATOR . $resultFile); $this->assertSame($expected, $result); + + $this->restoreIniValues(); } } diff --git a/tests/system/Test/IniTestTraitTest.php b/tests/system/Test/IniTestTraitTest.php new file mode 100644 index 000000000000..7881af978614 --- /dev/null +++ b/tests/system/Test/IniTestTraitTest.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Test; + +use ReflectionException; + +/** + * @internal + */ +final class IniTestTraitTest extends CIUnitTestCase +{ + use IniTestTrait; + + /** + * @throws ReflectionException + */ + public function testBackupAndRestoreIniValues(): void + { + $this->backupIniValues(['highlight.default']); + $backup = $this->getPrivateProperty($this, 'iniSettings'); + $this->assertSame('#0000BB', $backup['highlight.default']); + + ini_set('highlight.default', '#FFFFFF'); + $this->assertSame('#FFFFFF', ini_get('highlight.default')); + + $this->restoreIniValues(); + $this->assertSame('#0000BB', ini_get('highlight.default')); + + $backup = $this->getPrivateProperty($this, 'iniSettings'); + $this->assertSame([], $backup); + } +} From e98dcfd82980032ad167567ac3bfc0cf1704ce74 Mon Sep 17 00:00:00 2001 From: michalsn Date: Fri, 5 Jan 2024 13:48:25 +0100 Subject: [PATCH 4/6] add group to the IniTestTratiTest --- tests/system/Test/IniTestTraitTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/system/Test/IniTestTraitTest.php b/tests/system/Test/IniTestTraitTest.php index 7881af978614..e1c9a9a6f7c0 100644 --- a/tests/system/Test/IniTestTraitTest.php +++ b/tests/system/Test/IniTestTraitTest.php @@ -15,6 +15,8 @@ /** * @internal + * + * @group Others */ final class IniTestTraitTest extends CIUnitTestCase { From f9bd4da1562876097762ef290569193ab96ebb69 Mon Sep 17 00:00:00 2001 From: michalsn Date: Sat, 6 Jan 2024 09:09:19 +0100 Subject: [PATCH 5/6] add separate results for PHP 7.4 --- .../_support/Debug/highlightFile_pre_80000.html | 16 ++++++++++++++++ tests/system/Debug/ExceptionHandlerTest.php | 16 +++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 tests/_support/Debug/highlightFile_pre_80000.html diff --git a/tests/_support/Debug/highlightFile_pre_80000.html b/tests/_support/Debug/highlightFile_pre_80000.html new file mode 100644 index 000000000000..6b83117b9c97 --- /dev/null +++ b/tests/_support/Debug/highlightFile_pre_80000.html @@ -0,0 +1,16 @@ +
 9  * the LICENSE file that was distributed with this source code.
+10  */
+11
+12 namespace Tests\Support\Controllers;
+13
+14 use CodeIgniter\Controller;
+15
+16 class Hello extends Controller
+17 {
+18     public function index()
+19     {
+20         return 'Hello';
+21     }
+22 }
+23 
+
diff --git a/tests/system/Debug/ExceptionHandlerTest.php b/tests/system/Debug/ExceptionHandlerTest.php index f5eba44ed591..8dcad8e6c338 100644 --- a/tests/system/Debug/ExceptionHandlerTest.php +++ b/tests/system/Debug/ExceptionHandlerTest.php @@ -248,9 +248,19 @@ public function testHighlightFile(): void $highlightFile = $this->getPrivateMethodInvoker($this->handler, 'highlightFile'); $result = $highlightFile(SUPPORTPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Hello.php', 16); - $resultFile = PHP_VERSION_ID < 80300 ? - 'highlightFile_pre_80300.html' : - 'highlightFile.html'; + + switch (true) { + case PHP_VERSION_ID < 80000: + $resultFile = 'highlightFile_pre_80000.html'; + break; + + case PHP_VERSION_ID < 80300: + $resultFile = 'highlightFile_pre_80300.html'; + break; + + default: + $resultFile = 'highlightFile.html'; + } $expected = file_get_contents(SUPPORTPATH . 'Debug' . DIRECTORY_SEPARATOR . $resultFile); From d558f09551aac247420838746022f201fddb37e3 Mon Sep 17 00:00:00 2001 From: michalsn Date: Sat, 6 Jan 2024 09:56:57 +0100 Subject: [PATCH 6/6] update separate results for PHP 7.4 --- tests/_support/Debug/highlightFile_pre_80000.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/_support/Debug/highlightFile_pre_80000.html b/tests/_support/Debug/highlightFile_pre_80000.html index 6b83117b9c97..4b4ad7cecf34 100644 --- a/tests/_support/Debug/highlightFile_pre_80000.html +++ b/tests/_support/Debug/highlightFile_pre_80000.html @@ -1,10 +1,10 @@
 9  * the LICENSE file that was distributed with this source code.
 10  */
-11
+11 
 12 namespace Tests\Support\Controllers;
-13
+13 
 14 use CodeIgniter\Controller;
-15
+15 
 16 class Hello extends Controller
 17 {
 18     public function index()
@@ -13,4 +13,4 @@
 21     }
 22 }
 23 
-
+ \ No newline at end of file