~canonical-sysadmins/wordpress/4.7.2

« back to all changes in this revision

Viewing changes to wp-includes/SimplePie/Net/IPv6.php

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * SimplePie
 
4
 *
 
5
 * A PHP-Based RSS and Atom Feed Framework.
 
6
 * Takes the hard work out of managing a complete RSS/Atom solution.
 
7
 *
 
8
 * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
 
9
 * All rights reserved.
 
10
 *
 
11
 * Redistribution and use in source and binary forms, with or without modification, are
 
12
 * permitted provided that the following conditions are met:
 
13
 *
 
14
 *      * Redistributions of source code must retain the above copyright notice, this list of
 
15
 *        conditions and the following disclaimer.
 
16
 *
 
17
 *      * Redistributions in binary form must reproduce the above copyright notice, this list
 
18
 *        of conditions and the following disclaimer in the documentation and/or other materials
 
19
 *        provided with the distribution.
 
20
 *
 
21
 *      * Neither the name of the SimplePie Team nor the names of its contributors may be used
 
22
 *        to endorse or promote products derived from this software without specific prior
 
23
 *        written permission.
 
24
 *
 
25
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 
26
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 
27
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
 
28
 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
29
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
30
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
32
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
33
 * POSSIBILITY OF SUCH DAMAGE.
 
34
 *
 
35
 * @package SimplePie
 
36
 * @version 1.3.1
 
37
 * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
 
38
 * @author Ryan Parman
 
39
 * @author Geoffrey Sneddon
 
40
 * @author Ryan McCue
 
41
 * @link http://simplepie.org/ SimplePie
 
42
 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
 
43
 */
 
44
 
 
45
 
 
46
/**
 
47
 * Class to validate and to work with IPv6 addresses.
 
48
 *
 
49
 * @package SimplePie
 
50
 * @subpackage HTTP
 
51
 * @copyright 2003-2005 The PHP Group
 
52
 * @license http://www.opensource.org/licenses/bsd-license.php
 
53
 * @link http://pear.php.net/package/Net_IPv6
 
54
 * @author Alexander Merz <alexander.merz@web.de>
 
55
 * @author elfrink at introweb dot nl
 
56
 * @author Josh Peck <jmp at joshpeck dot org>
 
57
 * @author Geoffrey Sneddon <geoffers@gmail.com>
 
58
 */
 
59
class SimplePie_Net_IPv6
 
60
{
 
61
        /**
 
62
         * Uncompresses an IPv6 address
 
63
         *
 
64
         * RFC 4291 allows you to compress concecutive zero pieces in an address to
 
65
         * '::'. This method expects a valid IPv6 address and expands the '::' to
 
66
         * the required number of zero pieces.
 
67
         *
 
68
         * Example:  FF01::101   ->  FF01:0:0:0:0:0:0:101
 
69
         *           ::1         ->  0:0:0:0:0:0:0:1
 
70
         *
 
71
         * @author Alexander Merz <alexander.merz@web.de>
 
72
         * @author elfrink at introweb dot nl
 
73
         * @author Josh Peck <jmp at joshpeck dot org>
 
74
         * @copyright 2003-2005 The PHP Group
 
75
         * @license http://www.opensource.org/licenses/bsd-license.php
 
76
         * @param string $ip An IPv6 address
 
77
         * @return string The uncompressed IPv6 address
 
78
         */
 
79
        public static function uncompress($ip)
 
80
        {
 
81
                $c1 = -1;
 
82
                $c2 = -1;
 
83
                if (substr_count($ip, '::') === 1)
 
84
                {
 
85
                        list($ip1, $ip2) = explode('::', $ip);
 
86
                        if ($ip1 === '')
 
87
                        {
 
88
                                $c1 = -1;
 
89
                        }
 
90
                        else
 
91
                        {
 
92
                                $c1 = substr_count($ip1, ':');
 
93
                        }
 
94
                        if ($ip2 === '')
 
95
                        {
 
96
                                $c2 = -1;
 
97
                        }
 
98
                        else
 
99
                        {
 
100
                                $c2 = substr_count($ip2, ':');
 
101
                        }
 
102
                        if (strpos($ip2, '.') !== false)
 
103
                        {
 
104
                                $c2++;
 
105
                        }
 
106
                        // ::
 
107
                        if ($c1 === -1 && $c2 === -1)
 
108
                        {
 
109
                                $ip = '0:0:0:0:0:0:0:0';
 
110
                        }
 
111
                        // ::xxx
 
112
                        else if ($c1 === -1)
 
113
                        {
 
114
                                $fill = str_repeat('0:', 7 - $c2);
 
115
                                $ip = str_replace('::', $fill, $ip);
 
116
                        }
 
117
                        // xxx::
 
118
                        else if ($c2 === -1)
 
119
                        {
 
120
                                $fill = str_repeat(':0', 7 - $c1);
 
121
                                $ip = str_replace('::', $fill, $ip);
 
122
                        }
 
123
                        // xxx::xxx
 
124
                        else
 
125
                        {
 
126
                                $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
 
127
                                $ip = str_replace('::', $fill, $ip);
 
128
                        }
 
129
                }
 
130
                return $ip;
 
131
        }
 
132
 
 
133
        /**
 
134
         * Compresses an IPv6 address
 
135
         *
 
136
         * RFC 4291 allows you to compress concecutive zero pieces in an address to
 
137
         * '::'. This method expects a valid IPv6 address and compresses consecutive
 
138
         * zero pieces to '::'.
 
139
         *
 
140
         * Example:  FF01:0:0:0:0:0:0:101   ->  FF01::101
 
141
         *           0:0:0:0:0:0:0:1        ->  ::1
 
142
         *
 
143
         * @see uncompress()
 
144
         * @param string $ip An IPv6 address
 
145
         * @return string The compressed IPv6 address
 
146
         */
 
147
        public static function compress($ip)
 
148
        {
 
149
                // Prepare the IP to be compressed
 
150
                $ip = self::uncompress($ip);
 
151
                $ip_parts = self::split_v6_v4($ip);
 
152
 
 
153
                // Replace all leading zeros
 
154
                $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
 
155
 
 
156
                // Find bunches of zeros
 
157
                if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
 
158
                {
 
159
                        $max = 0;
 
160
                        $pos = null;
 
161
                        foreach ($matches[0] as $match)
 
162
                        {
 
163
                                if (strlen($match[0]) > $max)
 
164
                                {
 
165
                                        $max = strlen($match[0]);
 
166
                                        $pos = $match[1];
 
167
                                }
 
168
                        }
 
169
 
 
170
                        $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
 
171
                }
 
172
 
 
173
                if ($ip_parts[1] !== '')
 
174
                {
 
175
                        return implode(':', $ip_parts);
 
176
                }
 
177
                else
 
178
                {
 
179
                        return $ip_parts[0];
 
180
                }
 
181
        }
 
182
 
 
183
        /**
 
184
         * Splits an IPv6 address into the IPv6 and IPv4 representation parts
 
185
         *
 
186
         * RFC 4291 allows you to represent the last two parts of an IPv6 address
 
187
         * using the standard IPv4 representation
 
188
         *
 
189
         * Example:  0:0:0:0:0:0:13.1.68.3
 
190
         *           0:0:0:0:0:FFFF:129.144.52.38
 
191
         *
 
192
         * @param string $ip An IPv6 address
 
193
         * @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
 
194
         */
 
195
        private static function split_v6_v4($ip)
 
196
        {
 
197
                if (strpos($ip, '.') !== false)
 
198
                {
 
199
                        $pos = strrpos($ip, ':');
 
200
                        $ipv6_part = substr($ip, 0, $pos);
 
201
                        $ipv4_part = substr($ip, $pos + 1);
 
202
                        return array($ipv6_part, $ipv4_part);
 
203
                }
 
204
                else
 
205
                {
 
206
                        return array($ip, '');
 
207
                }
 
208
        }
 
209
 
 
210
        /**
 
211
         * Checks an IPv6 address
 
212
         *
 
213
         * Checks if the given IP is a valid IPv6 address
 
214
         *
 
215
         * @param string $ip An IPv6 address
 
216
         * @return bool true if $ip is a valid IPv6 address
 
217
         */
 
218
        public static function check_ipv6($ip)
 
219
        {
 
220
                $ip = self::uncompress($ip);
 
221
                list($ipv6, $ipv4) = self::split_v6_v4($ip);
 
222
                $ipv6 = explode(':', $ipv6);
 
223
                $ipv4 = explode('.', $ipv4);
 
224
                if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
 
225
                {
 
226
                        foreach ($ipv6 as $ipv6_part)
 
227
                        {
 
228
                                // The section can't be empty
 
229
                                if ($ipv6_part === '')
 
230
                                        return false;
 
231
 
 
232
                                // Nor can it be over four characters
 
233
                                if (strlen($ipv6_part) > 4)
 
234
                                        return false;
 
235
 
 
236
                                // Remove leading zeros (this is safe because of the above)
 
237
                                $ipv6_part = ltrim($ipv6_part, '0');
 
238
                                if ($ipv6_part === '')
 
239
                                        $ipv6_part = '0';
 
240
 
 
241
                                // Check the value is valid
 
242
                                $value = hexdec($ipv6_part);
 
243
                                if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
 
244
                                        return false;
 
245
                        }
 
246
                        if (count($ipv4) === 4)
 
247
                        {
 
248
                                foreach ($ipv4 as $ipv4_part)
 
249
                                {
 
250
                                        $value = (int) $ipv4_part;
 
251
                                        if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
 
252
                                                return false;
 
253
                                }
 
254
                        }
 
255
                        return true;
 
256
                }
 
257
                else
 
258
                {
 
259
                        return false;
 
260
                }
 
261
        }
 
262
 
 
263
        /**
 
264
         * Checks if the given IP is a valid IPv6 address
 
265
         *
 
266
         * @codeCoverageIgnore
 
267
         * @deprecated Use {@see SimplePie_Net_IPv6::check_ipv6()} instead
 
268
         * @see check_ipv6
 
269
         * @param string $ip An IPv6 address
 
270
         * @return bool true if $ip is a valid IPv6 address
 
271
         */
 
272
        public static function checkIPv6($ip)
 
273
        {
 
274
                return self::check_ipv6($ip);
 
275
        }
 
276
}