PluginProbe
The WP Remote WordPress Plugin / 6.76
The WP Remote WordPress Plugin v6.76
6.76 6.72 6.69 6.65 6.62 6.48 6.47 4.87 4.97 5.05 5.09 5.16 5.22 5.24 5.25 5.38 5.41 5.42 5.45 5.47 5.53 5.56 5.65 5.68 5.72 All 54 releases
← All changes | protect/fw/rule/functions/array.php +260 -14 5.426.76 View file →
@@ -1,9 +1,10 @@
1 1 <?php
2 +// phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped
2 3 if (!defined('ABSPATH') && !defined('MCDATAPATH')) exit;
3 4
4 -if (!trait_exists('WPRProtectFWRuleArrayFunc_V542')) :
5 -trait WPRProtectFWRuleArrayFunc_V542 {
5 +if (!trait_exists('WPRProtectFWRuleArrayFunc_V676')) :
6 +trait WPRProtectFWRuleArrayFunc_V676 {
6 7 private function _rf_inArray() {
7 8 $args = $this->processRuleFunctionParams(
8 9 'inArray',
9 10 func_num_args(),
@@ -14,15 +15,15 @@
14 15 $array = $args[1];
15 16 $strict = isset($args[2]) ? $args[2] : false;
16 17
17 18 if (!is_array($array)) {
18 - throw new WPRProtectRuleError_V542(
19 + throw new WPRProtectRuleError_V676(
19 20 $this->addExState("inArray: 2nd param is not an array")
20 21 );
21 22 }
22 23
23 24 if (!is_bool($strict)) {
24 - throw new WPRProtectRuleError_V542(
25 + throw new WPRProtectRuleError_V676(
25 26 $this->addExState("inArray: 3rd param is not a boolean")
26 27 );
27 28 }
28 29
@@ -51,9 +52,9 @@
51 52 }
52 53 }
53 54 }
54 55 } else {
55 - throw new WPRProtectRuleError_V542(
56 + throw new WPRProtectRuleError_V676(
56 57 $this->addExState("recInArray: Expects an array")
57 58 );
58 59 }
59 60
@@ -70,13 +71,13 @@
70 71 $key = $args[0];
71 72 $array = $args[1];
72 73
73 74 if (!is_array($array)) {
74 - throw new WPRProtectRuleError_V542(
75 + throw new WPRProtectRuleError_V676(
75 76 $this->addExState("arrayKeyExists: Array must be of type array")
76 77 );
77 78 } elseif (!is_string($key) && !is_int($key)) {
78 - throw new WPRProtectRuleError_V542(
79 + throw new WPRProtectRuleError_V676(
79 80 $this->addExState("arrayKeyExists: Key must be of type string or int")
80 81 );
81 82 }
82 83
@@ -104,10 +105,26 @@
104 105 1,
105 106 ['array']
106 107 );
107 108 $array = $args[0];
109 + $recursive = isset($args[1]) ? $args[1] : false;
108 110
109 - return array_keys($array);
111 + if (!is_bool($recursive)) {
112 + throw new WPRProtectRuleError_V676(
113 + $this->addExState("getArrayKeys: 2nd param must be a boolean")
114 + );
115 + }
116 +
117 + if (!$recursive) {
118 + $this->enforceArrayTraversalLimit('getArrayKeys', count($array));
119 + return array_keys($array);
120 + }
121 +
122 + $keys = array();
123 + $traversed_keys = 0;
124 + $this->getArrayKeysRecursive($array, $keys, $traversed_keys);
125 +
126 + return $keys;
110 127 }
111 128
112 129 private function _rf_hasAnyArrayKey() {
113 130 $args = $this->processRuleFunctionParams(
@@ -118,16 +135,39 @@
118 135 ['array', 'array']
119 136 );
120 137 $array = $args[0];
121 138 $keys = $args[1];
139 + $recursive = isset($args[2]) ? $args[2] : false;
122 140
141 + if (!is_bool($recursive)) {
142 + throw new WPRProtectRuleError_V676(
143 + $this->addExState("hasAnyArrayKey: 3rd param must be a boolean")
144 + );
145 + }
146 +
147 + $key_lookup = array();
123 148 foreach ($keys as $key) {
124 149 if (!is_int($key) && !is_string($key)) {
125 - throw new WPRProtectRuleError_V542(
150 + throw new WPRProtectRuleError_V676(
126 151 $this->addExState("hasAnyArrayKey: Key must be of type string or int")
127 152 );
128 153 }
129 154
155 + $key_lookup[$key] = true;
156 + }
157 +
158 + if (empty($key_lookup)) {
159 + return false;
160 + }
161 +
162 + $traversed_keys = 0;
163 + if ($recursive) {
164 + return $this->hasAnyArrayKeyRecursive($array, $key_lookup, $traversed_keys);
165 + }
166 +
167 + foreach ($key_lookup as $key => $unused) {
168 + $traversed_keys += 1;
169 + $this->enforceArrayTraversalLimit('hasAnyArrayKey', $traversed_keys);
130 170 if (array_key_exists($key, $array)) {
131 171 return true;
132 172 }
133 173 }
@@ -134,8 +174,140 @@
134 174
135 175 return false;
136 176 }
137 177
178 + private function _rf_keyMatches() {
179 + $args = $this->processRuleFunctionParams(
180 + 'keyMatches',
181 + func_num_args(),
182 + func_get_args(),
183 + 2,
184 + ['string', 'array']
185 + );
186 + $pattern = $args[0];
187 + $array = $args[1];
188 + $recursive = isset($args[2]) ? $args[2] : false;
189 +
190 + if (!is_bool($recursive)) {
191 + throw new WPRProtectRuleError_V676(
192 + $this->addExState("keyMatches: 3rd param must be a boolean")
193 + );
194 + }
195 +
196 + $this->validateKeyMatchPattern($pattern);
197 +
198 + $traversed_keys = 0;
199 + if ($recursive) {
200 + return $this->keyMatchesRecursive($array, $pattern, $traversed_keys);
201 + }
202 +
203 + foreach ($array as $key => $unused) {
204 + $traversed_keys += 1;
205 + $this->enforceArrayTraversalLimit('keyMatches', $traversed_keys);
206 + if ($this->keyMatchesPattern($pattern, $key)) {
207 + return true;
208 + }
209 + }
210 +
211 + return false;
212 + }
213 +
214 + private function validateKeyMatchPattern($pattern) {
215 + set_error_handler(function() {
216 + return true;
217 + });
218 +
219 + try {
220 + $resp = WPRHelper::safePregMatch($pattern, '');
221 + } finally {
222 + restore_error_handler();
223 + }
224 +
225 + if ($resp === false) {
226 + throw new WPRProtectRuleError_V676(
227 + $this->addExState("keyMatches: Invalid regular expression")
228 + );
229 + }
230 + }
231 +
232 + private function keyMatchesPattern($pattern, $key) {
233 + $resp = WPRHelper::safePregMatch($pattern, (string) $key);
234 + if ($resp === false) {
235 + throw new WPRProtectRuleError_V676(
236 + $this->addExState("keyMatches: Regex match failed")
237 + );
238 + }
239 +
240 + return $resp > 0;
241 + }
242 +
243 + private function keyMatchesRecursive($array, $pattern, &$traversed_keys, $depth = 1) {
244 + if ($depth > WPRProtectFWRuleEngine_V676::MAX_DEPTH_TO_ALLOWED_TYPE_FUNC) {
245 + return false;
246 + }
247 +
248 + foreach ($array as $key => $value) {
249 + $traversed_keys += 1;
250 + $this->enforceArrayTraversalLimit('keyMatches', $traversed_keys);
251 + if ($this->keyMatchesPattern($pattern, $key)) {
252 + return true;
253 + }
254 +
255 + if (is_array($value) && $this->keyMatchesRecursive($value, $pattern, $traversed_keys, $depth + 1)) {
256 + return true;
257 + }
258 + }
259 +
260 + return false;
261 + }
262 +
263 + private function getArrayKeysRecursive($array, &$keys, &$traversed_keys, $depth = 1) {
264 + if ($depth > WPRProtectFWRuleEngine_V676::MAX_DEPTH_TO_ALLOWED_TYPE_FUNC) {
265 + return;
266 + }
267 +
268 + foreach ($array as $key => $value) {
269 + $traversed_keys += 1;
270 + $this->enforceArrayTraversalLimit('getArrayKeys', $traversed_keys);
271 + $keys[] = $key;
272 + if (is_array($value)) {
273 + $this->getArrayKeysRecursive($value, $keys, $traversed_keys, $depth + 1);
274 + }
275 + }
276 + }
277 +
278 + private function hasAnyArrayKeyRecursive($array, $key_lookup, &$traversed_keys, $depth = 1) {
279 + if ($depth > WPRProtectFWRuleEngine_V676::MAX_DEPTH_TO_ALLOWED_TYPE_FUNC) {
280 + return false;
281 + }
282 +
283 + foreach ($array as $key => $value) {
284 + $traversed_keys += 1;
285 + $this->enforceArrayTraversalLimit('hasAnyArrayKey', $traversed_keys);
286 + if (isset($key_lookup[$key])) {
287 + return true;
288 + }
289 +
290 + if (is_array($value) && $this->hasAnyArrayKeyRecursive($value, $key_lookup, $traversed_keys, $depth + 1)) {
291 + return true;
292 + }
293 + }
294 +
295 + return false;
296 + }
297 +
298 + private function enforceArrayTraversalLimit($func_name, $traversed_keys) {
299 + if ($traversed_keys > WPRProtectFWRuleEngine_V676::MAX_ARRAY_KEYS_TO_TRAVERSE) {
300 + throw new WPRProtectRuleError_V676(
301 + $this->addExState(
302 + "TraversalLimitError: " . $func_name . " exceeded " .
303 + WPRProtectFWRuleEngine_V676::MAX_ARRAY_KEYS_TO_TRAVERSE .
304 + " array keys"
305 + )
306 + );
307 + }
308 + }
309 +
138 310 private function _rf_digArray() {
139 311 $args = $this->processRuleFunctionParams(
140 312 'digArray',
141 313 func_num_args(),
@@ -147,9 +319,9 @@
147 319 $keys = $args[1];
148 320
149 321 foreach ($keys as $key) {
150 322 if (!is_int($key) && !is_string($key)) {
151 - throw new WPRProtectRuleError_V542(
323 + throw new WPRProtectRuleError_V676(
152 324 $this->addExState("digArray: Keys must be a valid array of string, or integer type")
153 325 );
154 326 }
155 327 }
@@ -156,8 +328,82 @@
156 328
157 329 return WPRHelper::digArray($array, $keys);
158 330 }
159 331
332 + private function _rf_digArrayValues() {
333 + $args = $this->processRuleFunctionParams(
334 + 'digArrayValues',
335 + func_num_args(),
336 + func_get_args(),
337 + 2,
338 + ['mixed', 'array']
339 + );
340 + $array = $args[0];
341 + $keys = $args[1];
342 +
343 + if (empty($keys)) {
344 + throw new WPRProtectRuleError_V676(
345 + $this->addExState("digArrayValues: Keys must not be empty")
346 + );
347 + }
348 +
349 + if (count($keys) > WPRProtectFWRuleEngine_V676::MAX_DEPTH_TO_ALLOWED_TYPE_FUNC) {
350 + throw new WPRProtectRuleError_V676(
351 + $this->addExState(
352 + "digArrayValues: Keys exceeded " .
353 + WPRProtectFWRuleEngine_V676::MAX_DEPTH_TO_ALLOWED_TYPE_FUNC .
354 + " levels of traversal"
355 + )
356 + );
357 + }
358 +
359 + foreach ($keys as $key) {
360 + if (!is_int($key) && !is_string($key)) {
361 + throw new WPRProtectRuleError_V676(
362 + $this->addExState("digArrayValues: Keys must be a valid array of string, or integer type")
363 + );
364 + }
365 + }
366 +
367 + $nodes = array($array);
368 + $traversed_keys = 0;
369 +
370 + foreach ($keys as $key) {
371 + $next_nodes = array();
372 +
373 + foreach ($nodes as $node) {
374 + if (!is_array($node)) {
375 + continue;
376 + }
377 +
378 + if ($key === WPRProtectFWRuleEngine_V676::WILDCARD_KEY) {
379 + foreach ($node as $value) {
380 + $traversed_keys += 1;
381 + $this->enforceArrayTraversalLimit('digArrayValues', $traversed_keys);
382 + $next_nodes[] = $value;
383 + }
384 +
385 + continue;
386 + }
387 +
388 + $traversed_keys += 1;
389 + $this->enforceArrayTraversalLimit('digArrayValues', $traversed_keys);
390 +
391 + if (array_key_exists($key, $node)) {
392 + $next_nodes[] = $node[$key];
393 + }
394 + }
395 +
396 + if (empty($next_nodes)) {
397 + return array();
398 + }
399 +
400 + $nodes = $next_nodes;
401 + }
402 +
403 + return $nodes;
404 + }
405 +
160 406 private function _rf_filterArray() {
161 407 $args = $this->processRuleFunctionParams(
162 408 'filterArray',
163 409 func_num_args(),
@@ -169,9 +415,9 @@
169 415 $keys = $args[1];
170 416
171 417 foreach ($keys as $key) {
172 418 if (!is_int($key) && !is_string($key)) {
173 - throw new WPRProtectRuleError_V542(
419 + throw new WPRProtectRuleError_V676(
174 420 $this->addExState("filterArray: Keys must be a valid array of string, or integer type")
175 421 );
176 422 }
177 423 }
@@ -190,9 +436,9 @@
190 436 $array = $args[0];
191 437 $key = $args[1];
192 438
193 439 if (!is_string($key) && !is_int($key)) {
194 - throw new WPRProtectRuleError_V542(
440 + throw new WPRProtectRuleError_V676(
195 441 $this->addExState("getArrayVal: Key must be a valid string or integer")
196 442 );
197 443 }
198 444
@@ -271,9 +517,9 @@
271 517 $array = $args[1];
272 518
273 519 foreach ($array as $element) {
274 520 if (!is_scalar($element)) {
275 - throw new WPRProtectRuleError_V542(
521 + throw new WPRProtectRuleError_V676(
276 522 $this->addExState("arrayJoin: Array element must be of scalar type")
277 523 );
278 524 }
279 525 }
@@ -280,5 +526,5 @@
280 526
281 527 return implode($separator, $array);
282 528 }
283 529 }
284 -endif;
530 +endif;