ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
DOMDocumentFactory.php
Go to the documentation of this file.
1 <?php
2 
3 namespace SAML2;
4 
8 
9 final class DOMDocumentFactory
10 {
11  private function __construct()
12  {
13  }
14 
20  public static function fromString($xml)
21  {
22  if (!is_string($xml) || trim($xml) === '') {
23  throw InvalidArgumentException::invalidType('non-empty string', $xml);
24  }
25 
26  $entityLoader = libxml_disable_entity_loader(true);
27  $internalErrors = libxml_use_internal_errors(true);
28  libxml_clear_errors();
29 
30  $domDocument = self::create();
31  $options = LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NONET;
32  if (defined(LIBXML_COMPACT)) {
33  $options |= LIBXML_COMPACT;
34  }
35 
36  $loaded = $domDocument->loadXML($xml, $options);
37 
38  libxml_use_internal_errors($internalErrors);
39  libxml_disable_entity_loader($entityLoader);
40 
41  if (!$loaded) {
42  $error = libxml_get_last_error();
43  libxml_clear_errors();
44 
45  throw new UnparseableXmlException($error);
46  }
47 
48  libxml_clear_errors();
49 
50  foreach ($domDocument->childNodes as $child) {
51  if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
52  throw new RuntimeException(
53  'Dangerous XML detected, DOCTYPE nodes are not allowed in the XML body'
54  );
55  }
56  }
57 
58  return $domDocument;
59  }
60 
66  public static function fromFile($file)
67  {
68  if (!is_string($file)) {
69  throw InvalidArgumentException::invalidType('string', $file);
70  }
71 
72  if (!is_file($file)) {
73  throw new InvalidArgumentException(sprintf('Path "%s" is not a file', $file));
74  }
75 
76  if (!is_readable($file)) {
77  throw new InvalidArgumentException(sprintf('File "%s" is not readable', $file));
78  }
79 
80  // libxml_disable_entity_loader(true) disables \DOMDocument::load() method
81  // so we need to read the content and use \DOMDocument::loadXML()
82  $xml = file_get_contents($file);
83  if ($xml === false) {
84  throw new RuntimeException(sprintf(
85  'Contents of readable file "%s" could not be gotten',
86  $file
87  ));
88  }
89 
90  if (trim($xml) === '') {
91  throw new RuntimeException(sprintf('File "%s" does not have content', $file));
92  }
93 
94  return static::fromString($xml);
95  }
96 
100  public static function create()
101  {
102  return new \DOMDocument();
103  }
104 }