Passed
Pull Request — master (#72)
by Wilmer
11:03
created

EmailTest::testValidateIdn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 53
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 53
rs 9.216
c 0
b 0
f 0
eloc 44
nc 2
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Tests\Rule;
6
7
use PHPUnit\Framework\TestCase;
8
use Yiisoft\Validator\Rule\Email;
9
10
/**
11
 * @group validators
12
 */
13
class EmailTest extends TestCase
14
{
15
    public function testValidate(): void
16
    {
17
        $validator = new Email();
18
19
        $this->assertTrue($validator->validate('[email protected]')->isValid());
20
        $this->assertTrue($validator->validate('[email protected]')->isValid());
21
        $this->assertTrue($validator->validate('[email protected]')->isValid());
22
        $this->assertTrue($validator->validate('user+mailbox/[email protected]')->isValid());
23
        $this->assertTrue($validator->validate('!#$%&\'*+-/=?^_`.{|}[email protected]')->isValid());
24
        $this->assertFalse($validator->validate('rmcreative.ru')->isValid());
25
        $this->assertFalse($validator->validate('Carsten Brandt <[email protected]>')->isValid());
26
        $this->assertFalse($validator->validate('"Carsten Brandt" <[email protected]>')->isValid());
27
        $this->assertFalse($validator->validate('<[email protected]>')->isValid());
28
        $this->assertFalse($validator->validate('info@örtliches.de')->isValid());
29
        $this->assertFalse($validator->validate('sam@рмкреатиф.ru')->isValid());
30
        $this->assertFalse($validator->validate('[email protected]')->isValid());
31
        $this->assertFalse($validator->validate(['[email protected]'])->isValid());
32
33
        $validator = $validator->allowName(true);
34
35
        $this->assertTrue($validator->validate('[email protected]')->isValid());
36
        $this->assertTrue($validator->validate('[email protected]')->isValid());
37
        $this->assertFalse($validator->validate('rmcreative.ru')->isValid());
38
        $this->assertTrue($validator->validate('Carsten Brandt <[email protected]>')->isValid());
39
        $this->assertTrue($validator->validate('"Carsten Brandt" <[email protected]>')->isValid());
40
        $this->assertTrue($validator->validate('<[email protected]>')->isValid());
41
        $this->assertFalse($validator->validate('info@örtliches.de')->isValid());
42
        $this->assertFalse($validator->validate('üñîçøðé@üñîçøðé.com')->isValid());
43
        $this->assertFalse($validator->validate('sam@рмкреатиф.ru')->isValid());
44
        $this->assertFalse($validator->validate('Informtation [email protected]')->isValid());
45
        $this->assertTrue($validator->validate('[email protected]')->isValid());
46
        $this->assertTrue($validator->validate('John Smith <[email protected]>')->isValid());
47
        $this->assertTrue(
48
            $validator->validate(
49
                '"This name is longer than 64 characters. Blah blah blah blah blah" <[email protected]>'
50
            )->isValid()
51
        );
52
        $this->assertFalse($validator->validate('John Smith <example.com>')->isValid());
53
        $this->assertFalse(
54
            $validator->validate(
55
                'Short Name <localPartMoreThan64Characters-blah-blah-blah-blah-blah-blah-blah-blah@example.com>'
56
            )->isValid()
57
        );
58
        $this->assertFalse(
59
            $validator->validate(
60
                'Short Name <domainNameIsMoreThan254Characters@example-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah.com>'
61
            )->isValid()
62
        );
63
        $this->assertFalse($validator->validate(['[email protected]'])->isValid());
64
    }
65
66
    public function testValidateIdn(): void
67
    {
68
        if (!function_exists('idn_to_ascii')) {
69
            $this->markTestSkipped('Intl extension required');
70
71
            return;
72
        }
73
        $validator = (new Email())
74
            ->enableIDN(true);
75
76
        $this->assertTrue($validator->validate('[email protected]')->isValid());
77
        $this->assertTrue($validator->validate('example@äüößìà.de')->isValid());
78
        $this->assertTrue($validator->validate('[email protected]')->isValid());
79
        $this->assertTrue($validator->validate('info@örtliches.de')->isValid());
80
        $this->assertTrue($validator->validate('sam@рмкреатиф.ru')->isValid());
81
        $this->assertTrue($validator->validate('[email protected]')->isValid());
82
        $this->assertTrue($validator->validate('[email protected]')->isValid());
83
        $this->assertTrue($validator->validate('üñîçøðé@üñîçøðé.com')->isValid());
84
        $this->assertFalse($validator->validate('rmcreative.ru')->isValid());
85
        $this->assertFalse($validator->validate('Carsten Brandt <[email protected]>')->isValid());
86
        $this->assertFalse($validator->validate('"Carsten Brandt" <[email protected]>')->isValid());
87
        $this->assertFalse($validator->validate('<[email protected]>')->isValid());
88
89
        $validator = $validator->allowName(true);
90
91
        $this->assertTrue($validator->validate('info@örtliches.de')->isValid());
92
        $this->assertTrue($validator->validate('Informtation <info@örtliches.de>')->isValid());
93
        $this->assertFalse($validator->validate('Informtation info@örtliches.de')->isValid());
94
        $this->assertTrue($validator->validate('sam@рмкреатиф.ru')->isValid());
95
        $this->assertTrue($validator->validate('[email protected]')->isValid());
96
        $this->assertTrue($validator->validate('[email protected]')->isValid());
97
        $this->assertFalse($validator->validate('rmcreative.ru')->isValid());
98
        $this->assertTrue($validator->validate('Carsten Brandt <[email protected]>')->isValid());
99
        $this->assertTrue($validator->validate('"Carsten Brandt" <[email protected]>')->isValid());
100
        $this->assertTrue($validator->validate('üñîçøðé 日本国 <üñîçøðé@üñîçøðé.com>')->isValid());
101
        $this->assertTrue($validator->validate('<[email protected]>')->isValid());
102
        $this->assertTrue($validator->validate('[email protected]')->isValid());
103
        $this->assertTrue($validator->validate('John Smith <[email protected]>')->isValid());
104
        $this->assertTrue(
105
            $validator->validate(
106
                '"Такое имя достаточно длинное, но оно все равно может пройти валидацию" <[email protected]>'
107
            )->isValid()
108
        );
109
        $this->assertFalse($validator->validate('John Smith <example.com>')->isValid());
110
        $this->assertFalse(
111
            $validator->validate(
112
                'Короткое имя <после-преобразования-в-idn-тут-будет-больше-чем-64-символа@пример.com>'
113
            )->isValid()
114
        );
115
        $this->assertFalse(
116
            $validator->validate(
117
                'Короткое имя <тест@это-доменное-имя.после-преобразования-в-idn.будет-содержать-больше-254-символов.бла-бла-бла-бла-бла-бла-бла-бла.бла-бла-бла-бла-бла-бла.бла-бла-бла-бла-бла-бла.бла-бла-бла-бла-бла-бла.com>'
118
            )->isValid()
119
        );
120
    }
121
122
    public function testValidateMx(): void
123
    {
124
        $validator = (new Email())
125
            ->checkDNS(true);
126
127
        $this->assertTrue($validator->validate('[email protected]')->isValid());
128
129
        $validator = $validator->checkDNS(false);
130
        $this->assertTrue($validator->validate('[email protected]')->isValid());
131
132
        $validator = $validator->checkDNS(true);
133
        $this->assertFalse($validator->validate('[email protected]')->isValid());
134
135
        $validator = $validator->checkDns(true);
136
        $validator = $validator->allowName(true);
137
        $emails = [
138
            '[email protected]',
139
            'Ivan Petrov <[email protected]>',
140
        ];
141
        foreach ($emails as $email) {
142
            $this->assertTrue(
143
                $validator->validate($email)->isValid(),
144
                "Email: '$email' failed to validate(checkDNS=true, allowName=true)"
145
            );
146
        }
147
    }
148
149
    public function malformedAddressesProvider(): array
150
    {
151
        return [
152
            // this is the demo email used in the proof of concept of the exploit
153
            ['"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php "@email.com'],
154
            // trying more adresses
155
            ['"Attacker -Param2 -Param3"@test.com'],
156
            ['\'Attacker -Param2 -Param3\'@test.com'],
157
            ['"Attacker \" -Param2 -Param3"@test.com'],
158
            ["'Attacker \\' -Param2 -Param3'@test.com"],
159
            ['"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php "@email.com'],
160
            // and even more variants
161
            ['"attacker\"\ -oQ/tmp/\ -X/var/www/cache/phpcode.php"@email.com'],
162
            ["\"attacker\\\"\0-oQ/tmp/\0-X/var/www/cache/phpcode.php\"@email.com"],
163
            ['"[email protected]\"-Xbeep"@email.com'],
164
165
            ["'attacker\\' -oQ/tmp/ -X/var/www/cache/phpcode.php'@email.com"],
166
            ["'attacker\\\\' -oQ/tmp/ -X/var/www/cache/phpcode.php'@email.com"],
167
            ["'attacker\\\\'\\ -oQ/tmp/ -X/var/www/cache/phpcode.php'@email.com"],
168
            ["'attacker\\';touch /tmp/hackme'@email.com"],
169
            ["'attacker\\\\';touch /tmp/hackme'@email.com"],
170
            ["'attacker\\';touch/tmp/hackme'@email.com"],
171
            ["'attacker\\\\';touch/tmp/hackme'@email.com"],
172
            ['"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php "@email.com'],
173
        ];
174
    }
175
176
    /**
177
     * Test malicious email addresses that can be used to exploit SwiftMailer vulnerability CVE-2016-10074 while IDN is
178
     * disabled.
179
     * @see https://legalhackers.com/advisories/SwiftMailer-Exploit-Remote-Code-Exec-CVE-2016-10074-Vuln.html
180
     * @dataProvider malformedAddressesProvider
181
     *
182
     * @param string $value
183
     */
184
    public function testMalformedAddressesIdnDisabled($value): void
185
    {
186
        $validator = (new Email())
187
            ->enableIDN(true);
188
        $this->assertFalse($validator->validate($value)->isValid());
189
    }
190
191
    /**
192
     * Test malicious email addresses that can be used to exploit SwiftMailer vulnerability CVE-2016-10074 while IDN is
193
     * enabled.
194
     * @see https://legalhackers.com/advisories/SwiftMailer-Exploit-Remote-Code-Exec-CVE-2016-10074-Vuln.html
195
     * @dataProvider malformedAddressesProvider
196
     *
197
     * @param string $value
198
     */
199
    public function testMalformedAddressesIdnEnabled($value): void
200
    {
201
        if (!function_exists('idn_to_ascii')) {
202
            $this->markTestSkipped('Intl extension required');
203
204
            return;
205
        }
206
207
        $validator = (new Email())
208
            ->enableIDN(true);
209
        $this->assertFalse($validator->validate($value)->isValid());
210
    }
211
}
212