[SECURITY] XML entity expansion
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / Service / AbstractGenerator.php
1 <?php
2 namespace TYPO3\CMS\Fluid\Service;
3
4 /* *
5 * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License, either version 3 *
9 * of the License, or (at your option) any later version. *
10 * *
11 * The TYPO3 project - inspiring people to share! *
12 * */
13
14 /**
15 * Common base class for XML generators.
16 */
17 abstract class AbstractGenerator
18 {
19 /**
20 * The reflection class for AbstractViewHelper. Is needed quite often, that's why we use a pre-initialized one.
21 *
22 * @var \TYPO3\CMS\Extbase\Reflection\ClassReflection
23 */
24 protected $abstractViewHelperReflectionClass;
25
26 /**
27 * The doc comment parser.
28 *
29 * @var \TYPO3\CMS\Extbase\Reflection\DocCommentParser
30 * @inject
31 */
32 protected $docCommentParser;
33
34 /**
35 * @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
36 * @inject
37 */
38 protected $reflectionService;
39
40 /**
41 * Constructor. Sets $this->abstractViewHelperReflectionClass
42 *
43 */
44 public function __construct()
45 {
46 \TYPO3\CMS\Fluid\Fluid::$debugMode = true; // We want ViewHelper argument documentation
47 $this->abstractViewHelperReflectionClass = new \TYPO3\CMS\Extbase\Reflection\ClassReflection(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper::class);
48 }
49
50 /**
51 * Get all class names inside this namespace and return them as array.
52 *
53 * @param string $namespace
54 * @return array Array of all class names inside a given namespace.
55 */
56 protected function getClassNamesInNamespace($namespace)
57 {
58 $affectedViewHelperClassNames = array();
59
60 $allViewHelperClassNames = $this->reflectionService->getAllSubClassNamesForClass(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper::class);
61 foreach ($allViewHelperClassNames as $viewHelperClassName) {
62 if ($this->reflectionService->isClassAbstract($viewHelperClassName)) {
63 continue;
64 }
65 if (strncmp($namespace, $viewHelperClassName, strlen($namespace)) === 0) {
66 $affectedViewHelperClassNames[] = $viewHelperClassName;
67 }
68 }
69 sort($affectedViewHelperClassNames);
70 return $affectedViewHelperClassNames;
71 }
72
73 /**
74 * Get a tag name for a given ViewHelper class.
75 * Example: For the View Helper TYPO3\CMS\Fluid\ViewHelpers\Form\SelectViewHelper, and the
76 * namespace prefix TYPO3\CMS\Fluid\ViewHelpers\, this method returns "form.select".
77 *
78 * @param string $className Class name
79 * @param string $namespace Base namespace to use
80 * @return string Tag name
81 */
82 protected function getTagNameForClass($className, $namespace)
83 {
84 /// Strip namespace from the beginning and "ViewHelper" from the end of the class name
85 $strippedClassName = substr($className, strlen($namespace), -10);
86 $classNameParts = explode(\TYPO3\CMS\Fluid\Fluid::NAMESPACE_SEPARATOR, $strippedClassName);
87 return implode(
88 '.',
89 array_map(
90 function ($element) {
91 return lcfirst($element);
92 },
93 $classNameParts
94 )
95 );
96 }
97
98 /**
99 * Add a child node to $parentXmlNode, and wrap the contents inside a CDATA section.
100 *
101 * @param \SimpleXMLElement $parentXmlNode Parent XML Node to add the child to
102 * @param string $childNodeName Name of the child node
103 * @param string $childNodeValue Value of the child node. Will be placed inside CDATA.
104 * @return \SimpleXMLElement the new element
105 */
106 protected function addChildWithCData(\SimpleXMLElement $parentXmlNode, $childNodeName, $childNodeValue)
107 {
108 // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
109 $previousValueOfEntityLoader = libxml_disable_entity_loader(true);
110 $parentDomNode = dom_import_simplexml($parentXmlNode);
111 $domDocument = new \DOMDocument();
112
113 $childNode = $domDocument->appendChild($domDocument->createElement($childNodeName));
114 $childNode->appendChild($domDocument->createCDATASection($childNodeValue));
115 $childNodeTarget = $parentDomNode->ownerDocument->importNode($childNode, true);
116 $parentDomNode->appendChild($childNodeTarget);
117 $returnValue = simplexml_import_dom($childNodeTarget);
118 libxml_disable_entity_loader($previousValueOfEntityLoader);
119
120 return $returnValue;
121 }
122 }