diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
index 4559d5eb920a98c5152c2c558d5652224318acd1..abf4edc13545bf0b407d95155024b6d81917200d 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
@@ -3127,8 +3127,9 @@ class ContentObjectRenderer implements LoggerAwareInterface
         $stripNL = 0;
         $contentAccum = [];
         $contentAccumP = 0;
-        $allowTags = strtolower(str_replace(' ', '', $conf['allowTags'] ?? ''));
-        $denyTags = strtolower(str_replace(' ', '', $conf['denyTags'] ?? ''));
+
+        $allowTags = GeneralUtility::trimExplode(',', strtolower($conf['allowTags'] ?? ''), true);
+        $denyTags = GeneralUtility::trimExplode(',', strtolower($conf['denyTags'] ?? ''), true);
         $totalLen = strlen($theValue);
         do {
             if (!$inside) {
@@ -3150,58 +3151,54 @@ class ContentObjectRenderer implements LoggerAwareInterface
                 // $data is the content until the next <tag-start or end is detected.
                 // In case of a currentTag set, this would mean all data between the start- and end-tags
                 $data = substr($theValue, $pointer, $len);
-                if ($data !== false) {
-                    if ($stripNL) {
-                        // If the previous tag was set to strip NewLines in the beginning of the next data-chunk.
-                        $data = preg_replace('/^[ ]*' . CR . '?' . LF . '/', '', $data);
-                        if ($data === null) {
-                            $this->logger->debug('Stripping new lines failed for "{data}"', ['data' => $data]);
-                            $data = '';
-                        }
+                if ($stripNL) {
+                    // If the previous tag was set to strip NewLines in the beginning of the next data-chunk.
+                    $data = preg_replace('/^[ ]*' . CR . '?' . LF . '/', '', $data);
+                    if ($data === null) {
+                        $this->logger->debug('Stripping new lines failed for "{data}"', ['data' => $data]);
+                        $data = '';
                     }
-                    // These operations should only be performed on code outside the tags...
-                    if (!is_array($currentTag)) {
-                        // Short
-                        if (isset($conf['short.']) && is_array($conf['short.'])) {
-                            $shortWords = $conf['short.'];
-                            krsort($shortWords);
-                            foreach ($shortWords as $key => $val) {
-                                if (is_string($val)) {
-                                    $data = str_replace($key, $val, $data);
-                                }
+                }
+                // These operations should only be performed on code outside the tags...
+                if (!is_array($currentTag)) {
+                    // Short
+                    if (isset($conf['short.']) && is_array($conf['short.'])) {
+                        $shortWords = $conf['short.'];
+                        krsort($shortWords);
+                        foreach ($shortWords as $key => $val) {
+                            if (is_string($val)) {
+                                $data = str_replace($key, $val, $data);
                             }
                         }
-                        // stdWrap
-                        if (isset($conf['plainTextStdWrap.']) && is_array($conf['plainTextStdWrap.'])) {
-                            $data = $this->stdWrap($data, $conf['plainTextStdWrap.']);
-                        }
-                        // userFunc
-                        if ($conf['userFunc'] ?? false) {
-                            $data = $this->callUserFunction($conf['userFunc'], $conf['userFunc.'] ?? [], $data);
-                        }
                     }
-                    // Search for tags to process in current data and
-                    // call this method recursively if found
-                    if (str_contains($data, '<') && isset($conf['tags.']) && is_array($conf['tags.'])) {
-                        // @todo probably use a DOM tree traversal for the whole stuff
-                        // This iterations basically re-processes the markup string, as
-                        // long as there are `<$tag ` or `<$tag>` "tags" found...
-                        foreach (array_keys($conf['tags.']) as $tag) {
-                            // only match tag `a` in `<a href"...">` but not in `<abbr>`
-                            if (preg_match('#<' . $tag . '[\s/>]#', $data)) {
-                                $data = $this->parseFuncInternal($data, $conf);
-                                break;
-                            }
-                        }
+                    // stdWrap
+                    if (isset($conf['plainTextStdWrap.']) && is_array($conf['plainTextStdWrap.'])) {
+                        $data = $this->stdWrap($data, $conf['plainTextStdWrap.']);
+                    }
+                    // userFunc
+                    if ($conf['userFunc'] ?? false) {
+                        $data = $this->callUserFunction($conf['userFunc'], $conf['userFunc.'] ?? [], $data);
                     }
-                    if (!is_array($currentTag) && ($conf['makelinks'] ?? false)) {
-                        $data = $this->http_makelinks($data, $conf['makelinks.']['http.'] ?? []);
-                        $data = $this->mailto_makelinks($data, $conf['makelinks.']['mailto.'] ?? []);
+                }
+                // Search for tags to process in current data and
+                // call this method recursively if found
+                if (str_contains($data, '<') && isset($conf['tags.']) && is_array($conf['tags.'])) {
+                    // @todo probably use a DOM tree traversal for the whole stuff
+                    // This iterations basically re-processes the markup string, as
+                    // long as there are `<$tag ` or `<$tag>` "tags" found...
+                    foreach (array_keys($conf['tags.']) as $tag) {
+                        // only match tag `a` in `<a href"...">` but not in `<abbr>`
+                        if (preg_match('#<' . $tag . '[\s/>]#', $data)) {
+                            $data = $this->parseFuncInternal($data, $conf);
+                            break;
+                        }
                     }
-                    $contentAccum[$contentAccumP] = isset($contentAccum[$contentAccumP])
-                        ? $contentAccum[$contentAccumP] . $data
-                        : $data;
                 }
+                if (!is_array($currentTag) && ($conf['makelinks'] ?? false)) {
+                    $data = $this->http_makelinks($data, $conf['makelinks.']['http.'] ?? []);
+                    $data = $this->mailto_makelinks($data, $conf['makelinks.']['mailto.'] ?? []);
+                }
+                $contentAccum[$contentAccumP] = ($contentAccum[$contentAccumP] ?? '') . $data;
                 $inside = true;
             } else {
                 // tags
@@ -3245,11 +3242,9 @@ class ContentObjectRenderer implements LoggerAwareInterface
                         if (isset($currentTag[1])) {
                             // decode HTML entities in attributes, since they're processed
                             $params = GeneralUtility::get_tag_attributes((string)$currentTag[1], true);
-                            if (is_array($params)) {
-                                foreach ($params as $option => $val) {
-                                    // contains non-encoded values
-                                    $this->parameters[strtolower($option)] = $val;
-                                }
+                            foreach ($params as $option => $val) {
+                                // contains non-encoded values
+                                $this->parameters[strtolower($option)] = $val;
                             }
                             $this->parameters['allParams'] = trim((string)$currentTag[1]);
                         }
@@ -3283,17 +3278,14 @@ class ContentObjectRenderer implements LoggerAwareInterface
                         $contentAccum[$contentAccumP] .= $data;
                     }
                 } else {
+                    $contentAccum[$contentAccumP] = $contentAccum[$contentAccumP] ?? '';
                     // If a tag was not a typo tag, then it is just added to the content
                     $stripNL = false;
-                    if (GeneralUtility::inList($allowTags, (string)$tag[0]) ||
-                        ($denyTags !== '*' && !GeneralUtility::inList($denyTags, (string)$tag[0]))) {
-                        $contentAccum[$contentAccumP] = isset($contentAccum[$contentAccumP])
-                            ? $contentAccum[$contentAccumP] . $data
-                            : $data;
+                    if (in_array((string)$tag[0], $allowTags, true) ||
+                        ($denyTags !== ['*'] && !in_array((string)$tag[0], $denyTags))) {
+                        $contentAccum[$contentAccumP] .= $data;
                     } else {
-                        $contentAccum[$contentAccumP] = isset($contentAccum[$contentAccumP])
-                            ? $contentAccum[$contentAccumP] . htmlspecialchars($data)
-                            : htmlspecialchars($data);
+                        $contentAccum[$contentAccumP] .= htmlspecialchars($data);
                     }
                 }
                 $inside = false;