Repository: codeigniter4/CodeIgniter4 (PHP)

Issue:
Bug:  KINT `d()` visual error in debugging when activating CSP
### PHP Version

7.4

### CodeIgniter4 Version

4.1.5

### CodeIgniter4 Installation Method

Manual (zip or tar.gz)

### Which operating systems have you tested for this bug?

Windows

### Which server did you use?

apache

### Database

_No response_

### What happened?

kint-rich-script and kint-rich-style in RichRenderer.php inside thirdparty KIN need to put {csp-style-nonce} and {csp-script-nonce} because when "CONTENT SECURITY POLICY" is activated it disables it for security for the same. What causes that being in debug mode with CSP activated disables its visual style.



### Steps to Reproduce

Activate developer mode and CSP.

Use `d('example');` in some controller to debug

### Expected Output

Being able to see the theme used by kint in the web browser for debugging

### Anything else?

into folder _system/ThirdParty/Kint/Renderer/_ in file **RichRenderer.php** into line 383 a 392

`                switch ($type) {
                    case 'script':
                        $output .= '<script class="kint-rich-script">'.$contents.'</script>';
                        break;
                    case 'style':
                        $output .= '<style class="kint-rich-style">'.$contents.'</style>';
                        break;
                    default:
                        $output .= $contents;
                }`

replace by:

`switch ($type) {
                    case 'script':
                        $output .= '<script {csp-script-nonce} class="kint-rich-script">'.$contents.'</script>';
                        break;
                    case 'style':
                        $output .= '<style {csp-style-nonce} class="kint-rich-style">'.$contents.'</style>';
                        break;
                    default:
                        $output .= $contents;
                }`

To return the visual style of KINT when CSP is activated



Discussion:
@davidalmaraz Thank you for reporitng.
I've confirm this behavior.

But Kint is a third party library, so we can't change files in it.

The workaround is to use `dd()` instead of `d()`.

`app/Common.php`:
```php
function d(...$vars)
{
    Kint::$aliases[] = 'd';

    ob_start();
    Kint::dump(...$vars);
    $output = ob_get_clean();

    /** @var \Config\App $config */
    $config = config('App');

    if ($config->CSPEnabled === true) {
        $output = str_replace('<script ', '<script {csp-script-nonce} ', $output);
        $output = str_replace('<style ', '<style {csp-style-nonce} ', $output);
    }

    echo $output;
}
```

Kint has magical Modifiers:
https://kint-php.github.io/kint/advanced/

If you use the wrapper functions (or CI4 provides them), the Modifiers do not work.

This should be handled by Kint.

@davidalmaraz 
I created another PR. It works Kint Modifiers.
See  #5501

@kenjis 
Thank you very much, it worked for me to overwrite the function inside the common controller but I liked the one in
override RichRenderer :: preRender () #5501


#5501 was merged into develop.




Patch:
diff --git a/rector.php b/rector.php
index 8be24cd7024d..68d16bbb66e4 100644
--- a/rector.php
+++ b/rector.php
@@ -71,6 +71,7 @@
     $parameters->set(Option::SKIP, [
         __DIR__ . '/app/Views',
         __DIR__ . '/system/Debug/Toolbar/Views/toolbar.tpl.php',
+        __DIR__ . '/system/Debug/Kint/RichRenderer.php',
         __DIR__ . '/system/ThirdParty',
         __DIR__ . '/tests/system/Config/fixtures',
         __DIR__ . '/tests/_support',
diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php
index d309ca81c27a..56cb0df4b7bd 100644
--- a/system/CodeIgniter.php
+++ b/system/CodeIgniter.php
@@ -12,6 +12,7 @@
 namespace CodeIgniter;
 
 use Closure;
+use CodeIgniter\Debug\Kint\RichRenderer;
 use CodeIgniter\Debug\Timer;
 use CodeIgniter\Events\Events;
 use CodeIgniter\Exceptions\FrameworkException;
@@ -33,7 +34,6 @@
 use Exception;
 use Kint;
 use Kint\Renderer\CliRenderer;
-use Kint\Renderer\RichRenderer;
 
 /**
  * This class is the core of the framework, and will analyse the
@@ -257,6 +257,8 @@ protected function initializeKint()
             Kint::$plugins = $config->plugins;
         }
 
+        Kint::$renderers[Kint::MODE_RICH] = RichRenderer::class;
+
         RichRenderer::$theme  = $config->richTheme;
         RichRenderer::$folder = $config->richFolder;
         RichRenderer::$sort   = $config->richSort;
diff --git a/system/Debug/Kint/RichRenderer.php b/system/Debug/Kint/RichRenderer.php
new file mode 100644
index 000000000000..756cac75e144
--- /dev/null
+++ b/system/Debug/Kint/RichRenderer.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * This file is part of CodeIgniter 4 framework.
+ *
+ * (c) CodeIgniter Foundation <admin@codeigniter.com>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace CodeIgniter\Debug\Kint;
+
+use Kint\Renderer\RichRenderer as KintRichRenderer;
+
+/**
+ * Overrides RichRenderer::preRender() for CSP
+ */
+class RichRenderer extends KintRichRenderer
+{
+    public function preRender()
+    {
+        $output = '';
+
+        if ($this->pre_render) {
+            foreach (self::$pre_render_sources as $type => $values) {
+                $contents = '';
+
+                foreach ($values as $v) {
+                    $contents .= $v($this);
+                }
+
+                if (! \strlen($contents)) {
+                    continue;
+                }
+
+                switch ($type) {
+                    case 'script':
+                        $output .= '<script {csp-script-nonce} class="kint-rich-script">' . $contents . '</script>';
+                        break;
+
+                    case 'style':
+                        $output .= '<style {csp-style-nonce} class="kint-rich-style">' . $contents . '</style>';
+                        break;
+
+                    default:
+                        $output .= $contents;
+                }
+            }
+
+            // Don't pre-render on every dump
+            if (! $this->force_pre_render) {
+                self::$needs_pre_render = false;
+            }
+        }
+
+        $output .= '<div class="kint-rich';
+
+        if ($this->use_folder) {
+            $output .= ' kint-file';
+
+            if (self::$needs_folder_render || $this->force_pre_render) {
+                $output = $this->renderFolder() . $output;
+
+                if (! $this->force_pre_render) {
+                    self::$needs_folder_render = false;
+                }
+            }
+        }
+
+        $output .= '">';
+
+        return $output;
+    }
+}


Test patch:
diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php
index c6f1d6b9b2e1..b7f4f381c233 100644
--- a/tests/system/CommonFunctionsTest.php
+++ b/tests/system/CommonFunctionsTest.php
@@ -29,6 +29,7 @@
 use Config\Logger;
 use Config\Modules;
 use InvalidArgumentException;
+use Kint;
 use stdClass;
 use Tests\Support\Models\JobModel;
 
@@ -482,4 +483,37 @@ public function testIsCli()
         $this->assertIsBool(is_cli());
         $this->assertTrue(is_cli());
     }
+
+    public function testDWithCSP()
+    {
+        /** @var App $config */
+        $config       = config(App::class);
+        $CSPEnabled   = $config->CSPEnabled;
+        $cliDetection = Kint::$cli_detection;
+
+        $config->CSPEnabled  = true;
+        Kint::$cli_detection = false;
+
+        $this->expectOutputRegex('/<script {csp-script-nonce} class="kint-rich-script">/u');
+        d('string');
+
+        // Restore settings
+        $config->CSPEnabled  = $CSPEnabled;
+        Kint::$cli_detection = $cliDetection;
+    }
+
+    /**
+     * @runInSeparateProcess
+     * @preserveGlobalState  disabled
+     */
+    public function testTraceWithCSP()
+    {
+        /** @var App $config */
+        $config              = config(App::class);
+        $config->CSPEnabled  = true;
+        Kint::$cli_detection = false;
+
+        $this->expectOutputRegex('/<style {csp-style-nonce} class="kint-rich-style">/u');
+        trace();
+    }
 }