GeoIP Detection - Version 2.10.0

Version Description

  • NEW: The whitelisted proxies can now be subnets such as 11.11.11.0/24
  • NEW: Add a ContactForm7-Tag geoip_detect2_text_input (see https://github.com/yellowtree/geoip-detect/wiki/API-Documentation#create-a-text-input-that-is-prefilled-with-a-geodetected-property)
  • NEW: A new wordpress filter allows overriding of the detected geo-information inside the geoip_detect2_shortcode_show_if-Shortcode. Use the already-existing filter geoip_detect2_record_information instead if you want to override this information for all shortcodes and API calls.
  • Updated Maxmind vendor code
  • Increased WP minimum version to 4.0
Download this release

Release Info

Developer benjamin4
Plugin Icon 128x128 GeoIP Detection
Version 2.10.0
Comparing to
See all releases

Code changes from version 2.9.2 to 2.10.0

admin-ui.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
api.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
check_requirements.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
composer.json CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "name": "yellowtree/wp-geoip-detect",
3
  "description": "Wordpress Plugin GeoIP Detection: Retrieving Geo-Information using the Maxmind GeoIP2 (Lite) Database.",
4
  "type": "wordpress-plugin",
5
  "authors": [
@@ -15,6 +15,6 @@
15
  ],
16
  "require": {
17
  "geoip2/geoip2": "~2.0",
18
- "php": ">=5.3.1"
19
  }
20
  }
1
  {
2
+ "name": "yellowtree/geoip-detect",
3
  "description": "Wordpress Plugin GeoIP Detection: Retrieving Geo-Information using the Maxmind GeoIP2 (Lite) Database.",
4
  "type": "wordpress-plugin",
5
  "authors": [
15
  ],
16
  "require": {
17
  "geoip2/geoip2": "~2.0",
18
+ "php": ">=5.4"
19
  }
20
  }
composer.lock CHANGED
@@ -4,20 +4,20 @@
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
  "This file is @generated automatically"
6
  ],
7
- "content-hash": "600b354d911b7fb40bc8e6b398c09245",
8
  "packages": [
9
  {
10
  "name": "composer/ca-bundle",
11
- "version": "1.1.3",
12
  "source": {
13
  "type": "git",
14
  "url": "https://github.com/composer/ca-bundle.git",
15
- "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660"
16
  },
17
  "dist": {
18
  "type": "zip",
19
- "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660",
20
- "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660",
21
  "shasum": ""
22
  },
23
  "require": {
@@ -60,7 +60,7 @@
60
  "ssl",
61
  "tls"
62
  ],
63
- "time": "2018-10-18T06:09:13+00:00"
64
  },
65
  {
66
  "name": "geoip2/geoip2",
@@ -116,16 +116,16 @@
116
  },
117
  {
118
  "name": "maxmind-db/reader",
119
- "version": "v1.3.0",
120
  "source": {
121
  "type": "git",
122
  "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
123
- "reference": "e042b4f8a2dff41e19019faf16427178b07fbd58"
124
  },
125
  "dist": {
126
  "type": "zip",
127
- "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/e042b4f8a2dff41e19019faf16427178b07fbd58",
128
- "reference": "e042b4f8a2dff41e19019faf16427178b07fbd58",
129
  "shasum": ""
130
  },
131
  "require": {
@@ -168,7 +168,7 @@
168
  "geolocation",
169
  "maxmind"
170
  ],
171
- "time": "2018-02-21T21:23:33+00:00"
172
  },
173
  {
174
  "name": "maxmind/web-service-common",
@@ -224,7 +224,7 @@
224
  "prefer-stable": false,
225
  "prefer-lowest": false,
226
  "platform": {
227
- "php": ">=5.3.1"
228
  },
229
  "platform-dev": []
230
  }
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
  "This file is @generated automatically"
6
  ],
7
+ "content-hash": "1469024a23af7d9facb99a4208b34160",
8
  "packages": [
9
  {
10
  "name": "composer/ca-bundle",
11
+ "version": "1.1.4",
12
  "source": {
13
  "type": "git",
14
  "url": "https://github.com/composer/ca-bundle.git",
15
+ "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d"
16
  },
17
  "dist": {
18
  "type": "zip",
19
+ "url": "https://api.github.com/repos/composer/ca-bundle/zipball/558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
20
+ "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
21
  "shasum": ""
22
  },
23
  "require": {
60
  "ssl",
61
  "tls"
62
  ],
63
+ "time": "2019-01-28T09:30:10+00:00"
64
  },
65
  {
66
  "name": "geoip2/geoip2",
116
  },
117
  {
118
  "name": "maxmind-db/reader",
119
+ "version": "v1.4.1",
120
  "source": {
121
  "type": "git",
122
  "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
123
+ "reference": "eb83d0ee1c1f9b8a340206302136bc81ee02ae74"
124
  },
125
  "dist": {
126
  "type": "zip",
127
+ "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/eb83d0ee1c1f9b8a340206302136bc81ee02ae74",
128
+ "reference": "eb83d0ee1c1f9b8a340206302136bc81ee02ae74",
129
  "shasum": ""
130
  },
131
  "require": {
168
  "geolocation",
169
  "maxmind"
170
  ],
171
+ "time": "2019-01-04T19:55:56+00:00"
172
  },
173
  {
174
  "name": "maxmind/web-service-common",
224
  "prefer-stable": false,
225
  "prefer-lowest": false,
226
  "platform": {
227
+ "php": ">=5.4"
228
  },
229
  "platform-dev": []
230
  }
data-sources/auto.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
data-sources/header.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
data-sources/manual.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
data-sources/precision.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
data-sources/registry.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
filter.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
geoip-detect-lib.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
@@ -23,6 +23,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
 
24
  use YellowTree\GeoipDetect\DataSources\DataSourceRegistry;
25
 
 
 
 
 
26
  /**
27
  * Take the parameter options and add the default values.
28
  * @param array $options
@@ -262,11 +266,21 @@ function geoip_detect_normalize_ip($ip) {
262
  return $ip;
263
  }
264
 
265
- function geoip_detect_is_ip_equal($ip1, $ip2) {
266
- $one = @inet_pton($ip1);
267
- $two = @inet_pton($ip2);
268
-
269
- return !empty($one) && $one == $two;
 
 
 
 
 
 
 
 
 
 
270
  }
271
 
272
  function geoip_detect_is_ip($ip, $noIpv6 = false) {
@@ -295,7 +309,7 @@ function geoip_detect_is_ip_in_range($ip, $range_start, $range_end) {
295
  */
296
  function geoip_detect_is_public_ip($ip) {
297
  // filver_var only detects 127.0.0.1 as local ...
298
- if (geoip_detect_is_ip_in_range($ip, '127.0.0.0', '127.255.255.255'))
299
  return false;
300
  if (trim($ip) === '0.0.0.0')
301
  return false;
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
23
 
24
  use YellowTree\GeoipDetect\DataSources\DataSourceRegistry;
25
 
26
+ // This file is outside composer root in order to not distribute all the other symfony files
27
+ require_once(__DIR__ . '/lib/vendor/symfony/http-foundation/IpUtils.php');
28
+ use Symfony\Component\HttpFoundation\IpUtils;
29
+
30
  /**
31
  * Take the parameter options and add the default values.
32
  * @param array $options
266
  return $ip;
267
  }
268
 
269
+ /**
270
+ * Check if the expected IP left matches the actual IP
271
+ * @param string $actual IP
272
+ * @param string|array $expected IP (can include subnet)
273
+ * @return boolean
274
+ */
275
+ function geoip_detect_is_ip_equal($actual, $expected) {
276
+ try {
277
+ return IpUtils::checkIp($actual, $expected);
278
+ } catch(Exception $e) {
279
+ if (WP_DEBUG) {
280
+ throw $e;
281
+ }
282
+ return false;
283
+ }
284
  }
285
 
286
  function geoip_detect_is_ip($ip, $noIpv6 = false) {
309
  */
310
  function geoip_detect_is_public_ip($ip) {
311
  // filver_var only detects 127.0.0.1 as local ...
312
+ if (geoip_detect_is_ip_equal($ip, '127.0.0.0/8'))
313
  return false;
314
  if (trim($ip) === '0.0.0.0')
315
  return false;
geoip-detect.php CHANGED
@@ -5,21 +5,21 @@ Plugin URI: http://www.yellowtree.de
5
  Description: Retrieving Geo-Information using the Maxmind GeoIP (Lite) Database.
6
  Author: Yellow Tree (Benjamin Pick)
7
  Author URI: http://www.yellowtree.de
8
- Version: 2.9.2
9
  License: GPLv3 or later
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
  Text Domain: geoip-detect
12
  Domain Path: /languages
13
- GitHub Plugin URI: https://github.com/yellowtree/wp-geoip-detect
14
  GitHub Branch: master
15
- Requires WP: 3.5
16
  Requires PHP: 5.4
17
  */
18
 
19
- define('GEOIP_DETECT_VERSION', '2.9.2');
20
 
21
  /*
22
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
23
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
24
 
25
  This program is free software; you can redistribute it and/or modify
@@ -38,6 +38,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
38
  */
39
 
40
  define('GEOIP_REQUIRED_PHP_VERSION', '5.4');
 
 
41
  define('GEOIP_REQUIRED_WP_VERSION', '3.5');
42
 
43
  define('GEOIP_PLUGIN_FILE', __FILE__);
5
  Description: Retrieving Geo-Information using the Maxmind GeoIP (Lite) Database.
6
  Author: Yellow Tree (Benjamin Pick)
7
  Author URI: http://www.yellowtree.de
8
+ Version: 2.10.0
9
  License: GPLv3 or later
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
  Text Domain: geoip-detect
12
  Domain Path: /languages
13
+ GitHub Plugin URI: https://github.com/yellowtree/geoip-detect
14
  GitHub Branch: master
15
+ Requires WP: 4.0
16
  Requires PHP: 5.4
17
  */
18
 
19
+ define('GEOIP_DETECT_VERSION', '2.10.0');
20
 
21
  /*
22
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
23
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
24
 
25
  This program is free software; you can redistribute it and/or modify
38
  */
39
 
40
  define('GEOIP_REQUIRED_PHP_VERSION', '5.4');
41
+
42
+ // It should still run in 3.5 . But officially supported is only WP 4.0 and above.
43
  define('GEOIP_REQUIRED_WP_VERSION', '3.5');
44
 
45
  define('GEOIP_PLUGIN_FILE', __FILE__);
legacy-api.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
lib/composer.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "yellowtree/geoip-detect-lib",
3
+ "type": "library",
4
+ "require": {
5
+ "symfony/http-foundation": "^4.2"
6
+ },
7
+ "authors": [
8
+ {
9
+ "name": "Benjamin Pick",
10
+ "email": "benjaminpick@github.com"
11
+ }
12
+ ]
13
+ }
lib/composer.lock ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "content-hash": "689f4cbd126b0807e8268f1cfd775a98",
8
+ "packages": [
9
+ {
10
+ "name": "symfony/http-foundation",
11
+ "version": "v4.2.3",
12
+ "source": {
13
+ "type": "git",
14
+ "url": "https://github.com/symfony/http-foundation.git",
15
+ "reference": "8d2318b73e0a1bc75baa699d00ebe2ae8b595a39"
16
+ },
17
+ "dist": {
18
+ "type": "zip",
19
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8d2318b73e0a1bc75baa699d00ebe2ae8b595a39",
20
+ "reference": "8d2318b73e0a1bc75baa699d00ebe2ae8b595a39",
21
+ "shasum": ""
22
+ },
23
+ "require": {
24
+ "php": "^7.1.3",
25
+ "symfony/polyfill-mbstring": "~1.1"
26
+ },
27
+ "require-dev": {
28
+ "predis/predis": "~1.0",
29
+ "symfony/expression-language": "~3.4|~4.0"
30
+ },
31
+ "type": "library",
32
+ "extra": {
33
+ "branch-alias": {
34
+ "dev-master": "4.2-dev"
35
+ }
36
+ },
37
+ "autoload": {
38
+ "psr-4": {
39
+ "Symfony\\Component\\HttpFoundation\\": ""
40
+ },
41
+ "exclude-from-classmap": [
42
+ "/Tests/"
43
+ ]
44
+ },
45
+ "notification-url": "https://packagist.org/downloads/",
46
+ "license": [
47
+ "MIT"
48
+ ],
49
+ "authors": [
50
+ {
51
+ "name": "Fabien Potencier",
52
+ "email": "fabien@symfony.com"
53
+ },
54
+ {
55
+ "name": "Symfony Community",
56
+ "homepage": "https://symfony.com/contributors"
57
+ }
58
+ ],
59
+ "description": "Symfony HttpFoundation Component",
60
+ "homepage": "https://symfony.com",
61
+ "time": "2019-01-29T09:49:29+00:00"
62
+ },
63
+ {
64
+ "name": "symfony/polyfill-mbstring",
65
+ "version": "v1.10.0",
66
+ "source": {
67
+ "type": "git",
68
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
69
+ "reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
70
+ },
71
+ "dist": {
72
+ "type": "zip",
73
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
74
+ "reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
75
+ "shasum": ""
76
+ },
77
+ "require": {
78
+ "php": ">=5.3.3"
79
+ },
80
+ "suggest": {
81
+ "ext-mbstring": "For best performance"
82
+ },
83
+ "type": "library",
84
+ "extra": {
85
+ "branch-alias": {
86
+ "dev-master": "1.9-dev"
87
+ }
88
+ },
89
+ "autoload": {
90
+ "psr-4": {
91
+ "Symfony\\Polyfill\\Mbstring\\": ""
92
+ },
93
+ "files": [
94
+ "bootstrap.php"
95
+ ]
96
+ },
97
+ "notification-url": "https://packagist.org/downloads/",
98
+ "license": [
99
+ "MIT"
100
+ ],
101
+ "authors": [
102
+ {
103
+ "name": "Nicolas Grekas",
104
+ "email": "p@tchwork.com"
105
+ },
106
+ {
107
+ "name": "Symfony Community",
108
+ "homepage": "https://symfony.com/contributors"
109
+ }
110
+ ],
111
+ "description": "Symfony polyfill for the Mbstring extension",
112
+ "homepage": "https://symfony.com",
113
+ "keywords": [
114
+ "compatibility",
115
+ "mbstring",
116
+ "polyfill",
117
+ "portable",
118
+ "shim"
119
+ ],
120
+ "time": "2018-09-21T13:07:52+00:00"
121
+ }
122
+ ],
123
+ "packages-dev": [],
124
+ "aliases": [],
125
+ "minimum-stability": "stable",
126
+ "stability-flags": [],
127
+ "prefer-stable": false,
128
+ "prefer-lowest": false,
129
+ "platform": [],
130
+ "platform-dev": []
131
+ }
lib/geonames/geonames-country-info.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
lib/get-client-ip.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /*
4
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
5
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
6
 
7
  This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,6 @@ class GetClientIp {
26
  protected $useProxyWhitelist = false;
27
 
28
  public function __construct() {
29
- $this->proxyWhitelist[] = '';
30
  $this->proxyWhitelist[] = '::1';
31
  $this->proxyWhitelist[] = '127.0.0.1';
32
  }
@@ -57,8 +56,12 @@ class GetClientIp {
57
  if ($this->useProxyWhitelist) {
58
  // Add the REMOTE_ADDR to the available IP pool
59
  $ip_list_reverse = array_merge($ip_list_reverse, $currentIpList);
60
- $ip_list_reverse = array_map('geoip_detect_normalize_ip', $ip_list_reverse);
61
- $ip_list_reverse = array_diff($ip_list_reverse, $this->proxyWhitelist);
 
 
 
 
62
  }
63
 
64
  return $ip_list_reverse;
1
  <?php
2
 
3
  /*
4
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
5
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
6
 
7
  This program is free software; you can redistribute it and/or modify
26
  protected $useProxyWhitelist = false;
27
 
28
  public function __construct() {
 
29
  $this->proxyWhitelist[] = '::1';
30
  $this->proxyWhitelist[] = '127.0.0.1';
31
  }
56
  if ($this->useProxyWhitelist) {
57
  // Add the REMOTE_ADDR to the available IP pool
58
  $ip_list_reverse = array_merge($ip_list_reverse, $currentIpList);
59
+
60
+ $ip_list_reverse = array_filter($ip_list_reverse, function($value) {
61
+ $value = trim($value);
62
+ if (!$value) return false;
63
+ return false === geoip_detect_is_ip_equal($value, $this->proxyWhitelist);
64
+ });
65
  }
66
 
67
  return $ip_list_reverse;
lib/vendor/symfony/http-foundation/IpUtils.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
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 Symfony\Component\HttpFoundation;
13
+
14
+ /**
15
+ * Http utility functions.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class IpUtils
20
+ {
21
+ private static $checkedIps = [];
22
+
23
+ /**
24
+ * This class should not be instantiated.
25
+ */
26
+ private function __construct()
27
+ {
28
+ }
29
+
30
+ /**
31
+ * Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets.
32
+ *
33
+ * @param string $requestIp IP to check
34
+ * @param string|array $ips List of IPs or subnets (can be a string if only a single one)
35
+ *
36
+ * @return bool Whether the IP is valid
37
+ */
38
+ public static function checkIp($requestIp, $ips)
39
+ {
40
+ if (!\is_array($ips)) {
41
+ $ips = [$ips];
42
+ }
43
+
44
+ $method = substr_count($requestIp, ':') > 1 ? 'checkIp6' : 'checkIp4';
45
+
46
+ foreach ($ips as $ip) {
47
+ if (self::$method($requestIp, $ip)) {
48
+ return true;
49
+ }
50
+ }
51
+
52
+ return false;
53
+ }
54
+
55
+ /**
56
+ * Compares two IPv4 addresses.
57
+ * In case a subnet is given, it checks if it contains the request IP.
58
+ *
59
+ * @param string $requestIp IPv4 address to check
60
+ * @param string $ip IPv4 address or subnet in CIDR notation
61
+ *
62
+ * @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet
63
+ */
64
+ public static function checkIp4($requestIp, $ip)
65
+ {
66
+ $cacheKey = $requestIp.'-'.$ip;
67
+ if (isset(self::$checkedIps[$cacheKey])) {
68
+ return self::$checkedIps[$cacheKey];
69
+ }
70
+
71
+ if (!filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
72
+ return self::$checkedIps[$cacheKey] = false;
73
+ }
74
+
75
+ if (false !== strpos($ip, '/')) {
76
+ list($address, $netmask) = explode('/', $ip, 2);
77
+
78
+ if ('0' === $netmask) {
79
+ return self::$checkedIps[$cacheKey] = filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
80
+ }
81
+
82
+ if ($netmask < 0 || $netmask > 32) {
83
+ return self::$checkedIps[$cacheKey] = false;
84
+ }
85
+ } else {
86
+ $address = $ip;
87
+ $netmask = 32;
88
+ }
89
+
90
+ if (false === ip2long($address)) {
91
+ return self::$checkedIps[$cacheKey] = false;
92
+ }
93
+
94
+ return self::$checkedIps[$cacheKey] = 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
95
+ }
96
+
97
+ /**
98
+ * Compares two IPv6 addresses.
99
+ * In case a subnet is given, it checks if it contains the request IP.
100
+ *
101
+ * @author David Soria Parra <dsp at php dot net>
102
+ *
103
+ * @see https://github.com/dsp/v6tools
104
+ *
105
+ * @param string $requestIp IPv6 address to check
106
+ * @param string $ip IPv6 address or subnet in CIDR notation
107
+ *
108
+ * @return bool Whether the IP is valid
109
+ *
110
+ * @throws \RuntimeException When IPV6 support is not enabled
111
+ */
112
+ public static function checkIp6($requestIp, $ip)
113
+ {
114
+ $cacheKey = $requestIp.'-'.$ip;
115
+ if (isset(self::$checkedIps[$cacheKey])) {
116
+ return self::$checkedIps[$cacheKey];
117
+ }
118
+
119
+ if (!((\extension_loaded('sockets') && \defined('AF_INET6')) || @inet_pton('::1'))) {
120
+ throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
121
+ }
122
+
123
+ if (false !== strpos($ip, '/')) {
124
+ list($address, $netmask) = explode('/', $ip, 2);
125
+
126
+ if ('0' === $netmask) {
127
+ return (bool) unpack('n*', @inet_pton($address));
128
+ }
129
+
130
+ if ($netmask < 1 || $netmask > 128) {
131
+ return self::$checkedIps[$cacheKey] = false;
132
+ }
133
+ } else {
134
+ $address = $ip;
135
+ $netmask = 128;
136
+ }
137
+
138
+ $bytesAddr = unpack('n*', @inet_pton($address));
139
+ $bytesTest = unpack('n*', @inet_pton($requestIp));
140
+
141
+ if (!$bytesAddr || !$bytesTest) {
142
+ return self::$checkedIps[$cacheKey] = false;
143
+ }
144
+
145
+ for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
146
+ $left = $netmask - 16 * ($i - 1);
147
+ $left = ($left <= 16) ? $left : 16;
148
+ $mask = ~(0xffff >> $left) & 0xffff;
149
+ if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
150
+ return self::$checkedIps[$cacheKey] = false;
151
+ }
152
+ }
153
+
154
+ return self::$checkedIps[$cacheKey] = true;
155
+ }
156
+ }
lib/vendor/symfony/http-foundation/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2004-2019 Fabien Potencier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
  === GeoIP Detection ===
2
  Contributors: benjaminpick
3
  Tags: geoip, maxmind, geolocation, locator
4
- Requires at least: 3.5
5
- Tested up to: 5.0
6
  Requires PHP: 5.4
7
  Stable tag: trunk
8
  License: GPLv3 or later
@@ -18,28 +18,29 @@ as a shortcode, or via CSS body classes. The city & country names are translated
18
 
19
  = Features: =
20
 
21
- * Provides these 5 functions (see [API Documentation](https://github.com/yellowtree/wp-geoip-detect/wiki/API-Documentation)):
22
  * `geoip_detect2_get_info_from_ip($ip, $locales = array('en'), $options = array())`: Lookup Geo-Information of the specified IP
23
  * `geoip_detect2_get_info_from_current_ip($locales = array('en'), $options = array())`: Lookup Geo-Information of the current website user
24
  * `geoip_detect2_get_current_source_description(...)`: Return a human-readable label of the currently chosen source.
25
  * `geoip_detect2_get_external_ip_adress()`: Fetch the internet adress of the webserver
26
  * `geoip_detect2_get_client_ip()`: Get client IP (even if it is behind a reverse proxy)
27
- * You can use one of these data sources (see [comparison](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#which-data-source-should-i-choose)):
28
- * Free: [Maxmind GeoIP2 Lite City](http://dev.maxmind.com/geoip/geoip2/geolite2/), automatically updated every month (licensed CC BY-SA. See [FAQ](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ).)
29
  * Commercial: [Maxmind GeoIP2 City](https://www.maxmind.com/en/geoip2-country-database) or [Maxmind GeoIP2 Country](https://www.maxmind.com/en/geoip2-city)
30
  * Commercial Web-API: [Maxmind GeoIP2 Precision](https://www.maxmind.com/en/geoip2-precision-services) (City, Country or Insights)
31
  * Free (default source): [HostIP.info](http://www.hostip.info/) (IPv4 only)
32
  * Hosting-Provider dependent: [Cloudflare](https://support.cloudflare.com/hc/en-us/articles/200168236-What-does-CloudFlare-IP-Geolocation-do-) or [Amazon AWS CloudFront](https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/) (Country)
33
  * For the property names, see the results of a specific IP in the wordpress backend (under *Tools > GeoIP Detection*).
34
  * You can include these properties into your posts and pages by using the shortcode `[geoip_detect2 property="country.name" default="(country could not be detected)" lang="en"]` (where 'country.name' can be one of the other property names as well, and 'default' and 'lang' are optional).
35
- * You can show or hide content by using a shortcode `[geoip_detect2_show_if country="FR, DE" not_city="Berlin"]TEXT[/geoip_detect2_show_if]`. See [API Documentation](https://github.com/yellowtree/wp-geoip-detect/wiki/API-Documentation#show-or-hide-content-depending-on-the-location).
36
  * When enabled on the options page, it adds CSS classes to the body tag such as `geoip-province-HE`, `geoip-country-DE` and `geoip-continent-EU`.
37
  * When enabled on the options page, the client IP respects a reverse proxy of the server.
38
  * If you are using [Contact Form 7](https://wordpress.org/plugins/contact-form-7/), you can use these shortcodes:
39
- * A select input with all countries, the detected country being selected by default `[geoip_detect2_countries mycountry]`
40
- * Tracking information for the email text `[geoip_detect2_user_info]`
 
41
 
42
- See [API Documentation](https://github.com/yellowtree/wp-geoip-detect/wiki/API-Documentation) for more info.
43
 
44
  = How can I use these functions? =
45
 
@@ -54,7 +55,7 @@ See [API Documentation](https://github.com/yellowtree/wp-geoip-detect/wiki/API-D
54
 
55
  *GDPR: This plugin does not store any cookie or user-dependent data. If you use a web-based source (hostip.info, Maxmind Precision), the plugin stores all IPs that visited the site in a cache (by default for 7 days) for performance reasons. If you want to disable this behavior, add `define('GEOIP_DETECT_READER_CACHE_TIME', 0);` in your theme's `function.php`. Be especially careful when using this information to change prices or selling options, as this might not be legal.*
56
 
57
- *This extension is "charity-ware". If you are happy with it, please [leave a tip](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BSYUZHS8FH3CL) for the benefit of [this charity](http://www.jmem-hainichen.de/homepage). (See [FAQ](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#what-you-mean-by-this-plugin-is-charity-ware) for more infos.)*
58
 
59
  *This product can provide GeoLite2 data created by MaxMind, available from http://www.maxmind.com.*
60
 
@@ -70,29 +71,29 @@ Does `geoip_detect2_get_info_from_current_ip()` return the same country, regardl
70
 
71
  == Frequently Asked Questions ==
72
 
73
- [Technically speaking, how could I verify if my visitor comes from Germany?](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#technically-speaking-how-could-i-verify-if-my-visitor-comes-from-germany)
74
 
75
- [How can I show text only if the visitor is coming from Germany?](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#how-can-i-show-text-only-if-the-visitor-is-coming-from-germany)
76
 
77
- [How can I add the current country name as text in my page?](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#how-can-i-add-the-current-country-name-as-text-in-my-page)
78
 
79
- [Which data source should I choose?](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#which-data-source-should-i-choose)
80
 
81
- [Can I change the time period how long the data is cached?](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#can-i-change-the-time-period-how-long-the-data-is-cached)
82
 
83
- [The Maxmind Lite databases are licensed Creative Commons ShareAlike-Attribution. When do I need to give attribution?](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#the-maxmind-lite-databases-are-licensed-creative-commons-sharealike-attribution-when-do-i-need-to-give-attribution)
84
 
85
- [Does this plugin work in a MultiSite-Network environment?](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#does-this-plugin-work-in-a-multisite-network-environment)
86
 
87
- [What do you mean by "This plugin is charity-ware"?](https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#what-do-you-mean-by-this-plugin-is-charity-ware)
88
 
89
  **Further documentation**
90
 
91
- [API Documentation](https://github.com/yellowtree/wp-geoip-detect/wiki/API-Documentation)
92
 
93
- [Record Properties](https://github.com/yellowtree/wp-geoip-detect/wiki/Record-Properties)
94
 
95
- [API usage examples](https://github.com/yellowtree/wp-geoip-detect/wiki/API-Usage-Examples)
96
 
97
  == Screenshots ==
98
 
@@ -116,6 +117,15 @@ New: Shortcode for showing/hiding content!
116
 
117
  == Changelog ==
118
 
 
 
 
 
 
 
 
 
 
119
  = 2.9.2 =
120
  * FIX: ContactForm7-Mailtag disabled mailtags from other plugins.
121
 
@@ -132,4 +142,4 @@ New: Shortcode for showing/hiding content!
132
  * NEW: The CSS classes that are added to the body-tag (if enabled in the options) now also include the most specific subdivision (`geoip-province-HE`).
133
  * Maxmind vendor code was updated to the current version (2.9.0).
134
 
135
- [Older changelog](https://github.com/yellowtree/wp-geoip-detect/blob/master/CHANGELOG.md)
1
  === GeoIP Detection ===
2
  Contributors: benjaminpick
3
  Tags: geoip, maxmind, geolocation, locator
4
+ Requires at least: 4.0
5
+ Tested up to: 5.1
6
  Requires PHP: 5.4
7
  Stable tag: trunk
8
  License: GPLv3 or later
18
 
19
  = Features: =
20
 
21
+ * Provides these 5 functions (see [API Documentation](https://github.com/yellowtree/geoip-detect/wiki/API-Documentation)):
22
  * `geoip_detect2_get_info_from_ip($ip, $locales = array('en'), $options = array())`: Lookup Geo-Information of the specified IP
23
  * `geoip_detect2_get_info_from_current_ip($locales = array('en'), $options = array())`: Lookup Geo-Information of the current website user
24
  * `geoip_detect2_get_current_source_description(...)`: Return a human-readable label of the currently chosen source.
25
  * `geoip_detect2_get_external_ip_adress()`: Fetch the internet adress of the webserver
26
  * `geoip_detect2_get_client_ip()`: Get client IP (even if it is behind a reverse proxy)
27
+ * You can use one of these data sources (see [comparison](https://github.com/yellowtree/geoip-detect/wiki/FAQ#which-data-source-should-i-choose)):
28
+ * Free: [Maxmind GeoIP2 Lite City](http://dev.maxmind.com/geoip/geoip2/geolite2/), automatically updated every month (licensed CC BY-SA. See [FAQ](https://github.com/yellowtree/geoip-detect/wiki/FAQ).)
29
  * Commercial: [Maxmind GeoIP2 City](https://www.maxmind.com/en/geoip2-country-database) or [Maxmind GeoIP2 Country](https://www.maxmind.com/en/geoip2-city)
30
  * Commercial Web-API: [Maxmind GeoIP2 Precision](https://www.maxmind.com/en/geoip2-precision-services) (City, Country or Insights)
31
  * Free (default source): [HostIP.info](http://www.hostip.info/) (IPv4 only)
32
  * Hosting-Provider dependent: [Cloudflare](https://support.cloudflare.com/hc/en-us/articles/200168236-What-does-CloudFlare-IP-Geolocation-do-) or [Amazon AWS CloudFront](https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/) (Country)
33
  * For the property names, see the results of a specific IP in the wordpress backend (under *Tools > GeoIP Detection*).
34
  * You can include these properties into your posts and pages by using the shortcode `[geoip_detect2 property="country.name" default="(country could not be detected)" lang="en"]` (where 'country.name' can be one of the other property names as well, and 'default' and 'lang' are optional).
35
+ * You can show or hide content by using a shortcode `[geoip_detect2_show_if country="FR, DE" not_city="Berlin"]TEXT[/geoip_detect2_show_if]`. See [API Documentation](https://github.com/yellowtree/geoip-detect/wiki/API-Documentation#show-or-hide-content-depending-on-the-location).
36
  * When enabled on the options page, it adds CSS classes to the body tag such as `geoip-province-HE`, `geoip-country-DE` and `geoip-continent-EU`.
37
  * When enabled on the options page, the client IP respects a reverse proxy of the server.
38
  * If you are using [Contact Form 7](https://wordpress.org/plugins/contact-form-7/), you can use these shortcodes:
39
+ * A select input with all countries, the detected country being selected by default: `[geoip_detect2_countries mycountry]`
40
+ * A text input that is pre-filled with the detected city (or other property): `[geoip_detect2_text_input city property:city lang:fr id:id class:class default:Paris]`
41
+ * GeoIP information for the email text: `[geoip_detect2_user_info]`
42
 
43
+ See [API Documentation](https://github.com/yellowtree/geoip-detect/wiki/API-Documentation) for more info.
44
 
45
  = How can I use these functions? =
46
 
55
 
56
  *GDPR: This plugin does not store any cookie or user-dependent data. If you use a web-based source (hostip.info, Maxmind Precision), the plugin stores all IPs that visited the site in a cache (by default for 7 days) for performance reasons. If you want to disable this behavior, add `define('GEOIP_DETECT_READER_CACHE_TIME', 0);` in your theme's `function.php`. Be especially careful when using this information to change prices or selling options, as this might not be legal.*
57
 
58
+ *This extension is "charity-ware". If you are happy with it, please [leave a tip](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BSYUZHS8FH3CL) for the benefit of [this charity](http://www.jmem-hainichen.de/homepage). (See [FAQ](https://github.com/yellowtree/geoip-detect/wiki/FAQ#what-you-mean-by-this-plugin-is-charity-ware) for more infos.)*
59
 
60
  *This product can provide GeoLite2 data created by MaxMind, available from http://www.maxmind.com.*
61
 
71
 
72
  == Frequently Asked Questions ==
73
 
74
+ [Technically speaking, how could I verify if my visitor comes from Germany?](https://github.com/yellowtree/geoip-detect/wiki/FAQ#technically-speaking-how-could-i-verify-if-my-visitor-comes-from-germany)
75
 
76
+ [How can I show text only if the visitor is coming from Germany?](https://github.com/yellowtree/geoip-detect/wiki/FAQ#how-can-i-show-text-only-if-the-visitor-is-coming-from-germany)
77
 
78
+ [How can I add the current country name as text in my page?](https://github.com/yellowtree/geoip-detect/wiki/FAQ#how-can-i-add-the-current-country-name-as-text-in-my-page)
79
 
80
+ [Which data source should I choose?](https://github.com/yellowtree/geoip-detect/wiki/FAQ#which-data-source-should-i-choose)
81
 
82
+ [Can I change the time period how long the data is cached?](https://github.com/yellowtree/geoip-detect/wiki/FAQ#can-i-change-the-time-period-how-long-the-data-is-cached)
83
 
84
+ [The Maxmind Lite databases are licensed Creative Commons ShareAlike-Attribution. When do I need to give attribution?](https://github.com/yellowtree/geoip-detect/wiki/FAQ#the-maxmind-lite-databases-are-licensed-creative-commons-sharealike-attribution-when-do-i-need-to-give-attribution)
85
 
86
+ [Does this plugin work in a MultiSite-Network environment?](https://github.com/yellowtree/geoip-detect/wiki/FAQ#does-this-plugin-work-in-a-multisite-network-environment)
87
 
88
+ [What do you mean by "This plugin is charity-ware"?](https://github.com/yellowtree/geoip-detect/wiki/FAQ#what-do-you-mean-by-this-plugin-is-charity-ware)
89
 
90
  **Further documentation**
91
 
92
+ [API Documentation](https://github.com/yellowtree/geoip-detect/wiki/API-Documentation)
93
 
94
+ [Record Properties](https://github.com/yellowtree/geoip-detect/wiki/Record-Properties)
95
 
96
+ [API usage examples](https://github.com/yellowtree/geoip-detect/wiki/API-Usage-Examples)
97
 
98
  == Screenshots ==
99
 
117
 
118
  == Changelog ==
119
 
120
+ * Removed unnecessary file from symfony distribution
121
+
122
+ = 2.10.0 =
123
+ * NEW: The whitelisted proxies can now be subnets such as `11.11.11.0/24`
124
+ * NEW: Add a ContactForm7-Tag `geoip_detect2_text_input` (see https://github.com/yellowtree/geoip-detect/wiki/API-Documentation#create-a-text-input-that-is-prefilled-with-a-geodetected-property)
125
+ * NEW: A new wordpress filter allows overriding of the detected geo-information inside the `geoip_detect2_shortcode_show_if`-Shortcode. Use the already-existing filter `geoip_detect2_record_information` instead if you want to override this information for all shortcodes and API calls.
126
+ * Updated Maxmind vendor code
127
+ * Increased WP minimum version to 4.0
128
+
129
  = 2.9.2 =
130
  * FIX: ContactForm7-Mailtag disabled mailtags from other plugins.
131
 
142
  * NEW: The CSS classes that are added to the body-tag (if enabled in the options) now also include the most specific subdivision (`geoip-province-HE`).
143
  * Maxmind vendor code was updated to the current version (2.9.0).
144
 
145
+ [Older changelog](https://github.com/yellowtree/geoip-detect/blob/master/CHANGELOG.md)
shortcode.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
@@ -63,7 +63,7 @@ add_shortcode('geoip_detect', 'geoip_detect_shortcode');
63
  *
64
  * @since 2.5.7 New attribute `ip`
65
  */
66
- function geoip_detect2_shortcode($attr, $content, $shortcodeName)
67
  {
68
  $attr = shortcode_atts(array(
69
  'skip_cache' => 'false',
@@ -71,6 +71,7 @@ function geoip_detect2_shortcode($attr, $content, $shortcodeName)
71
  'default' => '',
72
  'property' => '',
73
  'ip' => null,
 
74
  ), $attr, $shortcodeName);
75
 
76
  $skipCache = filter_var($attr['skip_cache'], FILTER_VALIDATE_BOOLEAN );
@@ -87,12 +88,12 @@ function geoip_detect2_shortcode($attr, $content, $shortcodeName)
87
  $userInfo = geoip_detect2_get_info_from_ip($ip, $locales, $options);
88
 
89
  if ($userInfo->isEmpty)
90
- return $defaultValue . '<!-- GeoIP Detect: No information found for this IP (' . geoip_detect2_get_client_ip() . ') -->';
91
 
92
  try {
93
  $return = geoip_detect2_shortcode_get_property($userInfo, $attr['property']);
94
  } catch (\RuntimeException $e) {
95
- return $defaultValue . '<!-- GeoIP Detect: Invalid property name. -->';
96
  }
97
 
98
  if (is_object($return) && $return instanceof \GeoIp2\Record\AbstractPlaceRecord) {
@@ -100,7 +101,7 @@ function geoip_detect2_shortcode($attr, $content, $shortcodeName)
100
  }
101
 
102
  if (is_object($return) || is_array($return)) {
103
- return $defaultValue . '<!-- GeoIP Detect: Invalid property name (sub-property missing). -->';
104
  }
105
 
106
  if ($return)
@@ -189,8 +190,10 @@ add_shortcode('geoip_detect2_get_current_source_description', 'geoip_detect2_sho
189
  * `[geoip_detect2_countries_select name="mycountry" default="US"]`
190
  * Visitor's country is preselected, but in case the country is unknown, use "United States"
191
  *
 
192
  * @param string $name Name of the form element
193
  * @param string $id CSS Id of element
 
194
  * @param string $class CSS Class of element
195
  * @param string $lang Language(s) (optional. If not set, current site language is used.)
196
  * @param string $selected Which country to select by default (2-letter ISO code.) (optional. If not set, the country will be detected by client ip.)
@@ -222,11 +225,6 @@ function geoip_detect2_shortcode_country_select($attr) {
222
  'aria-required' => !empty($attr['required']) ? 'required' : '',
223
  'aria-invalid' => !empty($attr['invalid']) ? $attr['invalid'] : '',
224
  );
225
- $select_attrs_html = '';
226
- foreach ($select_attrs as $key => $value) {
227
- if ($value)
228
- $select_attrs_html .= $key . '="' . esc_attr($value) . '" ';
229
- }
230
 
231
  $countryInfo = new YellowTree\GeoipDetect\Geonames\CountryInformation();
232
  $countries = $countryInfo->getAllCountries($locales);
@@ -244,7 +242,7 @@ function geoip_detect2_shortcode_country_select($attr) {
244
  */
245
  $countries = apply_filters('geoip_detect2_shortcode_country_select_countries', $countries, $attr);
246
 
247
- $html = '<select ' . $select_attrs_html . '>';
248
  if (!empty($attr['include_blank']) && $attr['include_blank'] !== 'false')
249
  $html .= '<option value="">---</option>';
250
  foreach ($countries as $code => $label) {
@@ -264,8 +262,18 @@ function geoip_detect2_shortcode_country_select($attr) {
264
  add_shortcode('geoip_detect2_countries_select', 'geoip_detect2_shortcode_country_select');
265
  add_shortcode('geoip_detect2_countries', 'geoip_detect2_shortcode_country_select');
266
 
 
 
 
 
 
 
 
 
 
267
  /**
268
- *
 
269
  * Examples:
270
  *
271
  * `[geoip_detect2_countries mycountry id:id class:class lang:fr]`
@@ -313,14 +321,108 @@ function geoip_detect2_shortcode_country_select_wpcf7($tag) {
313
  return $html;
314
  }
315
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  add_action( 'wpcf7_init', 'geoip_detect2_add_wpcf7_shortcodes' );
317
  function geoip_detect2_add_wpcf7_shortcodes() {
318
  if (function_exists('wpcf7_add_form_tag')) {
319
  // >=CF 4.6
320
  wpcf7_add_form_tag(array('geoip_detect2_countries', 'geoip_detect2_countries*'), 'geoip_detect2_shortcode_country_select_wpcf7', true);
 
321
  } else if (function_exists('wpcf7_add_shortcode')) {
322
  // < CF 4.6
323
  wpcf7_add_shortcode(array('geoip_detect2_countries', 'geoip_detect2_countries*'), 'geoip_detect2_shortcode_country_select_wpcf7', true);
 
324
  }
325
  }
326
 
@@ -486,7 +588,17 @@ function geoip_detect2_shortcode_show_if($attr, $content = null, $shortcodeName
486
 
487
  $options = array('skipCache' => $skipCache);
488
 
489
- $info = geoip_detect2_get_info_from_current_ip($locales, $options);
 
 
 
 
 
 
 
 
 
 
490
  $isConditionMatching = true;
491
 
492
  foreach ($attributeNames as $shortcodeParamName => $maxmindName) {
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
63
  *
64
  * @since 2.5.7 New attribute `ip`
65
  */
66
+ function geoip_detect2_shortcode($attr, $content = '', $shortcodeName = 'geoip_detect2')
67
  {
68
  $attr = shortcode_atts(array(
69
  'skip_cache' => 'false',
71
  'default' => '',
72
  'property' => '',
73
  'ip' => null,
74
+ 'add_error' => true,
75
  ), $attr, $shortcodeName);
76
 
77
  $skipCache = filter_var($attr['skip_cache'], FILTER_VALIDATE_BOOLEAN );
88
  $userInfo = geoip_detect2_get_info_from_ip($ip, $locales, $options);
89
 
90
  if ($userInfo->isEmpty)
91
+ return $defaultValue . ($attr['add_error'] ? '<!-- GeoIP Detect: No information found for this IP (' . geoip_detect2_get_client_ip() . ') -->' : '');
92
 
93
  try {
94
  $return = geoip_detect2_shortcode_get_property($userInfo, $attr['property']);
95
  } catch (\RuntimeException $e) {
96
+ return $defaultValue . ($attr['add_error'] ? '<!-- GeoIP Detect: Invalid property name. -->' : '');
97
  }
98
 
99
  if (is_object($return) && $return instanceof \GeoIp2\Record\AbstractPlaceRecord) {
101
  }
102
 
103
  if (is_object($return) || is_array($return)) {
104
+ return $defaultValue . ($attr['add_error'] ? '<!-- GeoIP Detect: Invalid property name (sub-property missing). -->' : '');
105
  }
106
 
107
  if ($return)
190
  * `[geoip_detect2_countries_select name="mycountry" default="US"]`
191
  * Visitor's country is preselected, but in case the country is unknown, use "United States"
192
  *
193
+ * $attr is an array that can have these properties:
194
  * @param string $name Name of the form element
195
  * @param string $id CSS Id of element
196
+ * @param bool $required If the field is required or not
197
  * @param string $class CSS Class of element
198
  * @param string $lang Language(s) (optional. If not set, current site language is used.)
199
  * @param string $selected Which country to select by default (2-letter ISO code.) (optional. If not set, the country will be detected by client ip.)
225
  'aria-required' => !empty($attr['required']) ? 'required' : '',
226
  'aria-invalid' => !empty($attr['invalid']) ? $attr['invalid'] : '',
227
  );
 
 
 
 
 
228
 
229
  $countryInfo = new YellowTree\GeoipDetect\Geonames\CountryInformation();
230
  $countries = $countryInfo->getAllCountries($locales);
242
  */
243
  $countries = apply_filters('geoip_detect2_shortcode_country_select_countries', $countries, $attr);
244
 
245
+ $html = '<select ' . _geoip_detect_flatten_html_attr($select_attrs) . '>';
246
  if (!empty($attr['include_blank']) && $attr['include_blank'] !== 'false')
247
  $html .= '<option value="">---</option>';
248
  foreach ($countries as $code => $label) {
262
  add_shortcode('geoip_detect2_countries_select', 'geoip_detect2_shortcode_country_select');
263
  add_shortcode('geoip_detect2_countries', 'geoip_detect2_shortcode_country_select');
264
 
265
+ function _geoip_detect_flatten_html_attr($attr) {
266
+ $html = '';
267
+ foreach ($attr as $key => $value) {
268
+ if ($value)
269
+ $html .= $key . '="' . esc_attr($value) . '" ';
270
+ }
271
+ return $html;
272
+ }
273
+
274
  /**
275
+ * Generating a country select field that has the geoip value as default
276
+ *
277
  * Examples:
278
  *
279
  * `[geoip_detect2_countries mycountry id:id class:class lang:fr]`
321
  return $html;
322
  }
323
 
324
+ /**
325
+ * Generating a <input />-field that has a geoip value as default
326
+ *
327
+ * Property can be: continent, country, city, postal.code or any other property understood by `geoip_detect2_get_info_from_ip`
328
+ *
329
+ * Examples:
330
+ *
331
+ * `[geoip_detect2_text_input name="city" property="city" lang="fr" id="id" class="class"]`
332
+ * A text input that has the detetected city as default (with CSS id "#id" and class ".class")
333
+ *
334
+ * `[geoip_detect2_text_input name="city" property="city" lang="fr" id="id" class="class" default="Paris"]`
335
+ * As above, but in case the city is unknown, use "Paris"
336
+ *
337
+ * $attr is an array that can have these properties:
338
+ * @param string $property Maxmind property string (e.g. "city" or "postal.code")
339
+ * @param string $name Name of the form element
340
+ * @param bool $required If the field is required or not
341
+ * @param string $id CSS Id of element
342
+ * @param string $class CSS Class of element
343
+ * @param string $lang Language(s) (optional. If not set, current site language is used.)
344
+ * @param string $default Default Value that will be used if country cannot be detected (optional)
345
+ * @param bool $skip_cache
346
+ * @param string $ip
347
+ * @param string $placeholder
348
+ *
349
+ * @return string The generated HTML
350
+ */
351
+ function geoip_detect2_shortcode_text_input($attr) {
352
+ $value = geoip_detect2_shortcode($attr + array('add_error' => false));
353
+
354
+ $html_attrs = array(
355
+ 'type' => 'text',
356
+ 'name' => !empty($attr['name']) ? $attr['name'] : 'geoip-text-input',
357
+ 'id' => @$attr['id'],
358
+ 'class' => !empty($attr['class']) ? $attr['class'] : 'geoip-text-input',
359
+ 'aria-required' => !empty($attr['required']) ? 'required' : '',
360
+ 'aria-invalid' => !empty($attr['invalid']) ? $attr['invalid'] : '',
361
+ 'value' => $value,
362
+ 'placeholder' => @$attr['placeholder']
363
+ );
364
+
365
+ $html = '<input ' . _geoip_detect_flatten_html_attr($html_attrs) . '/>';
366
+ return $html;
367
+ }
368
+ add_shortcode('geoip_detect2_text_input', 'geoip_detect2_shortcode_text_input');
369
+ add_shortcode('geoip_detect2_input', 'geoip_detect2_shortcode_text_input');
370
+
371
+ /**
372
+ * Generating a text field that has a geoip value as default
373
+ *
374
+ * Property can be: continent, country, city, postal.code or any other property understood by `geoip_detect2_get_info_from_ip`
375
+ *
376
+ * Examples:
377
+ *
378
+ * `[geoip_detect2_text_input city property:city lang:fr id:id class:class]`
379
+ * A text input that has the detetected city as default (with CSS id "#id" and class ".class")
380
+ *
381
+ * `[geoip_detect2_text_input city property:city lang:fr id:id class:class default:Paris]`
382
+ * As above, but in case the city is unknown, use "Paris"
383
+ *
384
+ */
385
+ function geoip_detect2_shortcode_text_input_wpcf7($tag) {
386
+ $tag = new WPCF7_FormTag( $tag );
387
+
388
+ $default = (string) reset( $tag->values );
389
+ $default = $tag->get_default_option($default, array('multiple' => false));
390
+ $default = wpcf7_get_hangover( $tag->name, $default ); // Get from $_POST if available
391
+
392
+ $class = wpcf7_form_controls_class( $tag->type );
393
+ $validation_error = wpcf7_get_validation_error( $tag->name );
394
+ if ($validation_error)
395
+ $class .= ' wpcf7-not-valid';
396
+
397
+ $attr = array(
398
+ 'name' => $tag->name,
399
+ 'required' => substr($tag->type, -1) == '*',
400
+ 'invalid' => $validation_error ? 'true' : 'false',
401
+ 'id' => $tag->get_id_option(),
402
+ 'class' => $tag->get_class_option( $class ),
403
+ 'lang' => $tag->get_option('lang', '', true),
404
+ 'property' => $tag->get_option('property', '', true),
405
+ 'default' => $tag->get_option('default', '', true),
406
+ );
407
+ $html = geoip_detect2_shortcode_text_input($attr);
408
+
409
+ $html = sprintf(
410
+ '<span class="wpcf7-form-control-wrap %1$s">%2$s %3$s</span>',
411
+ sanitize_html_class( $tag->name ), $html, $validation_error );
412
+
413
+ return $html;
414
+ }
415
+
416
  add_action( 'wpcf7_init', 'geoip_detect2_add_wpcf7_shortcodes' );
417
  function geoip_detect2_add_wpcf7_shortcodes() {
418
  if (function_exists('wpcf7_add_form_tag')) {
419
  // >=CF 4.6
420
  wpcf7_add_form_tag(array('geoip_detect2_countries', 'geoip_detect2_countries*'), 'geoip_detect2_shortcode_country_select_wpcf7', true);
421
+ wpcf7_add_form_tag(array('geoip_detect2_text_input', 'geoip_detect2_text_input*'), 'geoip_detect2_shortcode_text_input_wpcf7', true);
422
  } else if (function_exists('wpcf7_add_shortcode')) {
423
  // < CF 4.6
424
  wpcf7_add_shortcode(array('geoip_detect2_countries', 'geoip_detect2_countries*'), 'geoip_detect2_shortcode_country_select_wpcf7', true);
425
+ wpcf7_add_shortcode(array('geoip_detect2_text_input', 'geoip_detect2_text_input*'), 'geoip_detect2_shortcode_text_input_wpcf7', true);
426
  }
427
  }
428
 
588
 
589
  $options = array('skipCache' => $skipCache);
590
 
591
+ $info = geoip_detect2_get_info_from_current_ip($locales, $options);
592
+
593
+ /**
594
+ * You can override the detected location information here.
595
+ * E.g. "Show if in Paris, but if the user has given an adress in his profile, use that city instead"
596
+ * @param YellowTree\GeoipDetect\DataSources\City $info
597
+ * @param array $attr Shortcode attributes given to the function.
598
+ * @param bool $showContentIfMatch Should the content be shown (TRUE) or hidden (FALSE) if the conditions are true?
599
+ */
600
+ $info = apply_filters('geoip_detect2_shortcode_show_if_ip_info_override', $info, $attr, $showContentIfMatch);
601
+
602
  $isConditionMatching = true;
603
 
604
  foreach ($attributeNames as $shortcodeParamName => $maxmindName) {
upgrade-plugin.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Copyright 2013-2018 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
1
  <?php
2
  /*
3
+ Copyright 2013-2019 Yellow Tree, Siegen, Germany
4
  Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
5
 
6
  This program is free software; you can redistribute it and/or modify
vendor/composer/ca-bundle/res/cacert.pem CHANGED
@@ -1,7 +1,7 @@
1
  ##
2
  ## Bundle of CA Root Certificates
3
  ##
4
- ## Certificate data from Mozilla as of: Wed Oct 17 03:12:10 2018 GMT
5
  ##
6
  ## This is a bundle of X.509 certificates of public Certificate Authorities
7
  ## (CA). These were automatically extracted from Mozilla's root certificates
@@ -14,7 +14,7 @@
14
  ## Just configure this file as the SSLCACertificateFile.
15
  ##
16
  ## Conversion done with mk-ca-bundle.pl version 1.27.
17
- ## SHA256: 3f875d87fee4ce3d966c69f1d6c111aa95c0143ade59e4fa24882c582bb5f0ca
18
  ##
19
 
20
 
@@ -261,28 +261,6 @@ gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
261
  X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
262
  -----END CERTIFICATE-----
263
 
264
- Visa eCommerce Root
265
- ===================
266
- -----BEGIN CERTIFICATE-----
267
- MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG
268
- EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug
269
- QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2
270
- WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm
271
- VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
272
- bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL
273
- F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b
274
- RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0
275
- TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI
276
- /k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs
277
- GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
278
- MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc
279
- CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW
280
- YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz
281
- zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
282
- YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
283
- 398znM/jra6O1I7mT1GvFpLgXPYHDw==
284
- -----END CERTIFICATE-----
285
-
286
  Comodo AAA Services root
287
  ========================
288
  -----BEGIN CERTIFICATE-----
@@ -3238,3 +3216,186 @@ BgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E
3238
  AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk
3239
  AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
3240
  -----END CERTIFICATE-----
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ##
2
  ## Bundle of CA Root Certificates
3
  ##
4
+ ## Certificate data from Mozilla as of: Wed Jan 23 04:12:09 2019 GMT
5
  ##
6
  ## This is a bundle of X.509 certificates of public Certificate Authorities
7
  ## (CA). These were automatically extracted from Mozilla's root certificates
14
  ## Just configure this file as the SSLCACertificateFile.
15
  ##
16
  ## Conversion done with mk-ca-bundle.pl version 1.27.
17
+ ## SHA256: 18372117493b5b7ec006c31d966143fc95a9464a2b5f8d5188e23c5557b2292d
18
  ##
19
 
20
 
261
  X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
262
  -----END CERTIFICATE-----
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  Comodo AAA Services root
265
  ========================
266
  -----BEGIN CERTIFICATE-----
3216
  AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk
3217
  AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
3218
  -----END CERTIFICATE-----
3219
+
3220
+ GTS Root R1
3221
+ ===========
3222
+ -----BEGIN CERTIFICATE-----
3223
+ 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
3247
+ CFF1pkgl
3248
+ -----END CERTIFICATE-----
3249
+
3250
+ GTS Root R2
3251
+ ===========
3252
+ -----BEGIN CERTIFICATE-----
3253
+ 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
3277
+ o/DUhgkC
3278
+ -----END CERTIFICATE-----
3279
+
3280
+ GTS Root R3
3281
+ ===========
3282
+ -----BEGIN CERTIFICATE-----
3283
+ MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV
3284
+ UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg
3285
+ UjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE
3286
+ ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcq
3287
+ hkjOPQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUU
3288
+ Rout736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24Cej
3289
+ QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP
3290
+ 0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFukfCPAlaUs3L6JbyO5o91lAFJekazInXJ0
3291
+ glMLfalAvWhgxeG4VDvBNhcl2MG9AjEAnjWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOa
3292
+ KaqW04MjyaR7YbPMAuhd
3293
+ -----END CERTIFICATE-----
3294
+
3295
+ GTS Root R4
3296
+ ===========
3297
+ -----BEGIN CERTIFICATE-----
3298
+ MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV
3299
+ UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg
3300
+ UjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE
3301
+ ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcq
3302
+ hkjOPQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa
3303
+ 6zzuhXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqj
3304
+ QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV
3305
+ 2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0CMRw3J5QdCHojXohw0+WbhXRIjVhLfoI
3306
+ N+4Zba3bssx9BzT1YBkstTTZbyACMANxsbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11x
3307
+ zPKwTdb+mciUqXWi4w==
3308
+ -----END CERTIFICATE-----
3309
+
3310
+ UCA Global G2 Root
3311
+ ==================
3312
+ -----BEGIN CERTIFICATE-----
3313
+ MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQG
3314
+ EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBHbG9iYWwgRzIgUm9vdDAeFw0x
3315
+ NjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0xCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlU
3316
+ cnVzdDEbMBkGA1UEAwwSVUNBIEdsb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
3317
+ MIICCgKCAgEAxeYrb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmT
3318
+ oni9kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzmVHqUwCoV
3319
+ 8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/RVogvGjqNO7uCEeBHANBS
3320
+ h6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDcC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8o
3321
+ LTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIjtm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/
3322
+ R+zvWr9LesGtOxdQXGLYD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBe
3323
+ KW4bHAyvj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6DlNaBa
3324
+ 4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6iIis7nCs+dwp4wwc
3325
+ OxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznPO6Q0ibd5Ei9Hxeepl2n8pndntd97
3326
+ 8XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
3327
+ BBYEFIHEjMz15DD/pQwIX4wVZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo
3328
+ 5sOASD0Ee/ojL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5
3329
+ 1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl1qnN3e92mI0A
3330
+ Ds0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oUb3n09tDh05S60FdRvScFDcH9
3331
+ yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LVPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAX
3332
+ c47QN6MUPJiVAAwpBVueSUmxX8fjy88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHo
3333
+ jhJi6IjMtX9Gl8CbEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZk
3334
+ bxqgDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI+Vg7RE+x
3335
+ ygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGyYiGqhkCyLmTTX8jjfhFn
3336
+ RR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bXUB+K+wb1whnw0A==
3337
+ -----END CERTIFICATE-----
3338
+
3339
+ UCA Extended Validation Root
3340
+ ============================
3341
+ -----BEGIN CERTIFICATE-----
3342
+ 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
3366
+ dhh2n1ax
3367
+ -----END CERTIFICATE-----
3368
+
3369
+ Certigna Root CA
3370
+ ================
3371
+ -----BEGIN CERTIFICATE-----
3372
+ MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UE
3373
+ BhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAwMiA0ODE0NjMwODEwMDAzNjEZ
3374
+ MBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0xMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjda
3375
+ MFoxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYz
3376
+ MDgxMDAwMzYxGTAXBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC
3377
+ DwAwggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sOty3tRQgX
3378
+ stmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9MCiBtnyN6tMbaLOQdLNyz
3379
+ KNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPuI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8
3380
+ JXrJhFwLrN1CTivngqIkicuQstDuI7pmTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16
3381
+ XdG+RCYyKfHx9WzMfgIhC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq
3382
+ 4NYKpkDfePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3YzIoej
3383
+ wpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWTCo/1VTp2lc5ZmIoJ
3384
+ lXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1kJWumIWmbat10TWuXekG9qxf5kBdI
3385
+ jzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp/
3386
+ /TBt2dzhauH8XwIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
3387
+ HQYDVR0OBBYEFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of
3388
+ 1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczovL3d3d3cuY2Vy
3389
+ dGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilodHRwOi8vY3JsLmNlcnRpZ25h
3390
+ LmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYraHR0cDovL2NybC5kaGlteW90aXMuY29tL2Nl
3391
+ cnRpZ25hcm9vdGNhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOIt
3392
+ OoldaDgvUSILSo3L6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxP
3393
+ TGRGHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH60BGM+RFq
3394
+ 7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncBlA2c5uk5jR+mUYyZDDl3
3395
+ 4bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdio2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd
3396
+ 8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS
3397
+ 6Cvu5zHbugRqh5jnxV/vfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaY
3398
+ tlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS
3399
+ aX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde
3400
+ E4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
3401
+ -----END CERTIFICATE-----
vendor/composer/installed.json CHANGED
@@ -1,23 +1,22 @@
1
  [
2
  {
3
- "name": "maxmind/web-service-common",
4
- "version": "v0.5.0",
5
- "version_normalized": "0.5.0.0",
6
  "source": {
7
  "type": "git",
8
- "url": "https://github.com/maxmind/web-service-common-php.git",
9
- "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b"
10
  },
11
  "dist": {
12
  "type": "zip",
13
- "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/61a9836fa3bb1743ab89752bae5005d71e78c73b",
14
- "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b",
15
  "shasum": ""
16
  },
17
  "require": {
18
- "composer/ca-bundle": "^1.0.3",
19
- "ext-curl": "*",
20
- "ext-json": "*",
21
  "php": ">=5.4"
22
  },
23
  "require-dev": {
@@ -25,13 +24,12 @@
25
  "phpunit/phpunit": "4.*",
26
  "squizlabs/php_codesniffer": "3.*"
27
  },
28
- "time": "2018-02-12T22:31:54+00:00",
29
  "type": "library",
30
  "installation-source": "dist",
31
  "autoload": {
32
  "psr-4": {
33
- "MaxMind\\Exception\\": "src/Exception",
34
- "MaxMind\\WebService\\": "src/WebService"
35
  }
36
  },
37
  "notification-url": "https://packagist.org/downloads/",
@@ -40,48 +38,54 @@
40
  ],
41
  "authors": [
42
  {
43
- "name": "Gregory Oschwald",
44
- "email": "goschwald@maxmind.com"
 
45
  }
46
  ],
47
- "description": "Internal MaxMind Web Service API",
48
- "homepage": "https://github.com/maxmind/web-service-common-php"
 
 
 
 
 
 
 
49
  },
50
  {
51
- "name": "maxmind-db/reader",
52
- "version": "v1.3.0",
53
- "version_normalized": "1.3.0.0",
54
  "source": {
55
  "type": "git",
56
- "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
57
- "reference": "e042b4f8a2dff41e19019faf16427178b07fbd58"
58
  },
59
  "dist": {
60
  "type": "zip",
61
- "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/e042b4f8a2dff41e19019faf16427178b07fbd58",
62
- "reference": "e042b4f8a2dff41e19019faf16427178b07fbd58",
63
  "shasum": ""
64
  },
65
  "require": {
 
 
 
66
  "php": ">=5.4"
67
  },
68
  "require-dev": {
69
  "friendsofphp/php-cs-fixer": "2.*",
70
- "phpunit/phpunit": "4.* || 5.*",
71
- "satooshi/php-coveralls": "1.0.*",
72
  "squizlabs/php_codesniffer": "3.*"
73
  },
74
- "suggest": {
75
- "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
76
- "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
77
- "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
78
- },
79
- "time": "2018-02-21T21:23:33+00:00",
80
  "type": "library",
81
  "installation-source": "dist",
82
  "autoload": {
83
  "psr-4": {
84
- "MaxMind\\Db\\": "src/MaxMind/Db"
 
85
  }
86
  },
87
  "notification-url": "https://packagist.org/downloads/",
@@ -90,52 +94,48 @@
90
  ],
91
  "authors": [
92
  {
93
- "name": "Gregory J. Oschwald",
94
- "email": "goschwald@maxmind.com",
95
- "homepage": "http://www.maxmind.com/"
96
  }
97
  ],
98
- "description": "MaxMind DB Reader API",
99
- "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php",
100
- "keywords": [
101
- "database",
102
- "geoip",
103
- "geoip2",
104
- "geolocation",
105
- "maxmind"
106
- ]
107
  },
108
  {
109
- "name": "geoip2/geoip2",
110
- "version": "v2.9.0",
111
- "version_normalized": "2.9.0.0",
112
  "source": {
113
  "type": "git",
114
- "url": "https://github.com/maxmind/GeoIP2-php.git",
115
- "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77"
116
  },
117
  "dist": {
118
  "type": "zip",
119
- "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/a807fbf65212eef5d8d2db1a1b31082b53633d77",
120
- "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77",
121
  "shasum": ""
122
  },
123
  "require": {
124
- "maxmind-db/reader": "~1.0",
125
- "maxmind/web-service-common": "~0.5",
126
  "php": ">=5.4"
127
  },
128
  "require-dev": {
129
  "friendsofphp/php-cs-fixer": "2.*",
130
- "phpunit/phpunit": "4.*",
 
131
  "squizlabs/php_codesniffer": "3.*"
132
  },
133
- "time": "2018-04-10T15:32:59+00:00",
 
 
 
 
 
134
  "type": "library",
135
  "installation-source": "dist",
136
  "autoload": {
137
  "psr-4": {
138
- "GeoIp2\\": "src"
139
  }
140
  },
141
  "notification-url": "https://packagist.org/downloads/",
@@ -149,10 +149,10 @@
149
  "homepage": "http://www.maxmind.com/"
150
  }
151
  ],
152
- "description": "MaxMind GeoIP2 PHP API",
153
- "homepage": "https://github.com/maxmind/GeoIP2-php",
154
  "keywords": [
155
- "IP",
156
  "geoip",
157
  "geoip2",
158
  "geolocation",
@@ -161,17 +161,17 @@
161
  },
162
  {
163
  "name": "composer/ca-bundle",
164
- "version": "1.1.3",
165
- "version_normalized": "1.1.3.0",
166
  "source": {
167
  "type": "git",
168
  "url": "https://github.com/composer/ca-bundle.git",
169
- "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660"
170
  },
171
  "dist": {
172
  "type": "zip",
173
- "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660",
174
- "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660",
175
  "shasum": ""
176
  },
177
  "require": {
@@ -184,7 +184,7 @@
184
  "psr/log": "^1.0",
185
  "symfony/process": "^2.5 || ^3.0 || ^4.0"
186
  },
187
- "time": "2018-10-18T06:09:13+00:00",
188
  "type": "library",
189
  "extra": {
190
  "branch-alias": {
1
  [
2
  {
3
+ "name": "geoip2/geoip2",
4
+ "version": "v2.9.0",
5
+ "version_normalized": "2.9.0.0",
6
  "source": {
7
  "type": "git",
8
+ "url": "https://github.com/maxmind/GeoIP2-php.git",
9
+ "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77"
10
  },
11
  "dist": {
12
  "type": "zip",
13
+ "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/a807fbf65212eef5d8d2db1a1b31082b53633d77",
14
+ "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77",
15
  "shasum": ""
16
  },
17
  "require": {
18
+ "maxmind-db/reader": "~1.0",
19
+ "maxmind/web-service-common": "~0.5",
 
20
  "php": ">=5.4"
21
  },
22
  "require-dev": {
24
  "phpunit/phpunit": "4.*",
25
  "squizlabs/php_codesniffer": "3.*"
26
  },
27
+ "time": "2018-04-10T15:32:59+00:00",
28
  "type": "library",
29
  "installation-source": "dist",
30
  "autoload": {
31
  "psr-4": {
32
+ "GeoIp2\\": "src"
 
33
  }
34
  },
35
  "notification-url": "https://packagist.org/downloads/",
38
  ],
39
  "authors": [
40
  {
41
+ "name": "Gregory J. Oschwald",
42
+ "email": "goschwald@maxmind.com",
43
+ "homepage": "http://www.maxmind.com/"
44
  }
45
  ],
46
+ "description": "MaxMind GeoIP2 PHP API",
47
+ "homepage": "https://github.com/maxmind/GeoIP2-php",
48
+ "keywords": [
49
+ "IP",
50
+ "geoip",
51
+ "geoip2",
52
+ "geolocation",
53
+ "maxmind"
54
+ ]
55
  },
56
  {
57
+ "name": "maxmind/web-service-common",
58
+ "version": "v0.5.0",
59
+ "version_normalized": "0.5.0.0",
60
  "source": {
61
  "type": "git",
62
+ "url": "https://github.com/maxmind/web-service-common-php.git",
63
+ "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b"
64
  },
65
  "dist": {
66
  "type": "zip",
67
+ "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/61a9836fa3bb1743ab89752bae5005d71e78c73b",
68
+ "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b",
69
  "shasum": ""
70
  },
71
  "require": {
72
+ "composer/ca-bundle": "^1.0.3",
73
+ "ext-curl": "*",
74
+ "ext-json": "*",
75
  "php": ">=5.4"
76
  },
77
  "require-dev": {
78
  "friendsofphp/php-cs-fixer": "2.*",
79
+ "phpunit/phpunit": "4.*",
 
80
  "squizlabs/php_codesniffer": "3.*"
81
  },
82
+ "time": "2018-02-12T22:31:54+00:00",
 
 
 
 
 
83
  "type": "library",
84
  "installation-source": "dist",
85
  "autoload": {
86
  "psr-4": {
87
+ "MaxMind\\Exception\\": "src/Exception",
88
+ "MaxMind\\WebService\\": "src/WebService"
89
  }
90
  },
91
  "notification-url": "https://packagist.org/downloads/",
94
  ],
95
  "authors": [
96
  {
97
+ "name": "Gregory Oschwald",
98
+ "email": "goschwald@maxmind.com"
 
99
  }
100
  ],
101
+ "description": "Internal MaxMind Web Service API",
102
+ "homepage": "https://github.com/maxmind/web-service-common-php"
 
 
 
 
 
 
 
103
  },
104
  {
105
+ "name": "maxmind-db/reader",
106
+ "version": "v1.4.1",
107
+ "version_normalized": "1.4.1.0",
108
  "source": {
109
  "type": "git",
110
+ "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
111
+ "reference": "eb83d0ee1c1f9b8a340206302136bc81ee02ae74"
112
  },
113
  "dist": {
114
  "type": "zip",
115
+ "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/eb83d0ee1c1f9b8a340206302136bc81ee02ae74",
116
+ "reference": "eb83d0ee1c1f9b8a340206302136bc81ee02ae74",
117
  "shasum": ""
118
  },
119
  "require": {
 
 
120
  "php": ">=5.4"
121
  },
122
  "require-dev": {
123
  "friendsofphp/php-cs-fixer": "2.*",
124
+ "phpunit/phpunit": "4.* || 5.*",
125
+ "satooshi/php-coveralls": "1.0.*",
126
  "squizlabs/php_codesniffer": "3.*"
127
  },
128
+ "suggest": {
129
+ "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
130
+ "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
131
+ "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
132
+ },
133
+ "time": "2019-01-04T19:55:56+00:00",
134
  "type": "library",
135
  "installation-source": "dist",
136
  "autoload": {
137
  "psr-4": {
138
+ "MaxMind\\Db\\": "src/MaxMind/Db"
139
  }
140
  },
141
  "notification-url": "https://packagist.org/downloads/",
149
  "homepage": "http://www.maxmind.com/"
150
  }
151
  ],
152
+ "description": "MaxMind DB Reader API",
153
+ "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php",
154
  "keywords": [
155
+ "database",
156
  "geoip",
157
  "geoip2",
158
  "geolocation",
161
  },
162
  {
163
  "name": "composer/ca-bundle",
164
+ "version": "1.1.4",
165
+ "version_normalized": "1.1.4.0",
166
  "source": {
167
  "type": "git",
168
  "url": "https://github.com/composer/ca-bundle.git",
169
+ "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d"
170
  },
171
  "dist": {
172
  "type": "zip",
173
+ "url": "https://api.github.com/repos/composer/ca-bundle/zipball/558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
174
+ "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
175
  "shasum": ""
176
  },
177
  "require": {
184
  "psr/log": "^1.0",
185
  "symfony/process": "^2.5 || ^3.0 || ^4.0"
186
  },
187
+ "time": "2019-01-28T09:30:10+00:00",
188
  "type": "library",
189
  "extra": {
190
  "branch-alias": {
vendor/geoip2/geoip2/README.md CHANGED
@@ -395,7 +395,7 @@ The GeoIP2 PHP API uses [Semantic Versioning](http://semver.org/).
395
 
396
  ## Copyright and License ##
397
 
398
- This software is Copyright (c) 2013-2018 by MaxMind, Inc.
399
 
400
  This is free software, licensed under the Apache License, Version 2.0.
401
 
395
 
396
  ## Copyright and License ##
397
 
398
+ This software is Copyright (c) 2013-2019 by MaxMind, Inc.
399
 
400
  This is free software, licensed under the Apache License, Version 2.0.
401
 
vendor/maxmind-db/reader/CHANGELOG.md CHANGED
@@ -1,6 +1,34 @@
1
  CHANGELOG
2
  =========
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  1.3.0 (2018-02-21)
5
  ------------------
6
 
1
  CHANGELOG
2
  =========
3
 
4
+ 1.4.1 (2019-01-04)
5
+ ------------------
6
+
7
+ * The `maxminddb` extension now returns a string when a `uint32`
8
+ value is greater than `LONG_MAX`. Previously, the value would
9
+ overflow. This generally only affects 32-bit machines. Reported
10
+ by Remi Collet. GitHub #79.
11
+ * For `uint64` values, the `maxminddb` extension now returns an
12
+ integer rather than a string when the value is less than or equal
13
+ to `LONG_MAX`. This more closely matches the behavior of the pure
14
+ PHP reader.
15
+
16
+ 1.4.0 (2018-11-20)
17
+ ------------------
18
+
19
+ * The `maxminddb` extension now has the arginfo when using reflection.
20
+ PR by Remi Collet. GitHub #75.
21
+ * The `maxminddb` extension now provides `MINFO()` function that
22
+ displays the extension version and the libmaxminddb version. PR by
23
+ Remi Collet. GitHub #74.
24
+ * The `maxminddb` `configure` script now uses `pkg-config` when
25
+ available to get libmaxmindb build info. PR by Remi Collet.
26
+ GitHub #73.
27
+ * The pure PHP reader now correctly decodes integers on 32-bit platforms.
28
+ Previously, large integers would overflow. Reported by Remi Collet.
29
+ GitHub #77.
30
+ * There are small performance improvements for the pure PHP reader.
31
+
32
  1.3.0 (2018-02-21)
33
  ------------------
34
 
vendor/maxmind-db/reader/README.md CHANGED
@@ -134,8 +134,8 @@ client API, please see [our support page](http://www.maxmind.com/en/support).
134
 
135
  ## Requirements ##
136
 
137
- This library requires PHP 5.4 or greater. The pure PHP reader included with
138
- this library works and is tested with HHVM.
139
 
140
  The GMP or BCMath extension may be required to read some databases
141
  using the pure PHP API.
@@ -151,6 +151,6 @@ The MaxMind DB Reader PHP API uses [Semantic Versioning](http://semver.org/).
151
 
152
  ## Copyright and License ##
153
 
154
- This software is Copyright (c) 2014-2017 by MaxMind, Inc.
155
 
156
  This is free software, licensed under the Apache License, Version 2.0.
134
 
135
  ## Requirements ##
136
 
137
+ This library requires PHP 5.4 or greater. The pure PHP reader included is
138
+ compatible with HHVM.
139
 
140
  The GMP or BCMath extension may be required to read some databases
141
  using the pure PHP API.
151
 
152
  ## Copyright and License ##
153
 
154
+ This software is Copyright (c) 2014-2018 by MaxMind, Inc.
155
 
156
  This is free software, licensed under the Apache License, Version 2.0.
vendor/maxmind-db/reader/autoload.php CHANGED
@@ -4,15 +4,15 @@
4
  * PSR-4 autoloader implementation for the MaxMind\DB namespace.
5
  * First we define the 'mmdb_autoload' function, and then we register
6
  * it with 'spl_autoload_register' so that PHP knows to use it.
 
 
7
  */
8
 
9
  /**
10
  * Automatically include the file that defines <code>class</code>.
11
  *
12
  * @param string $class
13
- * the name of the class to load
14
- *
15
- * @return void
16
  */
17
  function mmdb_autoload($class)
18
  {
@@ -23,10 +23,9 @@ function mmdb_autoload($class)
23
  * to extend in the future if (for example) the test classes
24
  * begin to use one another.
25
  */
26
- $namespace_map = array('MaxMind\\Db\\' => __DIR__ . '/src/MaxMind/Db/');
27
 
28
- foreach ($namespace_map as $prefix => $dir)
29
- {
30
  /* First swap out the namespace prefix with a directory... */
31
  $path = str_replace($prefix, $dir, $class);
32
 
@@ -37,7 +36,9 @@ function mmdb_autoload($class)
37
  $path = $path . '.php';
38
 
39
  /* $path should now contain the path to a PHP file defining $class */
40
- @include $path;
 
 
41
  }
42
  }
43
 
4
  * PSR-4 autoloader implementation for the MaxMind\DB namespace.
5
  * First we define the 'mmdb_autoload' function, and then we register
6
  * it with 'spl_autoload_register' so that PHP knows to use it.
7
+ *
8
+ * @param mixed $class
9
  */
10
 
11
  /**
12
  * Automatically include the file that defines <code>class</code>.
13
  *
14
  * @param string $class
15
+ * the name of the class to load
 
 
16
  */
17
  function mmdb_autoload($class)
18
  {
23
  * to extend in the future if (for example) the test classes
24
  * begin to use one another.
25
  */
26
+ $namespace_map = ['MaxMind\\Db\\' => __DIR__ . '/src/MaxMind/Db/'];
27
 
28
+ foreach ($namespace_map as $prefix => $dir) {
 
29
  /* First swap out the namespace prefix with a directory... */
30
  $path = str_replace($prefix, $dir, $class);
31
 
36
  $path = $path . '.php';
37
 
38
  /* $path should now contain the path to a PHP file defining $class */
39
+ if (file_exists($path)) {
40
+ include $path;
41
+ }
42
  }
43
  }
44
 
vendor/maxmind-db/reader/ext/config.m4 CHANGED
@@ -6,13 +6,34 @@ PHP_ARG_ENABLE(maxminddb-debug, for MaxMind DB debug support,
6
  [ --enable-maxminddb-debug Enable enable MaxMind DB deubg support], no, no)
7
 
8
  if test $PHP_MAXMINDDB != "no"; then
9
- PHP_CHECK_LIBRARY(maxminddb, MMDB_open)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  if test $PHP_MAXMINDDB_DEBUG != "no"; then
12
  CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror"
13
  fi
14
 
15
- PHP_ADD_LIBRARY(maxminddb, 1, MAXMINDDB_SHARED_LIBADD)
16
  PHP_SUBST(MAXMINDDB_SHARED_LIBADD)
17
 
18
  PHP_NEW_EXTENSION(maxminddb, maxminddb.c, $ext_shared)
6
  [ --enable-maxminddb-debug Enable enable MaxMind DB deubg support], no, no)
7
 
8
  if test $PHP_MAXMINDDB != "no"; then
9
+
10
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
11
+
12
+ AC_MSG_CHECKING(for libmaxminddb)
13
+ if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libmaxminddb; then
14
+ dnl retrieve build options from pkg-config
15
+ if $PKG_CONFIG libmaxminddb --atleast-version 1.0.0; then
16
+ LIBMAXMINDDB_INC=`$PKG_CONFIG libmaxminddb --cflags`
17
+ LIBMAXMINDDB_LIB=`$PKG_CONFIG libmaxminddb --libs`
18
+ LIBMAXMINDDB_VER=`$PKG_CONFIG libmaxminddb --modversion`
19
+ AC_MSG_RESULT(found version $LIBMAXMINDDB_VER)
20
+ else
21
+ AC_MSG_ERROR(system libmaxminddb must be upgraded to version >= 1.0.0)
22
+ fi
23
+ PHP_EVAL_LIBLINE($LIBMAXMINDDB_LIB, MAXMINDDB_SHARED_LIBADD)
24
+ PHP_EVAL_INCLINE($LIBMAXMINDDB_INC)
25
+ else
26
+ AC_MSG_RESULT(pkg-config information missing)
27
+ AC_MSG_WARN(will use libmaxmxinddb from compiler default path)
28
+
29
+ PHP_CHECK_LIBRARY(maxminddb, MMDB_open)
30
+ PHP_ADD_LIBRARY(maxminddb, 1, MAXMINDDB_SHARED_LIBADD)
31
+ fi
32
 
33
  if test $PHP_MAXMINDDB_DEBUG != "no"; then
34
  CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror"
35
  fi
36
 
 
37
  PHP_SUBST(MAXMINDDB_SHARED_LIBADD)
38
 
39
  PHP_NEW_EXTENSION(maxminddb, maxminddb.c, $ext_shared)
vendor/maxmind-db/reader/ext/maxminddb.c CHANGED
@@ -20,6 +20,7 @@
20
  #include <php.h>
21
  #include <zend.h>
22
  #include "Zend/zend_exceptions.h"
 
23
  #include <maxminddb.h>
24
 
25
  #ifdef ZTS
@@ -77,6 +78,8 @@ static void handle_uint128(const MMDB_entry_data_list_s *entry_data_list,
77
  zval *z_value TSRMLS_DC);
78
  static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list,
79
  zval *z_value TSRMLS_DC);
 
 
80
  static zend_class_entry * lookup_class(const char *name TSRMLS_DC);
81
 
82
  #define CHECK_ALLOCATED(val) \
@@ -115,6 +118,10 @@ static inline maxminddb_obj *php_maxminddb_fetch_object(zend_object *obj TSRMLS_
115
  #endif
116
  }
117
 
 
 
 
 
118
  PHP_METHOD(MaxMind_Db_Reader, __construct){
119
  char *db_file = NULL;
120
  strsize_t name_len;
@@ -150,6 +157,10 @@ PHP_METHOD(MaxMind_Db_Reader, __construct){
150
  mmdb_obj->mmdb = mmdb;
151
  }
152
 
 
 
 
 
153
  PHP_METHOD(MaxMind_Db_Reader, get){
154
  char *ip_address = NULL;
155
  strsize_t name_len;
@@ -225,6 +236,9 @@ PHP_METHOD(MaxMind_Db_Reader, get){
225
  MMDB_free_entry_data_list(entry_data_list);
226
  }
227
 
 
 
 
228
  PHP_METHOD(MaxMind_Db_Reader, metadata){
229
  if (ZEND_NUM_ARGS() != 0) {
230
  THROW_EXCEPTION("InvalidArgumentException",
@@ -326,7 +340,7 @@ static const MMDB_entry_data_list_s *handle_entry_data_list(
326
  ZVAL_LONG(z_value, entry_data_list->entry_data.uint16);
327
  break;
328
  case MMDB_DATA_TYPE_UINT32:
329
- ZVAL_LONG(z_value, entry_data_list->entry_data.uint32);
330
  break;
331
  case MMDB_DATA_TYPE_BOOLEAN:
332
  ZVAL_BOOL(z_value, entry_data_list->entry_data.boolean);
@@ -439,17 +453,51 @@ static void handle_uint128(const MMDB_entry_data_list_s *entry_data_list,
439
  efree(num_str);
440
  }
441
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
442
  static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list,
443
  zval *z_value TSRMLS_DC)
444
  {
445
- // We return it as a string because PHP uses signed longs
 
 
 
 
 
 
 
 
 
 
446
  char *int_str;
447
- spprintf(&int_str, 0, "%" PRIu64,
448
- entry_data_list->entry_data.uint64);
449
  CHECK_ALLOCATED(int_str);
450
 
451
  _ZVAL_STRING(z_value, int_str);
452
  efree(int_str);
 
453
  }
454
 
455
  static zend_class_entry *lookup_class(const char *name TSRMLS_DC)
@@ -520,11 +568,11 @@ static zend_object_value maxminddb_create_handler(
520
 
521
  /* *INDENT-OFF* */
522
  static zend_function_entry maxminddb_methods[] = {
523
- PHP_ME(MaxMind_Db_Reader, __construct, NULL,
524
  ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
525
- PHP_ME(MaxMind_Db_Reader, close, NULL, ZEND_ACC_PUBLIC)
526
- PHP_ME(MaxMind_Db_Reader, get, NULL, ZEND_ACC_PUBLIC)
527
- PHP_ME(MaxMind_Db_Reader, metadata, NULL, ZEND_ACC_PUBLIC)
528
  { NULL, NULL, NULL }
529
  };
530
  /* *INDENT-ON* */
@@ -546,6 +594,17 @@ PHP_MINIT_FUNCTION(maxminddb){
546
  return SUCCESS;
547
  }
548
 
 
 
 
 
 
 
 
 
 
 
 
549
  zend_module_entry maxminddb_module_entry = {
550
  STANDARD_MODULE_HEADER,
551
  PHP_MAXMINDDB_EXTNAME,
@@ -554,7 +613,7 @@ zend_module_entry maxminddb_module_entry = {
554
  NULL,
555
  NULL,
556
  NULL,
557
- NULL,
558
  PHP_MAXMINDDB_VERSION,
559
  STANDARD_MODULE_PROPERTIES
560
  };
20
  #include <php.h>
21
  #include <zend.h>
22
  #include "Zend/zend_exceptions.h"
23
+ #include "ext/standard/info.h"
24
  #include <maxminddb.h>
25
 
26
  #ifdef ZTS
78
  zval *z_value TSRMLS_DC);
79
  static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list,
80
  zval *z_value TSRMLS_DC);
81
+ static void handle_uint32(const MMDB_entry_data_list_s *entry_data_list,
82
+ zval *z_value TSRMLS_DC);
83
  static zend_class_entry * lookup_class(const char *name TSRMLS_DC);
84
 
85
  #define CHECK_ALLOCATED(val) \
118
  #endif
119
  }
120
 
121
+ ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_construct, 0, 0, 1)
122
+ ZEND_ARG_INFO(0, db_file)
123
+ ZEND_END_ARG_INFO()
124
+
125
  PHP_METHOD(MaxMind_Db_Reader, __construct){
126
  char *db_file = NULL;
127
  strsize_t name_len;
157
  mmdb_obj->mmdb = mmdb;
158
  }
159
 
160
+ ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_get, 0, 0, 1)
161
+ ZEND_ARG_INFO(0, ip_address)
162
+ ZEND_END_ARG_INFO()
163
+
164
  PHP_METHOD(MaxMind_Db_Reader, get){
165
  char *ip_address = NULL;
166
  strsize_t name_len;
236
  MMDB_free_entry_data_list(entry_data_list);
237
  }
238
 
239
+ ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_void, 0, 0, 0)
240
+ ZEND_END_ARG_INFO()
241
+
242
  PHP_METHOD(MaxMind_Db_Reader, metadata){
243
  if (ZEND_NUM_ARGS() != 0) {
244
  THROW_EXCEPTION("InvalidArgumentException",
340
  ZVAL_LONG(z_value, entry_data_list->entry_data.uint16);
341
  break;
342
  case MMDB_DATA_TYPE_UINT32:
343
+ handle_uint32(entry_data_list, z_value TSRMLS_CC);
344
  break;
345
  case MMDB_DATA_TYPE_BOOLEAN:
346
  ZVAL_BOOL(z_value, entry_data_list->entry_data.boolean);
453
  efree(num_str);
454
  }
455
 
456
+ static void handle_uint32(const MMDB_entry_data_list_s *entry_data_list,
457
+ zval *z_value TSRMLS_DC)
458
+ {
459
+ uint32_t val = entry_data_list->entry_data.uint32;
460
+
461
+ #if LONG_MAX >= UINT32_MAX
462
+ ZVAL_LONG(z_value, val);
463
+ return;
464
+ #else
465
+ if (val <= LONG_MAX) {
466
+ ZVAL_LONG(z_value, val);
467
+ return;
468
+ }
469
+
470
+ char *int_str;
471
+ spprintf(&int_str, 0, "%" PRIu32, val);
472
+ CHECK_ALLOCATED(int_str);
473
+
474
+ _ZVAL_STRING(z_value, int_str);
475
+ efree(int_str);
476
+ #endif
477
+ }
478
+
479
+
480
  static void handle_uint64(const MMDB_entry_data_list_s *entry_data_list,
481
  zval *z_value TSRMLS_DC)
482
  {
483
+ uint64_t val = entry_data_list->entry_data.uint64;
484
+
485
+ #if LONG_MAX >= UINT64_MAX
486
+ ZVAL_LONG(z_value, val);
487
+ return;
488
+ #else
489
+ if (val <= LONG_MAX) {
490
+ ZVAL_LONG(z_value, val);
491
+ return;
492
+ }
493
+
494
  char *int_str;
495
+ spprintf(&int_str, 0, "%" PRIu64, val);
 
496
  CHECK_ALLOCATED(int_str);
497
 
498
  _ZVAL_STRING(z_value, int_str);
499
  efree(int_str);
500
+ #endif
501
  }
502
 
503
  static zend_class_entry *lookup_class(const char *name TSRMLS_DC)
568
 
569
  /* *INDENT-OFF* */
570
  static zend_function_entry maxminddb_methods[] = {
571
+ PHP_ME(MaxMind_Db_Reader, __construct, arginfo_maxmindbreader_construct,
572
  ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
573
+ PHP_ME(MaxMind_Db_Reader, close, arginfo_maxmindbreader_void, ZEND_ACC_PUBLIC)
574
+ PHP_ME(MaxMind_Db_Reader, get, arginfo_maxmindbreader_get, ZEND_ACC_PUBLIC)
575
+ PHP_ME(MaxMind_Db_Reader, metadata, arginfo_maxmindbreader_void, ZEND_ACC_PUBLIC)
576
  { NULL, NULL, NULL }
577
  };
578
  /* *INDENT-ON* */
594
  return SUCCESS;
595
  }
596
 
597
+ static PHP_MINFO_FUNCTION(maxminddb)
598
+ {
599
+ php_info_print_table_start();
600
+
601
+ php_info_print_table_row(2, "MaxMind DB Reader", "enabled");
602
+ php_info_print_table_row(2, "maxminddb extension version", PHP_MAXMINDDB_VERSION);
603
+ php_info_print_table_row(2, "libmaxminddb library version", MMDB_lib_version());
604
+
605
+ php_info_print_table_end();
606
+ }
607
+
608
  zend_module_entry maxminddb_module_entry = {
609
  STANDARD_MODULE_HEADER,
610
  PHP_MAXMINDDB_EXTNAME,
613
  NULL,
614
  NULL,
615
  NULL,
616
+ PHP_MINFO(maxminddb),
617
  PHP_MAXMINDDB_VERSION,
618
  STANDARD_MODULE_PROPERTIES
619
  };
vendor/maxmind-db/reader/ext/php_maxminddb.h CHANGED
@@ -15,7 +15,7 @@
15
 
16
  #ifndef PHP_MAXMINDDB_H
17
  #define PHP_MAXMINDDB_H 1
18
- #define PHP_MAXMINDDB_VERSION "1.3.0"
19
  #define PHP_MAXMINDDB_EXTNAME "maxminddb"
20
 
21
  extern zend_module_entry maxminddb_module_entry;
15
 
16
  #ifndef PHP_MAXMINDDB_H
17
  #define PHP_MAXMINDDB_H 1
18
+ #define PHP_MAXMINDDB_VERSION "1.4.1"
19
  #define PHP_MAXMINDDB_EXTNAME "maxminddb"
20
 
21
  extern zend_module_entry maxminddb_module_entry;
vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php CHANGED
@@ -38,7 +38,7 @@ class Reader
38
  */
39
  public function __construct($database)
40
  {
41
- if (func_num_args() !== 1) {
42
  throw new \InvalidArgumentException(
43
  'The constructor takes exactly one argument.'
44
  );
@@ -88,13 +88,13 @@ class Reader
88
  */
89
  public function get($ipAddress)
90
  {
91
- if (func_num_args() !== 1) {
92
  throw new \InvalidArgumentException(
93
  'Method takes exactly one argument.'
94
  );
95
  }
96
 
97
- if (!is_resource($this->fileHandle)) {
98
  throw new \BadMethodCallException(
99
  'Attempt to read from a closed MaxMind DB.'
100
  );
@@ -125,13 +125,13 @@ class Reader
125
  // XXX - could simplify. Done as a byte array to ease porting
126
  $rawAddress = array_merge(unpack('C*', inet_pton($ipAddress)));
127
 
128
- $bitCount = count($rawAddress) * 8;
129
 
130
  // The first node of the tree is always node 0, at the beginning of the
131
  // value
132
  $node = $this->startNode($bitCount);
133
 
134
- for ($i = 0; $i < $bitCount; $i++) {
135
  if ($node >= $this->metadata->nodeCount) {
136
  break;
137
  }
@@ -175,7 +175,7 @@ class Reader
175
  }
176
  $node = 0;
177
 
178
- for ($i = 0; $i < 96 && $node < $this->metadata->nodeCount; $i++) {
179
  $node = $this->readNode($node, 0);
180
  }
181
  $this->ipV4Start = $node;
@@ -203,7 +203,7 @@ class Reader
203
  $middle = 0x0F & $middle;
204
  }
205
  $bytes = Util::read($this->fileHandle, $baseOffset + $index * 4, 3);
206
- list(, $node) = unpack('N', chr($middle) . $bytes);
207
 
208
  return $node;
209
  case 32:
@@ -249,8 +249,8 @@ class Reader
249
  $metadataMaxLengthExcludingMarker
250
  = min(self::$METADATA_MAX_SIZE, $fileSize) - $markerLength;
251
 
252
- for ($i = 0; $i <= $metadataMaxLengthExcludingMarker; $i++) {
253
- for ($j = 0; $j < $markerLength; $j++) {
254
  fseek($handle, $fileSize - $i - $j - 1);
255
  $matchBit = fgetc($handle);
256
  if ($matchBit !== $marker[$markerLength - $j - 1]) {
@@ -274,7 +274,7 @@ class Reader
274
  */
275
  public function metadata()
276
  {
277
- if (func_num_args()) {
278
  throw new \InvalidArgumentException(
279
  'Method takes no arguments.'
280
  );
@@ -282,7 +282,7 @@ class Reader
282
 
283
  // Not technically required, but this makes it consistent with
284
  // C extension and it allows us to change our implementation later.
285
- if (!is_resource($this->fileHandle)) {
286
  throw new \BadMethodCallException(
287
  'Attempt to read from a closed MaxMind DB.'
288
  );
@@ -299,7 +299,7 @@ class Reader
299
  */
300
  public function close()
301
  {
302
- if (!is_resource($this->fileHandle)) {
303
  throw new \BadMethodCallException(
304
  'Attempt to close a closed MaxMind DB.'
305
  );
38
  */
39
  public function __construct($database)
40
  {
41
+ if (\func_num_args() !== 1) {
42
  throw new \InvalidArgumentException(
43
  'The constructor takes exactly one argument.'
44
  );
88
  */
89
  public function get($ipAddress)
90
  {
91
+ if (\func_num_args() !== 1) {
92
  throw new \InvalidArgumentException(
93
  'Method takes exactly one argument.'
94
  );
95
  }
96
 
97
+ if (!\is_resource($this->fileHandle)) {
98
  throw new \BadMethodCallException(
99
  'Attempt to read from a closed MaxMind DB.'
100
  );
125
  // XXX - could simplify. Done as a byte array to ease porting
126
  $rawAddress = array_merge(unpack('C*', inet_pton($ipAddress)));
127
 
128
+ $bitCount = \count($rawAddress) * 8;
129
 
130
  // The first node of the tree is always node 0, at the beginning of the
131
  // value
132
  $node = $this->startNode($bitCount);
133
 
134
+ for ($i = 0; $i < $bitCount; ++$i) {
135
  if ($node >= $this->metadata->nodeCount) {
136
  break;
137
  }
175
  }
176
  $node = 0;
177
 
178
+ for ($i = 0; $i < 96 && $node < $this->metadata->nodeCount; ++$i) {
179
  $node = $this->readNode($node, 0);
180
  }
181
  $this->ipV4Start = $node;
203
  $middle = 0x0F & $middle;
204
  }
205
  $bytes = Util::read($this->fileHandle, $baseOffset + $index * 4, 3);
206
+ list(, $node) = unpack('N', \chr($middle) . $bytes);
207
 
208
  return $node;
209
  case 32:
249
  $metadataMaxLengthExcludingMarker
250
  = min(self::$METADATA_MAX_SIZE, $fileSize) - $markerLength;
251
 
252
+ for ($i = 0; $i <= $metadataMaxLengthExcludingMarker; ++$i) {
253
+ for ($j = 0; $j < $markerLength; ++$j) {
254
  fseek($handle, $fileSize - $i - $j - 1);
255
  $matchBit = fgetc($handle);
256
  if ($matchBit !== $marker[$markerLength - $j - 1]) {
274
  */
275
  public function metadata()
276
  {
277
+ if (\func_num_args()) {
278
  throw new \InvalidArgumentException(
279
  'Method takes no arguments.'
280
  );
282
 
283
  // Not technically required, but this makes it consistent with
284
  // C extension and it allows us to change our implementation later.
285
+ if (!\is_resource($this->fileHandle)) {
286
  throw new \BadMethodCallException(
287
  'Attempt to read from a closed MaxMind DB.'
288
  );
299
  */
300
  public function close()
301
  {
302
+ if (!\is_resource($this->fileHandle)) {
303
  throw new \BadMethodCallException(
304
  'Attempt to close a closed MaxMind DB.'
305
  );
vendor/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php CHANGED
@@ -2,32 +2,35 @@
2
 
3
  namespace MaxMind\Db\Reader;
4
 
 
 
 
 
5
  class Decoder
6
  {
7
  private $fileStream;
8
  private $pointerBase;
 
9
  // This is only used for unit testing
10
  private $pointerTestHack;
11
  private $switchByteOrder;
12
 
13
- private $types = [
14
- 0 => 'extended',
15
- 1 => 'pointer',
16
- 2 => 'utf8_string',
17
- 3 => 'double',
18
- 4 => 'bytes',
19
- 5 => 'uint16',
20
- 6 => 'uint32',
21
- 7 => 'map',
22
- 8 => 'int32',
23
- 9 => 'uint64',
24
- 10 => 'uint128',
25
- 11 => 'array',
26
- 12 => 'container',
27
- 13 => 'end_marker',
28
- 14 => 'boolean',
29
- 15 => 'float',
30
- ];
31
 
32
  public function __construct(
33
  $fileStream,
@@ -36,6 +39,8 @@ class Decoder
36
  ) {
37
  $this->fileStream = $fileStream;
38
  $this->pointerBase = $pointerBase;
 
 
39
  $this->pointerTestHack = $pointerTestHack;
40
 
41
  $this->switchByteOrder = $this->isPlatformLittleEndian();
@@ -47,14 +52,14 @@ class Decoder
47
  'C',
48
  Util::read($this->fileStream, $offset, 1)
49
  );
50
- $offset++;
51
 
52
- $type = $this->types[$ctrlByte >> 5];
53
 
54
  // Pointers are a special case, we don't read the next $size bytes, we
55
  // use the size to determine the length of the pointer and then follow
56
  // it.
57
- if ($type === 'pointer') {
58
  list($pointer, $offset) = $this->decodePointer($ctrlByte, $offset);
59
 
60
  // for unit testing
@@ -67,25 +72,24 @@ class Decoder
67
  return [$result, $offset];
68
  }
69
 
70
- if ($type === 'extended') {
71
  list(, $nextByte) = unpack(
72
  'C',
73
  Util::read($this->fileStream, $offset, 1)
74
  );
75
 
76
- $typeNum = $nextByte + 7;
77
 
78
- if ($typeNum < 8) {
79
  throw new InvalidDatabaseException(
80
  'Something went horribly wrong in the decoder. An extended type '
81
  . 'resolved to a type number < 8 ('
82
- . $this->types[$typeNum]
83
  . ')'
84
  );
85
  }
86
 
87
- $type = $this->types[$typeNum];
88
- $offset++;
89
  }
90
 
91
  list($size, $offset) = $this->sizeFromCtrlByte($ctrlByte, $offset);
@@ -96,37 +100,35 @@ class Decoder
96
  private function decodeByType($type, $offset, $size)
97
  {
98
  switch ($type) {
99
- case 'map':
100
  return $this->decodeMap($size, $offset);
101
- case 'array':
102
  return $this->decodeArray($size, $offset);
103
- case 'boolean':
104
  return [$this->decodeBoolean($size), $offset];
105
  }
106
 
107
  $newOffset = $offset + $size;
108
  $bytes = Util::read($this->fileStream, $offset, $size);
109
  switch ($type) {
110
- case 'utf8_string':
111
- return [$this->decodeString($bytes), $newOffset];
112
- case 'double':
 
113
  $this->verifySize(8, $size);
114
 
115
  return [$this->decodeDouble($bytes), $newOffset];
116
- case 'float':
117
  $this->verifySize(4, $size);
118
 
119
  return [$this->decodeFloat($bytes), $newOffset];
120
- case 'bytes':
121
- return [$bytes, $newOffset];
122
- case 'uint16':
123
- case 'uint32':
124
- return [$this->decodeUint($bytes), $newOffset];
125
- case 'int32':
126
- return [$this->decodeInt32($bytes), $newOffset];
127
- case 'uint64':
128
- case 'uint128':
129
- return [$this->decodeBigUint($bytes, $size), $newOffset];
130
  default:
131
  throw new InvalidDatabaseException(
132
  'Unknown or unexpected type: ' . $type
@@ -147,7 +149,7 @@ class Decoder
147
  {
148
  $array = [];
149
 
150
- for ($i = 0; $i < $size; $i++) {
151
  list($value, $offset) = $this->decode($offset);
152
  array_push($array, $value);
153
  }
@@ -162,7 +164,12 @@ class Decoder
162
 
163
  private function decodeDouble($bits)
164
  {
165
- // XXX - Assumes IEEE 754 double on platform
 
 
 
 
 
166
  list(, $double) = unpack('d', $this->maybeSwitchByteOrder($bits));
167
 
168
  return $double;
@@ -170,15 +177,35 @@ class Decoder
170
 
171
  private function decodeFloat($bits)
172
  {
173
- // XXX - Assumes IEEE 754 floats on platform
 
 
 
 
 
174
  list(, $float) = unpack('f', $this->maybeSwitchByteOrder($bits));
175
 
176
  return $float;
177
  }
178
 
179
- private function decodeInt32($bytes)
180
  {
181
- $bytes = $this->zeroPadLeft($bytes, 4);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  list(, $int) = unpack('l', $this->maybeSwitchByteOrder($bytes));
183
 
184
  return $int;
@@ -188,7 +215,7 @@ class Decoder
188
  {
189
  $map = [];
190
 
191
- for ($i = 0; $i < $size; $i++) {
192
  list($key, $offset) = $this->decode($offset);
193
  list($value, $offset) = $this->decode($offset);
194
  $map[$key] = $value;
@@ -197,13 +224,6 @@ class Decoder
197
  return [$map, $offset];
198
  }
199
 
200
- private $pointerValueOffset = [
201
- 1 => 0,
202
- 2 => 2048,
203
- 3 => 526336,
204
- 4 => 0,
205
- ];
206
-
207
  private function decodePointer($ctrlByte, $offset)
208
  {
209
  $pointerSize = (($ctrlByte >> 3) & 0x3) + 1;
@@ -211,50 +231,66 @@ class Decoder
211
  $buffer = Util::read($this->fileStream, $offset, $pointerSize);
212
  $offset = $offset + $pointerSize;
213
 
214
- $packed = $pointerSize === 4
215
- ? $buffer
216
- : (pack('C', $ctrlByte & 0x7)) . $buffer;
217
-
218
- $unpacked = $this->decodeUint($packed);
219
- $pointer = $unpacked + $this->pointerBase
220
- + $this->pointerValueOffset[$pointerSize];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
 
222
  return [$pointer, $offset];
223
  }
224
 
225
- private function decodeUint($bytes)
226
- {
227
- list(, $int) = unpack('N', $this->zeroPadLeft($bytes, 4));
228
-
229
- return $int;
230
- }
231
-
232
- private function decodeBigUint($bytes, $byteLength)
233
  {
234
- $maxUintBytes = log(PHP_INT_MAX, 2) / 8;
235
-
236
  if ($byteLength === 0) {
237
  return 0;
238
  }
239
 
240
- $numberOfLongs = ceil($byteLength / 4);
241
- $paddedLength = $numberOfLongs * 4;
242
- $paddedBytes = $this->zeroPadLeft($bytes, $paddedLength);
243
- $unpacked = array_merge(unpack("N$numberOfLongs", $paddedBytes));
244
-
245
  $integer = 0;
246
 
247
- // 2^32
248
- $twoTo32 = '4294967296';
249
 
250
- foreach ($unpacked as $part) {
251
  // We only use gmp or bcmath if the final value is too big
252
- if ($byteLength <= $maxUintBytes) {
253
- $integer = ($integer << 32) + $part;
254
- } elseif (extension_loaded('gmp')) {
255
- $integer = gmp_strval(gmp_add(gmp_mul($integer, $twoTo32), $part));
256
- } elseif (extension_loaded('bcmath')) {
257
- $integer = bcadd(bcmul($integer, $twoTo32), $part);
258
  } else {
259
  throw new \RuntimeException(
260
  'The gmp or bcmath extension must be installed to read this database.'
@@ -265,37 +301,31 @@ class Decoder
265
  return $integer;
266
  }
267
 
268
- private function decodeString($bytes)
269
- {
270
- // XXX - NOOP. As far as I know, the end user has to explicitly set the
271
- // encoding in PHP. Strings are just bytes.
272
- return $bytes;
273
- }
274
-
275
  private function sizeFromCtrlByte($ctrlByte, $offset)
276
  {
277
  $size = $ctrlByte & 0x1f;
278
- $bytesToRead = $size < 29 ? 0 : $size - 28;
 
 
 
 
 
279
  $bytes = Util::read($this->fileStream, $offset, $bytesToRead);
280
- $decoded = $this->decodeUint($bytes);
281
 
282
  if ($size === 29) {
283
- $size = 29 + $decoded;
284
  } elseif ($size === 30) {
285
- $size = 285 + $decoded;
 
286
  } elseif ($size > 30) {
287
- $size = ($decoded & (0x0FFFFFFF >> (32 - (8 * $bytesToRead))))
 
288
  + 65821;
289
  }
290
 
291
  return [$size, $offset + $bytesToRead];
292
  }
293
 
294
- private function zeroPadLeft($content, $desiredLength)
295
- {
296
- return str_pad($content, $desiredLength, "\x00", STR_PAD_LEFT);
297
- }
298
-
299
  private function maybeSwitchByteOrder($bytes)
300
  {
301
  return $this->switchByteOrder ? strrev($bytes) : $bytes;
2
 
3
  namespace MaxMind\Db\Reader;
4
 
5
+ // @codingStandardsIgnoreLine
6
+ // We subtract 1 from the log to protect against precision loss.
7
+ \define(__NAMESPACE__ . '\_MM_MAX_INT_BYTES', (log(PHP_INT_MAX, 2) - 1) / 8);
8
+
9
  class Decoder
10
  {
11
  private $fileStream;
12
  private $pointerBase;
13
+ private $pointerBaseByteSize;
14
  // This is only used for unit testing
15
  private $pointerTestHack;
16
  private $switchByteOrder;
17
 
18
+ const _EXTENDED = 0;
19
+ const _POINTER = 1;
20
+ const _UTF8_STRING = 2;
21
+ const _DOUBLE = 3;
22
+ const _BYTES = 4;
23
+ const _UINT16 = 5;
24
+ const _UINT32 = 6;
25
+ const _MAP = 7;
26
+ const _INT32 = 8;
27
+ const _UINT64 = 9;
28
+ const _UINT128 = 10;
29
+ const _ARRAY = 11;
30
+ const _CONTAINER = 12;
31
+ const _END_MARKER = 13;
32
+ const _BOOLEAN = 14;
33
+ const _FLOAT = 15;
 
 
34
 
35
  public function __construct(
36
  $fileStream,
39
  ) {
40
  $this->fileStream = $fileStream;
41
  $this->pointerBase = $pointerBase;
42
+
43
+ $this->pointerBaseByteSize = $pointerBase > 0 ? log($pointerBase, 2) / 8 : 0;
44
  $this->pointerTestHack = $pointerTestHack;
45
 
46
  $this->switchByteOrder = $this->isPlatformLittleEndian();
52
  'C',
53
  Util::read($this->fileStream, $offset, 1)
54
  );
55
+ ++$offset;
56
 
57
+ $type = $ctrlByte >> 5;
58
 
59
  // Pointers are a special case, we don't read the next $size bytes, we
60
  // use the size to determine the length of the pointer and then follow
61
  // it.
62
+ if ($type === self::_POINTER) {
63
  list($pointer, $offset) = $this->decodePointer($ctrlByte, $offset);
64
 
65
  // for unit testing
72
  return [$result, $offset];
73
  }
74
 
75
+ if ($type === self::_EXTENDED) {
76
  list(, $nextByte) = unpack(
77
  'C',
78
  Util::read($this->fileStream, $offset, 1)
79
  );
80
 
81
+ $type = $nextByte + 7;
82
 
83
+ if ($type < 8) {
84
  throw new InvalidDatabaseException(
85
  'Something went horribly wrong in the decoder. An extended type '
86
  . 'resolved to a type number < 8 ('
87
+ . $type
88
  . ')'
89
  );
90
  }
91
 
92
+ ++$offset;
 
93
  }
94
 
95
  list($size, $offset) = $this->sizeFromCtrlByte($ctrlByte, $offset);
100
  private function decodeByType($type, $offset, $size)
101
  {
102
  switch ($type) {
103
+ case self::_MAP:
104
  return $this->decodeMap($size, $offset);
105
+ case self::_ARRAY:
106
  return $this->decodeArray($size, $offset);
107
+ case self::_BOOLEAN:
108
  return [$this->decodeBoolean($size), $offset];
109
  }
110
 
111
  $newOffset = $offset + $size;
112
  $bytes = Util::read($this->fileStream, $offset, $size);
113
  switch ($type) {
114
+ case self::_BYTES:
115
+ case self::_UTF8_STRING:
116
+ return [$bytes, $newOffset];
117
+ case self::_DOUBLE:
118
  $this->verifySize(8, $size);
119
 
120
  return [$this->decodeDouble($bytes), $newOffset];
121
+ case self::_FLOAT:
122
  $this->verifySize(4, $size);
123
 
124
  return [$this->decodeFloat($bytes), $newOffset];
125
+ case self::_INT32:
126
+ return [$this->decodeInt32($bytes, $size), $newOffset];
127
+ case self::_UINT16:
128
+ case self::_UINT32:
129
+ case self::_UINT64:
130
+ case self::_UINT128:
131
+ return [$this->decodeUint($bytes, $size), $newOffset];
 
 
 
132
  default:
133
  throw new InvalidDatabaseException(
134
  'Unknown or unexpected type: ' . $type
149
  {
150
  $array = [];
151
 
152
+ for ($i = 0; $i < $size; ++$i) {
153
  list($value, $offset) = $this->decode($offset);
154
  array_push($array, $value);
155
  }
164
 
165
  private function decodeDouble($bits)
166
  {
167
+ // This assumes IEEE 754 doubles, but most (all?) modern platforms
168
+ // use them.
169
+ //
170
+ // We are not using the "E" format as that was only added in
171
+ // 7.0.15 and 7.1.1. As such, we must switch byte order on
172
+ // little endian machines.
173
  list(, $double) = unpack('d', $this->maybeSwitchByteOrder($bits));
174
 
175
  return $double;
177
 
178
  private function decodeFloat($bits)
179
  {
180
+ // This assumes IEEE 754 floats, but most (all?) modern platforms
181
+ // use them.
182
+ //
183
+ // We are not using the "G" format as that was only added in
184
+ // 7.0.15 and 7.1.1. As such, we must switch byte order on
185
+ // little endian machines.
186
  list(, $float) = unpack('f', $this->maybeSwitchByteOrder($bits));
187
 
188
  return $float;
189
  }
190
 
191
+ private function decodeInt32($bytes, $size)
192
  {
193
+ switch ($size) {
194
+ case 0:
195
+ return 0;
196
+ case 1:
197
+ case 2:
198
+ case 3:
199
+ $bytes = str_pad($bytes, 4, "\x00", STR_PAD_LEFT);
200
+ break;
201
+ case 4:
202
+ break;
203
+ default:
204
+ throw new InvalidDatabaseException(
205
+ "The MaxMind DB file's data section contains bad data (unknown data type or corrupt data)"
206
+ );
207
+ }
208
+
209
  list(, $int) = unpack('l', $this->maybeSwitchByteOrder($bytes));
210
 
211
  return $int;
215
  {
216
  $map = [];
217
 
218
+ for ($i = 0; $i < $size; ++$i) {
219
  list($key, $offset) = $this->decode($offset);
220
  list($value, $offset) = $this->decode($offset);
221
  $map[$key] = $value;
224
  return [$map, $offset];
225
  }
226
 
 
 
 
 
 
 
 
227
  private function decodePointer($ctrlByte, $offset)
228
  {
229
  $pointerSize = (($ctrlByte >> 3) & 0x3) + 1;
231
  $buffer = Util::read($this->fileStream, $offset, $pointerSize);
232
  $offset = $offset + $pointerSize;
233
 
234
+ switch ($pointerSize) {
235
+ case 1:
236
+ $packed = (pack('C', $ctrlByte & 0x7)) . $buffer;
237
+ list(, $pointer) = unpack('n', $packed);
238
+ $pointer += $this->pointerBase;
239
+ break;
240
+ case 2:
241
+ $packed = "\x00" . (pack('C', $ctrlByte & 0x7)) . $buffer;
242
+ list(, $pointer) = unpack('N', $packed);
243
+ $pointer += $this->pointerBase + 2048;
244
+ break;
245
+ case 3:
246
+ $packed = (pack('C', $ctrlByte & 0x7)) . $buffer;
247
+
248
+ // It is safe to use 'N' here, even on 32 bit machines as the
249
+ // first bit is 0.
250
+ list(, $pointer) = unpack('N', $packed);
251
+ $pointer += $this->pointerBase + 526336;
252
+ break;
253
+ case 4:
254
+ // We cannot use unpack here as we might overflow on 32 bit
255
+ // machines
256
+ $pointerOffset = $this->decodeUint($buffer, $pointerSize);
257
+
258
+ $byteLength = $pointerSize + $this->pointerBaseByteSize;
259
+
260
+ if ($byteLength <= _MM_MAX_INT_BYTES) {
261
+ $pointer = $pointerOffset + $this->pointerBase;
262
+ } elseif (\extension_loaded('gmp')) {
263
+ $pointer = gmp_strval(gmp_add($pointerOffset, $this->pointerBase));
264
+ } elseif (\extension_loaded('bcmath')) {
265
+ $pointer = bcadd($pointerOffset, $this->pointerBase);
266
+ } else {
267
+ throw new \RuntimeException(
268
+ 'The gmp or bcmath extension must be installed to read this database.'
269
+ );
270
+ }
271
+ }
272
 
273
  return [$pointer, $offset];
274
  }
275
 
276
+ private function decodeUint($bytes, $byteLength)
 
 
 
 
 
 
 
277
  {
 
 
278
  if ($byteLength === 0) {
279
  return 0;
280
  }
281
 
 
 
 
 
 
282
  $integer = 0;
283
 
284
+ for ($i = 0; $i < $byteLength; ++$i) {
285
+ $part = \ord($bytes[$i]);
286
 
 
287
  // We only use gmp or bcmath if the final value is too big
288
+ if ($byteLength <= _MM_MAX_INT_BYTES) {
289
+ $integer = ($integer << 8) + $part;
290
+ } elseif (\extension_loaded('gmp')) {
291
+ $integer = gmp_strval(gmp_add(gmp_mul($integer, 256), $part));
292
+ } elseif (\extension_loaded('bcmath')) {
293
+ $integer = bcadd(bcmul($integer, 256), $part);
294
  } else {
295
  throw new \RuntimeException(
296
  'The gmp or bcmath extension must be installed to read this database.'
301
  return $integer;
302
  }
303
 
 
 
 
 
 
 
 
304
  private function sizeFromCtrlByte($ctrlByte, $offset)
305
  {
306
  $size = $ctrlByte & 0x1f;
307
+
308
+ if ($size < 29) {
309
+ return [$size, $offset];
310
+ }
311
+
312
+ $bytesToRead = $size - 28;
313
  $bytes = Util::read($this->fileStream, $offset, $bytesToRead);
 
314
 
315
  if ($size === 29) {
316
+ $size = 29 + \ord($bytes);
317
  } elseif ($size === 30) {
318
+ list(, $adjust) = unpack('n', $bytes);
319
+ $size = 285 + $adjust;
320
  } elseif ($size > 30) {
321
+ list(, $adjust) = unpack('N', "\x00" . $bytes);
322
+ $size = ($adjust & (0x0FFFFFFF >> (32 - (8 * $bytesToRead))))
323
  + 65821;
324
  }
325
 
326
  return [$size, $offset + $bytesToRead];
327
  }
328
 
 
 
 
 
 
329
  private function maybeSwitchByteOrder($bytes)
330
  {
331
  return $this->switchByteOrder ? strrev($bytes) : $bytes;
vendor/symfony/http-foundation/IpUtils.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
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 Symfony\Component\HttpFoundation;
13
+
14
+ /**
15
+ * Http utility functions.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class IpUtils
20
+ {
21
+ private static $checkedIps = [];
22
+
23
+ /**
24
+ * This class should not be instantiated.
25
+ */
26
+ private function __construct()
27
+ {
28
+ }
29
+
30
+ /**
31
+ * Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets.
32
+ *
33
+ * @param string $requestIp IP to check
34
+ * @param string|array $ips List of IPs or subnets (can be a string if only a single one)
35
+ *
36
+ * @return bool Whether the IP is valid
37
+ */
38
+ public static function checkIp($requestIp, $ips)
39
+ {
40
+ if (!\is_array($ips)) {
41
+ $ips = [$ips];
42
+ }
43
+
44
+ $method = substr_count($requestIp, ':') > 1 ? 'checkIp6' : 'checkIp4';
45
+
46
+ foreach ($ips as $ip) {
47
+ if (self::$method($requestIp, $ip)) {
48
+ return true;
49
+ }
50
+ }
51
+
52
+ return false;
53
+ }
54
+
55
+ /**
56
+ * Compares two IPv4 addresses.
57
+ * In case a subnet is given, it checks if it contains the request IP.
58
+ *
59
+ * @param string $requestIp IPv4 address to check
60
+ * @param string $ip IPv4 address or subnet in CIDR notation
61
+ *
62
+ * @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet
63
+ */
64
+ public static function checkIp4($requestIp, $ip)
65
+ {
66
+ $cacheKey = $requestIp.'-'.$ip;
67
+ if (isset(self::$checkedIps[$cacheKey])) {
68
+ return self::$checkedIps[$cacheKey];
69
+ }
70
+
71
+ if (!filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
72
+ return self::$checkedIps[$cacheKey] = false;
73
+ }
74
+
75
+ if (false !== strpos($ip, '/')) {
76
+ list($address, $netmask) = explode('/', $ip, 2);
77
+
78
+ if ('0' === $netmask) {
79
+ return self::$checkedIps[$cacheKey] = filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
80
+ }
81
+
82
+ if ($netmask < 0 || $netmask > 32) {
83
+ return self::$checkedIps[$cacheKey] = false;
84
+ }
85
+ } else {
86
+ $address = $ip;
87
+ $netmask = 32;
88
+ }
89
+
90
+ if (false === ip2long($address)) {
91
+ return self::$checkedIps[$cacheKey] = false;
92
+ }
93
+
94
+ return self::$checkedIps[$cacheKey] = 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
95
+ }
96
+
97
+ /**
98
+ * Compares two IPv6 addresses.
99
+ * In case a subnet is given, it checks if it contains the request IP.
100
+ *
101
+ * @author David Soria Parra <dsp at php dot net>
102
+ *
103
+ * @see https://github.com/dsp/v6tools
104
+ *
105
+ * @param string $requestIp IPv6 address to check
106
+ * @param string $ip IPv6 address or subnet in CIDR notation
107
+ *
108
+ * @return bool Whether the IP is valid
109
+ *
110
+ * @throws \RuntimeException When IPV6 support is not enabled
111
+ */
112
+ public static function checkIp6($requestIp, $ip)
113
+ {
114
+ $cacheKey = $requestIp.'-'.$ip;
115
+ if (isset(self::$checkedIps[$cacheKey])) {
116
+ return self::$checkedIps[$cacheKey];
117
+ }
118
+
119
+ if (!((\extension_loaded('sockets') && \defined('AF_INET6')) || @inet_pton('::1'))) {
120
+ throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
121
+ }
122
+
123
+ if (false !== strpos($ip, '/')) {
124
+ list($address, $netmask) = explode('/', $ip, 2);
125
+
126
+ if ('0' === $netmask) {
127
+ return (bool) unpack('n*', @inet_pton($address));
128
+ }
129
+
130
+ if ($netmask < 1 || $netmask > 128) {
131
+ return self::$checkedIps[$cacheKey] = false;
132
+ }
133
+ } else {
134
+ $address = $ip;
135
+ $netmask = 128;
136
+ }
137
+
138
+ $bytesAddr = unpack('n*', @inet_pton($address));
139
+ $bytesTest = unpack('n*', @inet_pton($requestIp));
140
+
141
+ if (!$bytesAddr || !$bytesTest) {
142
+ return self::$checkedIps[$cacheKey] = false;
143
+ }
144
+
145
+ for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
146
+ $left = $netmask - 16 * ($i - 1);
147
+ $left = ($left <= 16) ? $left : 16;
148
+ $mask = ~(0xffff >> $left) & 0xffff;
149
+ if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
150
+ return self::$checkedIps[$cacheKey] = false;
151
+ }
152
+ }
153
+
154
+ return self::$checkedIps[$cacheKey] = true;
155
+ }
156
+ }
vendor/symfony/http-foundation/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2004-2019 Fabien Potencier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
views/options.php CHANGED
@@ -76,7 +76,7 @@ $options = $currentSource->getParameterHTML();
76
  </span>
77
  </p>
78
  <p>
79
- <label><?php _e('IPs of trusted proxies:', 'geoip-detect'); ?><input type="text" name="options[trusted_proxy_ips]" <?php echo esc_attr($wp_options['trusted_proxy_ips']); ?>" placeholder="<?php _e('IPs comma-seperated', 'geoip-detect'); ?>" />
80
  <span class="detail-box">
81
  <?php _e('If specified, only IPs in this list will be treated as proxy.', 'geoip-detect'); ?><br>
82
  <?php _e('Make sure to add both IPv4 and IPv6 adresses of the proxy!', 'geoip-detect'); ?>
76
  </span>
77
  </p>
78
  <p>
79
+ <label><?php _e('IPs of trusted proxies:', 'geoip-detect'); ?><input type="text" name="options[trusted_proxy_ips]" <?php echo esc_attr($wp_options['trusted_proxy_ips']); ?>" placeholder="1.1.1.1, 1234::1, 2.2.2.2/24" />
80
  <span class="detail-box">
81
  <?php _e('If specified, only IPs in this list will be treated as proxy.', 'geoip-detect'); ?><br>
82
  <?php _e('Make sure to add both IPv4 and IPv6 adresses of the proxy!', 'geoip-detect'); ?>