Issues (26)

src/Constraint/Xml/XmlUtility.php (2 issues)

1
<?php declare(strict_types=1);
2
3
4
namespace Pitchart\Phlunit\Constraint\Xml;
5
6
use PHPUnit\Framework\Exception;
7
8
/**
9
 * Static methods have been back ported from phpunit
10
 *
11
 * @package Constraint\Xml
12
 *
13
 * @author Julien VITTE <[email protected]>
14
 *
15
 * @internal
16
 * @codeCoverageIgnore
17
 */
18
class XmlUtility
19
{
20
    /**
21
     * Load an $actual document into a DOMDocument.  This is called
22
     * from the selector assertions.
23
     *
24
     * If $actual is already a DOMDocument, it is returned with
25
     * no changes.  Otherwise, $actual is loaded into a new DOMDocument
26
     * as either HTML or XML, depending on the value of $isHtml. If $isHtml is
27
     * false and $xinclude is true, xinclude is performed on the loaded
28
     * DOMDocument.
29
     *
30
     * Note: prior to PHPUnit 3.3.0, this method loaded a file and
31
     * not a string as it currently does.  To load a file into a
32
     * DOMDocument, use loadFile() instead.
33
     *
34
     * @param \DOMDocument|string $actual
35
     *
36
     * @throws Exception
37
     */
38
    public static function load($actual, bool $isHtml = false, string $filename = '', bool $xinclude = false, bool $strict = false): \DOMDocument
39
    {
40
        if ($actual instanceof \DOMDocument) {
41
            return $actual;
42
        }
43
44
        if (!\is_string($actual)) {
0 ignored issues
show
The condition is_string($actual) is always true.
Loading history...
45
            throw new Exception('Could not load XML from ' . \gettype($actual));
46
        }
47
48
        if ($actual === '') {
49
            throw new Exception('Could not load XML from empty string');
50
        }
51
52
        // Required for XInclude on Windows.
53
        if ($xinclude) {
54
            $cwd = \getcwd();
55
            @\chdir(\dirname($filename));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

55
            /** @scrutinizer ignore-unhandled */ @\chdir(\dirname($filename));

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
56
        }
57
58
        $document = new \DOMDocument();
59
        $document->preserveWhiteSpace = false;
60
61
        $internal  = \libxml_use_internal_errors(true);
62
        $message   = '';
63
        $reporting = \error_reporting(0);
64
65
        if ($filename !== '') {
66
            // Required for XInclude
67
            $document->documentURI = $filename;
68
        }
69
70
        if ($isHtml) {
71
            $loaded = $document->loadHTML($actual);
72
        } else {
73
            $loaded = $document->loadXML($actual);
74
        }
75
76
        if (!$isHtml && $xinclude) {
77
            $document->xinclude();
78
        }
79
80
        foreach (\libxml_get_errors() as $error) {
81
            $message .= "\n" . $error->message;
82
        }
83
84
        \libxml_use_internal_errors($internal);
85
        \error_reporting($reporting);
86
87
        if (isset($cwd)) {
88
            @\chdir($cwd);
89
        }
90
91
        if ($loaded === false || ($strict && $message !== '')) {
92
            if ($filename !== '') {
93
                throw new Exception(
94
                    \sprintf(
95
                        'Could not load "%s".%s',
96
                        $filename,
97
                        $message !== '' ? "\n" . $message : ''
98
                    )
99
                );
100
            }
101
102
            if ($message === '') {
103
                $message = 'Could not load XML for unknown reason';
104
            }
105
106
            throw new Exception($message);
107
        }
108
109
        return $document;
110
    }
111
112
    /**
113
     * Loads an XML (or HTML) file into a DOMDocument object.
114
     *
115
     * @throws Exception
116
     */
117
    public static function loadFile(string $filename, bool $isHtml = false, bool $xinclude = false, bool $strict = false): \DOMDocument
118
    {
119
        $reporting = \error_reporting(0);
120
        $contents  = \file_get_contents($filename);
121
122
        \error_reporting($reporting);
123
124
        if ($contents === false) {
125
            throw new Exception(
126
                \sprintf(
127
                    'Could not read "%s".',
128
                    $filename
129
                )
130
            );
131
        }
132
133
        return self::load($contents, $isHtml, $filename, $xinclude, $strict);
134
    }
135
}
136