Skip to content

Commit 37b5c21

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into 4.4
2 parents 2c1ce59 + 1e7204b commit 37b5c21

File tree

1 file changed

+57
-54
lines changed

1 file changed

+57
-54
lines changed

system/HTTP/RequestTrait.php

Lines changed: 57 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ public function getIPAddress(): string
6666
// @phpstan-ignore-next-line
6767
$proxyIPs = $this->proxyIPs ?? config(App::class)->proxyIPs;
6868
// @phpstan-ignore-next-line
69+
70+
// Workaround for old Config\App file. App::$proxyIPs may be empty string.
71+
if ($proxyIPs === '') {
72+
$proxyIPs = [];
73+
}
6974
if (! empty($proxyIPs) && (! is_array($proxyIPs) || is_int(array_key_first($proxyIPs)))) {
7075
throw new ConfigException(
7176
'You must set an array with Proxy IP address key and HTTP header name value in Config\App::$proxyIPs.'
@@ -79,76 +84,74 @@ public function getIPAddress(): string
7984
return $this->ipAddress = '0.0.0.0';
8085
}
8186

82-
if ($proxyIPs) {
83-
// @TODO Extract all this IP address logic to another class.
84-
foreach ($proxyIPs as $proxyIP => $header) {
85-
// Check if we have an IP address or a subnet
86-
if (strpos($proxyIP, '/') === false) {
87-
// An IP address (and not a subnet) is specified.
88-
// We can compare right away.
89-
if ($proxyIP === $this->ipAddress) {
90-
$spoof = $this->getClientIP($header);
91-
92-
if ($spoof !== null) {
93-
$this->ipAddress = $spoof;
94-
break;
95-
}
96-
}
87+
// @TODO Extract all this IP address logic to another class.
88+
foreach ($proxyIPs as $proxyIP => $header) {
89+
// Check if we have an IP address or a subnet
90+
if (strpos($proxyIP, '/') === false) {
91+
// An IP address (and not a subnet) is specified.
92+
// We can compare right away.
93+
if ($proxyIP === $this->ipAddress) {
94+
$spoof = $this->getClientIP($header);
9795

98-
continue;
96+
if ($spoof !== null) {
97+
$this->ipAddress = $spoof;
98+
break;
99+
}
99100
}
100101

101-
// We have a subnet ... now the heavy lifting begins
102-
if (! isset($separator)) {
103-
$separator = $ipValidator($this->ipAddress, 'ipv6') ? ':' : '.';
104-
}
102+
continue;
103+
}
105104

106-
// If the proxy entry doesn't match the IP protocol - skip it
107-
if (strpos($proxyIP, $separator) === false) {
108-
continue;
109-
}
105+
// We have a subnet ... now the heavy lifting begins
106+
if (! isset($separator)) {
107+
$separator = $ipValidator($this->ipAddress, 'ipv6') ? ':' : '.';
108+
}
110109

111-
// Convert the REMOTE_ADDR IP address to binary, if needed
112-
if (! isset($ip, $sprintf)) {
113-
if ($separator === ':') {
114-
// Make sure we're having the "full" IPv6 format
115-
$ip = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($this->ipAddress, ':')), $this->ipAddress));
110+
// If the proxy entry doesn't match the IP protocol - skip it
111+
if (strpos($proxyIP, $separator) === false) {
112+
continue;
113+
}
116114

117-
for ($j = 0; $j < 8; $j++) {
118-
$ip[$j] = intval($ip[$j], 16);
119-
}
115+
// Convert the REMOTE_ADDR IP address to binary, if needed
116+
if (! isset($ip, $sprintf)) {
117+
if ($separator === ':') {
118+
// Make sure we're having the "full" IPv6 format
119+
$ip = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($this->ipAddress, ':')), $this->ipAddress));
120120

121-
$sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b';
122-
} else {
123-
$ip = explode('.', $this->ipAddress);
124-
$sprintf = '%08b%08b%08b%08b';
121+
for ($j = 0; $j < 8; $j++) {
122+
$ip[$j] = intval($ip[$j], 16);
125123
}
126124

127-
$ip = vsprintf($sprintf, $ip);
125+
$sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b';
126+
} else {
127+
$ip = explode('.', $this->ipAddress);
128+
$sprintf = '%08b%08b%08b%08b';
128129
}
129130

130-
// Split the netmask length off the network address
131-
sscanf($proxyIP, '%[^/]/%d', $netaddr, $masklen);
131+
$ip = vsprintf($sprintf, $ip);
132+
}
132133

133-
// Again, an IPv6 address is most likely in a compressed form
134-
if ($separator === ':') {
135-
$netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr));
134+
// Split the netmask length off the network address
135+
sscanf($proxyIP, '%[^/]/%d', $netaddr, $masklen);
136136

137-
for ($i = 0; $i < 8; $i++) {
138-
$netaddr[$i] = intval($netaddr[$i], 16);
139-
}
140-
} else {
141-
$netaddr = explode('.', $netaddr);
137+
// Again, an IPv6 address is most likely in a compressed form
138+
if ($separator === ':') {
139+
$netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr));
140+
141+
for ($i = 0; $i < 8; $i++) {
142+
$netaddr[$i] = intval($netaddr[$i], 16);
142143
}
144+
} else {
145+
$netaddr = explode('.', $netaddr);
146+
}
143147

144-
// Convert to binary and finally compare
145-
if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0) {
146-
$spoof = $this->getClientIP($header);
148+
// Convert to binary and finally compare
149+
if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0) {
150+
$spoof = $this->getClientIP($header);
147151

148-
if ($spoof !== null) {
149-
$this->ipAddress = $spoof;
150-
break;
151-
}
152+
if ($spoof !== null) {
153+
$this->ipAddress = $spoof;
154+
break;
152155
}
153156
}
154157
}

0 commit comments

Comments
 (0)