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;