RdataDecoder::txt()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 8
ccs 4
cts 5
cp 0.8
crap 2.032
rs 10
1
<?php
2
3
/*
4
 * This file is part of PHP DNS Server.
5
 *
6
 * (c) Yif Swery <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace yswery\DNS;
13
14
class RdataDecoder
15
{
16
    /**
17
     * Maps an RData type to its decoder method.
18
     *
19
     * @var array
20
     */
21
    private static $methodMap = [
22
        RecordTypeEnum::TYPE_A => 'a',
23
        RecordTypeEnum::TYPE_AAAA => 'a',
24
        RecordTypeEnum::TYPE_CNAME => 'cname',
25
        RecordTypeEnum::TYPE_DNAME => 'cname',
26
        RecordTypeEnum::TYPE_NS => 'cname',
27
        RecordTypeEnum::TYPE_PTR => 'cname',
28
        RecordTypeEnum::TYPE_SOA => 'soa',
29
        RecordTypeEnum::TYPE_MX => 'mx',
30
        RecordTypeEnum::TYPE_TXT => 'txt',
31
        RecordTypeEnum::TYPE_SRV => 'srv',
32
    ];
33
34
    /**
35
     * @param int    $type
36
     * @param string $rdata
37
     *
38
     * @return array|string
39
     *
40
     * @throws UnsupportedTypeException
41
     */
42 6
    public static function decodeRdata(int $type, string $rdata)
43
    {
44 6
        if (!array_key_exists($type, self::$methodMap)) {
45
            throw new UnsupportedTypeException(sprintf('Record type "%s" is not a supported type.', RecordTypeEnum::getName($type)));
46
        }
47
48 6
        return call_user_func(['self', self::$methodMap[$type]], $rdata);
49
    }
50
51
    /**
52
     * Used for A and AAAA records.
53
     *
54
     * @param string $rdata
55
     *
56
     * @return string
57
     */
58 5
    public static function a(string $rdata): string
59
    {
60 5
        return inet_ntop($rdata);
61
    }
62
63
    /**
64
     * Used for CNAME, DNAME, NS, and PTR records.
65
     *
66
     * @param string $rdata
67
     *
68
     * @return string
69
     */
70 2
    public static function cname(string $rdata): string
71
    {
72 2
        return Decoder::decodeDomainName($rdata);
73
    }
74
75
    /**
76
     * Exclusively for SOA records.
77
     *
78
     * @param string $rdata
79
     *
80
     * @return array
81
     */
82 1
    public static function soa(string $rdata): array
83
    {
84 1
        $offset = 0;
85
86 1
        return array_merge(
87
            [
88 1
                'mname' => Decoder::decodeDomainName($rdata, $offset),
89 1
                'rname' => Decoder::decodeDomainName($rdata, $offset),
90
            ],
91 1
            unpack('Nserial/Nrefresh/Nretry/Nexpire/Nminimum', substr($rdata, $offset))
0 ignored issues
show
Bug introduced by
It seems like unpack('Nserial/Nrefresh...ubstr($rdata, $offset)) can also be of type false; however, parameter $array2 of array_merge() does only seem to accept array|null, maybe add an additional type check? ( Ignorable by Annotation )

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

91
            /** @scrutinizer ignore-type */ unpack('Nserial/Nrefresh/Nretry/Nexpire/Nminimum', substr($rdata, $offset))
Loading history...
92
        );
93
    }
94
95
    /**
96
     * Exclusively for MX records.
97
     *
98
     * @param string $rdata
99
     *
100
     * @return array
101
     */
102 3
    public static function mx(string $rdata): array
103
    {
104
        return [
105 3
            'preference' => unpack('npreference', $rdata)['preference'],
106 3
            'exchange' => Decoder::decodeDomainName(substr($rdata, 2)),
107
        ];
108
    }
109
110
    /**
111
     * Exclusively for TXT records.
112
     *
113
     * @param string $rdata
114
     *
115
     * @return string
116
     */
117 1
    public static function txt(string $rdata): string
118
    {
119 1
        $len = ord($rdata[0]);
120 1
        if ((strlen($rdata) + 1) < $len) {
121
            return '';
122
        }
123
124 1
        return substr($rdata, 1, $len);
125
    }
126
127
    /**
128
     * Exclusively for SRV records.
129
     *
130
     * @param string $rdata
131
     *
132
     * @return array
133
     */
134 2
    public static function srv(string $rdata): array
135
    {
136 2
        $offset = 6;
137 2
        $values = unpack('npriority/nweight/nport', $rdata);
138 2
        $values['target'] = Decoder::decodeDomainName($rdata, $offset);
139
140 2
        return $values;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $values could return the type false which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
141
    }
142
}
143