• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PHPOffice / Math / 15319762567

29 May 2025 08:31AM UTC coverage: 95.208% (-4.8%) from 100.0%
15319762567

push

github

Progi1984
Merge commit from fork

14 of 29 new or added lines in 2 files covered. (48.28%)

298 of 313 relevant lines covered (95.21%)

3.27 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.31
/src/Math/Reader/Security/XmlScanner.php
1
<?php
2

3
namespace PhpOffice\Math\Reader\Security;
4

5
use PhpOffice\Math\Exception\SecurityException;
6

7
class XmlScanner
8
{
9
    public static function getInstance(): self
10
    {
11
        return new self();
8✔
12
    }
13

14
    /**
15
     * Scan the XML for use of <!ENTITY to prevent XXE/XEE attacks.
16
     */
17
    public function scan(string $xml): string
18
    {
19
        // Don't rely purely on libxml_disable_entity_loader()
20
        $searchDoctype = static::mb_str_split('<!DOCTYPE', 1, 'UTF-8');
8✔
21
        $patternDoctype = '/\0*' . implode('\0*', is_array($searchDoctype) ? $searchDoctype : []) . '\0*/';
8✔
22
        $searchDoctypeMath = static::mb_str_split('<!DOCTYPE math', 1, 'UTF-8');
8✔
23
        $patternDoctypeMath = '/\0*' . implode('\0*', is_array($searchDoctypeMath) ? $searchDoctypeMath : []) . '\0*/';
8✔
24

25
        if (preg_match($patternDoctype, $xml) && !preg_match($patternDoctypeMath, $xml)) {
8✔
26
            throw new SecurityException('Detected use of ENTITY in XML, loading aborted to prevent XXE/XEE attacks');
1✔
27
        }
28

29
        return $xml;
7✔
30
    }
31

32
    /**
33
     * @param string $string
34
     * @param int<1, max> $split_length
35
     * @param string|null $encoding
36
     *
37
     * @return array<string>|bool|null
38
     */
39
    public static function mb_str_split(string $string, int $split_length = 1, ?string $encoding = null)
40
    {
41
        if (extension_loaded('mbstring')) {
8✔
42
            if (function_exists('mb_str_split')) {
8✔
43
                return mb_str_split($string, $split_length, $encoding);
8✔
44
            }
45
        }
46
        // @phpstan-ignore-next-line
NEW
47
        if (null !== $string && !\is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) {
×
NEW
48
            trigger_error('mb_str_split() expects parameter 1 to be string, ' . \gettype($string) . ' given', \E_USER_WARNING);
×
49

NEW
50
            return null;
×
51
        }
52

53
        // @phpstan-ignore-next-line
NEW
54
        if (1 > $split_length = (int) $split_length) {
×
NEW
55
            trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING);
×
56

NEW
57
            return false;
×
58
        }
59

NEW
60
        if (null === $encoding) {
×
NEW
61
            $encoding = mb_internal_encoding();
×
62
        }
63

NEW
64
        if ('UTF-8' === $encoding || \in_array(strtoupper($encoding), ['UTF-8', 'UTF8'], true)) {
×
NEW
65
            return preg_split("/(.{{$split_length}})/u", $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
×
66
        }
67

NEW
68
        $result = [];
×
NEW
69
        $length = mb_strlen($string, $encoding);
×
70

NEW
71
        for ($i = 0; $i < $length; $i += $split_length) {
×
NEW
72
            $result[] = mb_substr($string, $i, $split_length, $encoding);
×
73
        }
74

NEW
75
        return $result;
×
76
    }
77
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc