From a6ec631560a55633ae8dacaaf70d4674bd2b96e6 Mon Sep 17 00:00:00 2001
From: Benni Mack <benni@typo3.org>
Date: Wed, 14 Jun 2017 18:30:36 +0200
Subject: [PATCH] [!!!][TASK] Remove devlog constants

Drop three error related constants from bootstrap:
TYPO3_DLOG, TYPO3_ERROR_DLOG, TYPO3_EXCEPTION_DLOG

Removal of these constants has been prepared in v8
and can be done now. This unblocks further logging
related works.

Along the way, the two TYPO3_CONF_VARS "enable_errorDLOG"
and "enable_exceptionDLOG" can be dropped.

The extension scanner can find usages of these constants,
making the patch not less breaking, but usage detection
within extensions is safe and thus helps a lot to spot them.

A new matcher is added to the extension scanner to
scan for usages of global constants.

Resolves: #82162
Releases: master
Change-Id: I6310866738e5cda79a807239846f64996ec76974
Reviewed-on: https://review.typo3.org/53212
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
---
 .../sysext/backend/Classes/Routing/Router.php |   2 +-
 typo3/sysext/core/Classes/Core/Bootstrap.php  |  15 ---
 .../Configuration/DefaultConfiguration.php    |   2 -
 .../DefaultConfigurationDescription.php       |   4 +-
 ...king-82162-GlobalErrorConstantsRemoved.rst |  43 +++++++
 .../Controller/Action/AbstractAction.php      |   1 -
 .../Action/Ajax/ExtensionScannerScanFile.php  |   5 +
 .../Php/Matcher/ConstantMatcher.php           |  60 ++++++++++
 .../Classes/Service/ClearCacheService.php     |   1 -
 .../SilentConfigurationUpgradeService.php     |  27 +++--
 .../Php/ArrayDimensionMatcher.php             |  10 ++
 .../ExtensionScanner/Php/ConstantMatcher.php  |  18 +++
 .../Php/Matcher/ConstantMatcherTest.php       | 111 ++++++++++++++++++
 .../Fixtures/ConstantMatcherFixture.php       |  33 ++++++
 .../scheduler/Classes/Example/TestTask.php    |   2 -
 15 files changed, 301 insertions(+), 33 deletions(-)
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Breaking-82162-GlobalErrorConstantsRemoved.rst
 create mode 100644 typo3/sysext/install/Classes/ExtensionScanner/Php/Matcher/ConstantMatcher.php
 create mode 100644 typo3/sysext/install/Configuration/ExtensionScanner/Php/ConstantMatcher.php
 create mode 100644 typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/ConstantMatcherTest.php
 create mode 100644 typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/ConstantMatcherFixture.php

diff --git a/typo3/sysext/backend/Classes/Routing/Router.php b/typo3/sysext/backend/Classes/Routing/Router.php
index c520267c3231..db719035b695 100644
--- a/typo3/sysext/backend/Classes/Routing/Router.php
+++ b/typo3/sysext/backend/Classes/Routing/Router.php
@@ -24,7 +24,7 @@ use TYPO3\CMS\Backend\Routing\Exception\ResourceNotFoundException;
  *
  * Ideally, the Router is solely instantiated and accessed via the Bootstrap, the RequestHandler and the UriBuilder.
  *
- * See \TYPO3\CMS\Backend\RequestHandler for more details on route matching() and Bootstrap->initializeBackendRouting().
+ * See \TYPO3\CMS\Backend\Http\RequestHandler for more details on route matching() and Bootstrap->initializeBackendRouting().
  *
  * The architecture is inspired by the Symfony Routing Component.
  */
diff --git a/typo3/sysext/core/Classes/Core/Bootstrap.php b/typo3/sysext/core/Classes/Core/Bootstrap.php
index 79a4b05d29b8..1923f23ca5d5 100644
--- a/typo3/sysext/core/Classes/Core/Bootstrap.php
+++ b/typo3/sysext/core/Classes/Core/Bootstrap.php
@@ -171,7 +171,6 @@ class Bootstrap
             ->loadConfigurationAndInitialize()
             ->loadTypo3LoadedExtAndExtLocalconf(true)
             ->setFinalCachingFrameworkCacheConfiguration()
-            ->defineLoggingAndExceptionConstants()
             ->unsetReservedGlobalVariables()
             ->loadBaseTca();
 
@@ -704,20 +703,6 @@ class Bootstrap
         return $this;
     }
 
-    /**
-     * Define logging and exception constants
-     *
-     * @return Bootstrap
-     * @internal This is not a public API method, do not use in own extensions
-     */
-    public function defineLoggingAndExceptionConstants()
-    {
-        define('TYPO3_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']);
-        define('TYPO3_ERROR_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_errorDLOG']);
-        define('TYPO3_EXCEPTION_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_exceptionDLOG']);
-        return $this;
-    }
-
     /**
      * Unsetting reserved global variables:
      * Those are set in "ext:core/ext_tables.php" file:
diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php
index c801de682e7c..680439a2982f 100644
--- a/typo3/sysext/core/Configuration/DefaultConfiguration.php
+++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php
@@ -219,8 +219,6 @@ return [
         'errorHandler' => \TYPO3\CMS\Core\Error\ErrorHandler::class,
         'errorHandlerErrors' => E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR),
         'exceptionalErrors' => E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR | E_DEPRECATED | E_WARNING | E_USER_ERROR | E_USER_NOTICE | E_USER_WARNING),
-        'enable_errorDLOG' => 0,
-        'enable_exceptionDLOG' => 0, // Boolean: If set,
         'syslogErrorReporting' => E_ALL & ~(E_STRICT | E_NOTICE),
         'belogErrorReporting' => E_ALL & ~(E_STRICT | E_NOTICE),
         'locallangXMLOverride' => [], // For extension/overriding of the arrays in 'locallang' files in frontend  and backend. See 'Inside TYPO3' for more information.
diff --git a/typo3/sysext/core/Configuration/DefaultConfigurationDescription.php b/typo3/sysext/core/Configuration/DefaultConfigurationDescription.php
index de42972f48d5..e13416672cf0 100644
--- a/typo3/sysext/core/Configuration/DefaultConfigurationDescription.php
+++ b/typo3/sysext/core/Configuration/DefaultConfigurationDescription.php
@@ -47,7 +47,7 @@ return [
         'trustedHostsPattern' => 'String: Regular expression pattern that matches all allowed hostnames (including their ports) of this TYPO3 installation, or the string "SERVER_NAME" (default). The default value <code>SERVER_NAME</code> checks if the HTTP Host header equals the SERVER_NAME and SERVER_PORT. This is secure in correctly configured hosting environments and does not need further configuration. If you cannot change your hosting environment, you can enter a regular expression here. Examples: <code>.*\\.domain\\.com</code> matches all hosts that end with <code>.domain.com</code> with all corresponding subdomains. <code>(.*\\.domain|.*\\.otherdomain)\\.com</code> matches all hostnames with subdomains from <code>.domain.com</code> and <code>.otherdomain.com</code>. Be aware that HTTP Host header may also contain a port. If your installation runs on a specific port, you need to explicitly allow this in your pattern, e.g. <code>www\\.domain\\.com:88</code> allows only <code>www.domain.com:88</code>, <strong>not</strong> <code>www.domain.com</code>. To disable this check completely (not recommended because it is <strong>insecure</strong>) you can use ".*" as pattern.',
         'devIPmask' => 'Defines a list of IP addresses which will allow development-output to display. The debug() function will use this as a filter. See the function <code>\\TYPO3\\CMS\\Core\\Utility\\GeneralUtility::cmpIP()</code> for details on syntax. Setting this to blank value will deny all. Setting to "*" will allow all.',
         'sqlDebug' => '<p>Integer (0, 1, 2). Allows displaying executed SQL queries in the browser (for debugging purposes and development)</p><dl><dt>0</dt><dd>no SQL shown (default)</dd><dt>1</dt><dd>show only failed queries</dd><dt>2</dt><dd>show all queries</dd></dl>',
-        'enable_DLOG' => 'Boolean: Whether the developer log is enabled. See constant "TYPO3_DLOG"',
+        'enable_DLOG' => 'Boolean: Whether the developer log is enabled.',
         'ddmmyy' => 'Format of Date-Month-Year - see PHP-function <a href="http://php.net/date" target="_blank">date()</a>',
         'hhmm' => 'Format of Hours-Minutes - see PHP-function <a href="http://php.net/date" target="_blank">date()</a>',
         'USdateFormat' => 'Boolean: If TRUE, dates entered in the TCEforms of the backend will be formatted mm-dd-yyyy',
@@ -79,8 +79,6 @@ return [
         'errorHandler' => 'String: Classname to handle PHP errors. E.g.: TYPO3\\CMS\\Core\\Error\\ErrorHandler. This class displays and logs all errors that are registered as [SYS][errorHandlerErrors]. Leave empty to disable error handling. Errors can be logged to syslog (see: [SYS][systemLog]), to the installed developer log and to the "syslog" table. If an error is registered in [SYS][exceptionalErrors] it will be turned into an exception to be handled by the configured exceptionHandler.',
         'errorHandlerErrors' => 'Integer: The E_* constant that will be handled by the [SYS][errorHandler]. Not all PHP error types can be handled! Default is 30466 = <code>E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR)</code> (see <a href="http://php.net/manual/en/errorfunc.constants.php" target="_blank">PHP documentation</a>).',
         'exceptionalErrors' => 'Integer: The E_* constant that will be converted into an exception by the default [SYS][errorHandler]. Default is 20480 = <code>E_ALL & ~(E_STRICT | E_NOTICE | E_COMPILE_WARNING | E_COMPILE_ERROR | E_CORE_WARNING | E_CORE_ERROR | E_PARSE | E_ERROR | E_DEPRECATED | E_WARNING | E_USER_ERROR | E_USER_NOTICE | E_USER_WARNING)</code> (see <a href="http://php.net/manual/en/errorfunc.constants.php" target="_blank">PHP documentation</a>).',
-        'enable_errorDLOG' => 'Boolean: If set, errors are written to the developer log (requires an installed *devlog* extension).',
-        'enable_exceptionDLOG' => 'Boolean: If set, exceptions are written to the developer log (requires an installed *devlog* extension).',
         'syslogErrorReporting' => 'Integer: Configures which PHP errors should be logged to the configured syslogs (see: [SYS][systemLog]). If set to "0" no PHP errors are logged to the syslog. Default is 30711 = <code>E_ALL & ~(E_STRICT | E_NOTICE)</code> (see <a href="http://php.net/manual/en/errorfunc.constants.php" target="_blank">PHP documentation</a>).',
         'belogErrorReporting' => 'Integer: Configures which PHP errors should be logged to the "syslog" table (extension: belog). If set to "0" no PHP errors are logged to the sys_log table. Default is 30711 = <code>E_ALL & ~(E_STRICT | E_NOTICE)</code> (see <a href="http://php.net/manual/en/errorfunc.constants.php" target="_blank">PHP documentation</a>).',
         'generateApacheHtaccess' => 'Boolean: TYPO3 can create <em>.htaccess</em> files which are used by Apache Webserver. They are useful for access protection or performance improvements. Currently <em>.htaccess</em> files in the following directories are created, if they do not exist: <ul><li>typo3temp/compressor/</li></ul>You want to disable this feature, if you are not running Apache or want to use own rulesets.',
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-82162-GlobalErrorConstantsRemoved.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-82162-GlobalErrorConstantsRemoved.rst
new file mode 100644
index 000000000000..f2ebe8ce8e49
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-82162-GlobalErrorConstantsRemoved.rst
@@ -0,0 +1,43 @@
+.. include:: ../../Includes.txt
+
+=================================================
+Breaking: #82162 - Global error constants removed
+=================================================
+
+See :issue:`82162`
+
+Description
+===========
+
+Three error and logging related constants are no longer defined during TYPO3 core bootstrap:
+* :php:`TYPO3_DLOG`
+* :php:`TYPO3_ERROR_DLOG`
+* :php:`TYPO3_EXCEPTION_DLOG`
+
+Two error and logging related keys have been removed from :php:`TYPO3_CONF_VARS`:
+* :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_errorDLOG']`
+* :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_exceptionDLOG']`
+
+
+Impact
+======
+
+Accessing one of the constants in PHP will return the constants name as value
+which is different to the former value and most likely breaks code depending on it.
+
+
+Affected Installations
+======================
+
+The extension scanner of the install tool finds extensions affected by this change.
+The install tool will automatically remove the :php:`LocalConfiguration.php` settings
+:php:`TYPO3_CONF_VARS` if used.
+
+
+Migration
+=========
+
+Refactor code to not depend on these constants and :php:`TYPO3_CONF_VARS` any longer,
+there shouldn't be many use cases where extensions used these.
+
+.. index:: LocalConfiguration, PHP-API, FullyScanned
\ No newline at end of file
diff --git a/typo3/sysext/install/Classes/Controller/Action/AbstractAction.php b/typo3/sysext/install/Classes/Controller/Action/AbstractAction.php
index dc15e9463da3..3d544bf40e21 100644
--- a/typo3/sysext/install/Classes/Controller/Action/AbstractAction.php
+++ b/typo3/sysext/install/Classes/Controller/Action/AbstractAction.php
@@ -193,7 +193,6 @@ abstract class AbstractAction implements ActionInterface
         \TYPO3\CMS\Core\Core\Bootstrap::getInstance()
             ->ensureClassLoadingInformationExists()
             ->loadTypo3LoadedExtAndExtLocalconf(false)
-            ->defineLoggingAndExceptionConstants()
             ->unsetReservedGlobalVariables()
             ->loadBaseTca(false)
             ->loadExtTables(false);
diff --git a/typo3/sysext/install/Classes/Controller/Action/Ajax/ExtensionScannerScanFile.php b/typo3/sysext/install/Classes/Controller/Action/Ajax/ExtensionScannerScanFile.php
index afb22fa05a39..09120f6a8e0f 100644
--- a/typo3/sysext/install/Classes/Controller/Action/Ajax/ExtensionScannerScanFile.php
+++ b/typo3/sysext/install/Classes/Controller/Action/Ajax/ExtensionScannerScanFile.php
@@ -28,6 +28,7 @@ use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ArrayDimensionMatcher;
 use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ArrayGlobalMatcher;
 use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ClassConstantMatcher;
 use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ClassNameMatcher;
+use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ConstantMatcher;
 use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\InterfaceMethodChangedMatcher;
 use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentDroppedMatcher;
 use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\MethodArgumentDroppedStaticMatcher;
@@ -65,6 +66,10 @@ class ExtensionScannerScanFile extends AbstractAjaxAction
             'class' => ClassNameMatcher::class,
             'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php',
         ],
+        [
+            'class' => ConstantMatcher::class,
+            'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/ConstantMatcher.php',
+        ],
         [
             'class' => InterfaceMethodChangedMatcher::class,
             'configurationFile' => 'EXT:install/Configuration/ExtensionScanner/Php/InterfaceMethodChangedMatcher.php',
diff --git a/typo3/sysext/install/Classes/ExtensionScanner/Php/Matcher/ConstantMatcher.php b/typo3/sysext/install/Classes/ExtensionScanner/Php/Matcher/ConstantMatcher.php
new file mode 100644
index 000000000000..850fe4b7d8c6
--- /dev/null
+++ b/typo3/sysext/install/Classes/ExtensionScanner/Php/Matcher/ConstantMatcher.php
@@ -0,0 +1,60 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Install\ExtensionScanner\Php\Matcher;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use PhpParser\Node;
+use PhpParser\Node\Expr\ConstFetch;
+
+/**
+ * Find usages of class constants.
+ *
+ * Test for "THE_CONSTANT", matches are considered "strong"
+ */
+class ConstantMatcher extends AbstractCoreMatcher
+{
+    /**
+     * Validate config
+     *
+     * @param array $matcherDefinitions Incoming main configuration
+     */
+    public function __construct(array $matcherDefinitions)
+    {
+        $this->matcherDefinitions = $matcherDefinitions;
+        $this->validateMatcherDefinitions();
+    }
+
+    /**
+     * Called by PhpParser.
+     *
+     * @param Node $node
+     */
+    public function enterNode(Node $node)
+    {
+        if (!$this->isFileIgnored($node)
+            && !$this->isLineIgnored($node)
+            && $node instanceof ConstFetch
+            && in_array($node->name->toString(), array_keys($this->matcherDefinitions), true)
+        ) {
+            // Access to constants is detected as strong match
+            $this->matches[] = [
+                'restFiles' => $this->matcherDefinitions[$node->name->toString()]['restFiles'],
+                'line' => $node->getAttribute('startLine'),
+                'message' => 'Call to global constant "' . $node->name->toString() . '"',
+                'indicator' => 'strong',
+            ];
+        }
+    }
+}
diff --git a/typo3/sysext/install/Classes/Service/ClearCacheService.php b/typo3/sysext/install/Classes/Service/ClearCacheService.php
index 7f2f50a6ec38..b48ca133865e 100644
--- a/typo3/sysext/install/Classes/Service/ClearCacheService.php
+++ b/typo3/sysext/install/Classes/Service/ClearCacheService.php
@@ -71,7 +71,6 @@ class ClearCacheService
         // Use bootstrap to load all ext_localconf and ext_tables
         $bootstrap
             ->loadTypo3LoadedExtAndExtLocalconf(false)
-            ->defineLoggingAndExceptionConstants()
             ->unsetReservedGlobalVariables()
             ->loadBaseTca(false)
             ->loadExtTables(false);
diff --git a/typo3/sysext/install/Classes/Service/SilentConfigurationUpgradeService.php b/typo3/sysext/install/Classes/Service/SilentConfigurationUpgradeService.php
index 4880a65e0a79..028cc33ed758 100644
--- a/typo3/sysext/install/Classes/Service/SilentConfigurationUpgradeService.php
+++ b/typo3/sysext/install/Classes/Service/SilentConfigurationUpgradeService.php
@@ -97,6 +97,9 @@ class SilentConfigurationUpgradeService
         // #80711
         'FE/noPHPscriptInclude',
         'FE/maxSessionDataSize',
+        // #82162
+        'SYS/enable_errorDLOG',
+        'SYS/enable_exceptionDLOG',
     ];
 
     public function __construct(ConfigurationManager $configurationManager = null)
@@ -162,8 +165,10 @@ class SilentConfigurationUpgradeService
             }
         } catch (\RuntimeException $e) {
             // If an exception is thrown, the value is not set in LocalConfiguration
-            $this->configurationManager->setLocalConfigurationValueByPath('BE/loginSecurityLevel',
-                $rsaauthLoaded ? 'rsa' : 'normal');
+            $this->configurationManager->setLocalConfigurationValueByPath(
+                'BE/loginSecurityLevel',
+                $rsaauthLoaded ? 'rsa' : 'normal'
+            );
             $this->throwRedirectException();
         }
     }
@@ -526,22 +531,28 @@ class SilentConfigurationUpgradeService
         if (!empty($changedSettings['GFX/im_noScaleUp'])) {
             $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noScaleUp');
             $newProcessorValue = !$currentProcessorValue;
-            $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor_allowUpscaling',
-                $newProcessorValue);
+            $this->configurationManager->setLocalConfigurationValueByPath(
+                'GFX/processor_allowUpscaling',
+                $newProcessorValue
+            );
         }
 
         if (!empty($changedSettings['GFX/im_noFramePrepended'])) {
             $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_noFramePrepended');
             $newProcessorValue = !$currentProcessorValue;
-            $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor_allowFrameSelection',
-                $newProcessorValue);
+            $this->configurationManager->setLocalConfigurationValueByPath(
+                'GFX/processor_allowFrameSelection',
+                $newProcessorValue
+            );
         }
 
         if (!empty($changedSettings['GFX/im_mask_temp_ext_gif'])) {
             $currentProcessorValue = $this->configurationManager->getLocalConfigurationValueByPath('GFX/im_mask_temp_ext_gif');
             $newProcessorValue = !$currentProcessorValue;
-            $this->configurationManager->setLocalConfigurationValueByPath('GFX/processor_allowTemporaryMasksAsPng',
-                $newProcessorValue);
+            $this->configurationManager->setLocalConfigurationValueByPath(
+                'GFX/processor_allowTemporaryMasksAsPng',
+                $newProcessorValue
+            );
         }
 
         if (!empty(array_filter($changedSettings))) {
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php
index 627680c8b489..28b6c1a7477c 100644
--- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php
@@ -24,6 +24,16 @@ return [
             'Deprecation-80583-TYPO3_CONF_VARS_extensionAdded.rst',
         ],
     ],
+    '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'enable_errorDLOG\']' => [
+        'restFiles' => [
+            'Breaking-82162-GlobalErrorConstantsRemoved.rst',
+        ],
+    ],
+    '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'enable_exceptionDLOG\']' => [
+        'restFiles' => [
+            'Breaking-82162-GlobalErrorConstantsRemoved.rst',
+        ],
+    ],
 
     // Hooks
     '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'t3lib/class.t3lib_befunc.php\'][\'getFlexFormDSClass\']' => [
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ConstantMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ConstantMatcher.php
new file mode 100644
index 000000000000..0adf5066f910
--- /dev/null
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ConstantMatcher.php
@@ -0,0 +1,18 @@
+<?php
+return [
+    'TYPO3_DLOG' => [
+        'restFiles' => [
+            'Breaking-82162-GlobalErrorConstantsRemoved.rst',
+        ],
+    ],
+    'TYPO3_ERROR_DLOG' => [
+        'restFiles' => [
+            'Breaking-82162-GlobalErrorConstantsRemoved.rst',
+        ],
+    ],
+    'TYPO3_EXCEPTION_DLOG' => [
+        'restFiles' => [
+            'Breaking-82162-GlobalErrorConstantsRemoved.rst',
+        ],
+    ],
+];
diff --git a/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/ConstantMatcherTest.php b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/ConstantMatcherTest.php
new file mode 100644
index 000000000000..c530926cd51b
--- /dev/null
+++ b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/ConstantMatcherTest.php
@@ -0,0 +1,111 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Install\Tests\Unit\ExtensionScanner\Php\Matcher;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use PhpParser\NodeTraverser;
+use PhpParser\NodeVisitor\NameResolver;
+use PhpParser\ParserFactory;
+use TYPO3\CMS\Install\ExtensionScanner\Php\GeneratorClassesResolver;
+use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\ConstantMatcher;
+use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
+
+/**
+ * Test case
+ */
+class ConstantMatcherTest extends UnitTestCase
+{
+    /**
+     * @test
+     */
+    public function hitsFromFixtureAreFound()
+    {
+        $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
+        $fixtureFile = __DIR__ . '/Fixtures/ConstantMatcherFixture.php';
+        $statements = $parser->parse(file_get_contents($fixtureFile));
+
+        $traverser = new NodeTraverser();
+        $traverser->addVisitor(new NameResolver());
+        $traverser->addVisitor(new GeneratorClassesResolver());
+
+        $configuration = [
+            'TYPO3_DLOG' => [
+                'restFiles' => [
+                    'Breaking-82162-GlobalErrorConstantsRemoved.rst',
+                ],
+            ],
+        ];
+        $subject = new ConstantMatcher($configuration);
+        $traverser->addVisitor($subject);
+        $traverser->traverse($statements);
+        $expectedHitLineNumbers = [
+            26,
+        ];
+        $actualHitLineNumbers = [];
+        foreach ($subject->getMatches() as $hit) {
+            $actualHitLineNumbers[] = $hit['line'];
+        }
+        $this->assertEquals($expectedHitLineNumbers, $actualHitLineNumbers);
+    }
+
+    /**
+     * @return array
+     */
+    public function matchesReturnsExpectedRestFilesDataProvider()
+    {
+        return [
+            'a straight match' => [
+                [
+                    'aConstant' => [
+                        'restFiles' => [
+                            'Foo-1.rst',
+                            'Foo-2.rst',
+                        ],
+                    ],
+                ],
+                '<?php
+                $foo = aConstant;',
+                [
+                    0 => [
+                        'restFiles' => [
+                            'Foo-1.rst',
+                            'Foo-2.rst',
+                        ],
+                    ],
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider matchesReturnsExpectedRestFilesDataProvider
+     */
+    public function matchesReturnsExpectedRestFiles(array $configuration, string $phpCode, array $expected)
+    {
+        $parser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7);
+        $statements = $parser->parse($phpCode);
+
+        $subject = new ConstantMatcher($configuration);
+
+        $traverser = new NodeTraverser();
+        $traverser->addVisitor(new NameResolver());
+        $traverser->addVisitor($subject);
+        $traverser->traverse($statements);
+
+        $result = $subject->getMatches();
+        $this->assertSame($expected[0]['restFiles'], $result[0]['restFiles']);
+    }
+}
diff --git a/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/ConstantMatcherFixture.php b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/ConstantMatcherFixture.php
new file mode 100644
index 000000000000..2d2d82283a0c
--- /dev/null
+++ b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/ConstantMatcherFixture.php
@@ -0,0 +1,33 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Install\Tests\Unit\ExtensionScanner\Php\Matcher\Fixtures;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Fixture file
+ */
+class ConstantMatcherFixture
+{
+    public function aMethod()
+    {
+        // Matches
+        $foo = TYPO3_DLOG;
+
+        // No match
+        $foo = \My\Project\AClass::TYPO3_DLOG;
+        // @extensionScannerIgnoreLine
+        $foo = TYPO3_DLOG;
+    }
+}
diff --git a/typo3/sysext/scheduler/Classes/Example/TestTask.php b/typo3/sysext/scheduler/Classes/Example/TestTask.php
index 97cf7fbb023b..47cfe1dc9f6d 100644
--- a/typo3/sysext/scheduler/Classes/Example/TestTask.php
+++ b/typo3/sysext/scheduler/Classes/Example/TestTask.php
@@ -37,8 +37,6 @@ class TestTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
         $success = false;
         if (!empty($this->email)) {
             // If an email address is defined, send a message to it
-            // NOTE: the TYPO3_DLOG constant is not used in this case, as this is a test task
-            // and debugging is its main purpose anyway
             \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[TYPO3\\CMS\\Scheduler\\Example\\TestTask]: Test email sent to "' . $this->email . '"', 'scheduler', 0);
             // Get execution information
             $exec = $this->getExecution();
-- 
GitLab