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
wpremote / protect / fw / rule / functions / array.php

array.php in The WP Remote WordPress Plugin 6.76, at protect/fw/rule/functions/array.php

531 lines 11.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped
3 if (!defined('ABSPATH') && !defined('MCDATAPATH')) exit;
4
5 if (!trait_exists('WPRProtectFWRuleArrayFunc_V676')) :
6 trait WPRProtectFWRuleArrayFunc_V676 {
7 private function _rf_inArray() {
8 $args = $this->processRuleFunctionParams(
9 'inArray',
10 func_num_args(),
11 func_get_args(),
12 2
13 );
14 $element = $args[0];
15 $array = $args[1];
16 $strict = isset($args[2]) ? $args[2] : false;
17
18 if (!is_array($array)) {
19 throw new WPRProtectRuleError_V676(
20 $this->addExState("inArray: 2nd param is not an array")
21 );
22 }
23
24 if (!is_bool($strict)) {
25 throw new WPRProtectRuleError_V676(
26 $this->addExState("inArray: 3rd param is not a boolean")
27 );
28 }
29
30 return in_array($element, $array, $strict);
31 }
32
33 private function _rf_recInArray() {
34 $args = $this->processRuleFunctionParams(
35 'recInArray',
36 func_num_args(),
37 func_get_args(),
38 2
39 );
40 $element = $args[0];
41 $array = $args[1];
42
43 if (is_array($array)) {
44 foreach ($array as $key => $value) {
45 if (is_array($value)) {
46 if ($this->_rf_recInArray($element, $value)) {
47 return true;
48 }
49 } else {
50 if ($value === $element) {
51 return true;
52 }
53 }
54 }
55 } else {
56 throw new WPRProtectRuleError_V676(
57 $this->addExState("recInArray: Expects an array")
58 );
59 }
60
61 return false;
62 }
63
64 private function _rf_arrayKeyExists() {
65 $args = $this->processRuleFunctionParams(
66 'arrayKeyExists',
67 func_num_args(),
68 func_get_args(),
69 2
70 );
71 $key = $args[0];
72 $array = $args[1];
73
74 if (!is_array($array)) {
75 throw new WPRProtectRuleError_V676(
76 $this->addExState("arrayKeyExists: Array must be of type array")
77 );
78 } elseif (!is_string($key) && !is_int($key)) {
79 throw new WPRProtectRuleError_V676(
80 $this->addExState("arrayKeyExists: Key must be of type string or int")
81 );
82 }
83
84 return array_key_exists($key, $array);
85 }
86
87 private function _rf_isArrayEmpty() {
88 $args = $this->processRuleFunctionParams(
89 'isArrayEmpty',
90 func_num_args(),
91 func_get_args(),
92 1,
93 ['array']
94 );
95 $array = $args[0];
96
97 return $this->_rf_isEmpty($array);
98 }
99
100 private function _rf_getArrayKeys() {
101 $args = $this->processRuleFunctionParams(
102 'getArrayKeys',
103 func_num_args(),
104 func_get_args(),
105 1,
106 ['array']
107 );
108 $array = $args[0];
109 $recursive = isset($args[1]) ? $args[1] : false;
110
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;
127 }
128
129 private function _rf_hasAnyArrayKey() {
130 $args = $this->processRuleFunctionParams(
131 'hasAnyArrayKey',
132 func_num_args(),
133 func_get_args(),
134 2,
135 ['array', 'array']
136 );
137 $array = $args[0];
138 $keys = $args[1];
139 $recursive = isset($args[2]) ? $args[2] : false;
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();
148 foreach ($keys as $key) {
149 if (!is_int($key) && !is_string($key)) {
150 throw new WPRProtectRuleError_V676(
151 $this->addExState("hasAnyArrayKey: Key must be of type string or int")
152 );
153 }
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);
170 if (array_key_exists($key, $array)) {
171 return true;
172 }
173 }
174
175 return false;
176 }
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
310 private function _rf_digArray() {
311 $args = $this->processRuleFunctionParams(
312 'digArray',
313 func_num_args(),
314 func_get_args(),
315 2,
316 ['array', 'array']
317 );
318 $array = $args[0];
319 $keys = $args[1];
320
321 foreach ($keys as $key) {
322 if (!is_int($key) && !is_string($key)) {
323 throw new WPRProtectRuleError_V676(
324 $this->addExState("digArray: Keys must be a valid array of string, or integer type")
325 );
326 }
327 }
328
329 return WPRHelper::digArray($array, $keys);
330 }
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
406 private function _rf_filterArray() {
407 $args = $this->processRuleFunctionParams(
408 'filterArray',
409 func_num_args(),
410 func_get_args(),
411 2,
412 ['array', 'array']
413 );
414 $array = $args[0];
415 $keys = $args[1];
416
417 foreach ($keys as $key) {
418 if (!is_int($key) && !is_string($key)) {
419 throw new WPRProtectRuleError_V676(
420 $this->addExState("filterArray: Keys must be a valid array of string, or integer type")
421 );
422 }
423 }
424
425 return WPRHelper::filterArray($array, $keys);
426 }
427
428 private function _rf_getArrayVal() {
429 $args = $this->processRuleFunctionParams(
430 'getArrayVal',
431 func_num_args(),
432 func_get_args(),
433 2,
434 ['array']
435 );
436 $array = $args[0];
437 $key = $args[1];
438
439 if (!is_string($key) && !is_int($key)) {
440 throw new WPRProtectRuleError_V676(
441 $this->addExState("getArrayVal: Key must be a valid string or integer")
442 );
443 }
444
445 if (array_key_exists($key, $array)) {
446 return $array[$key];
447 }
448
449 return null;
450 }
451
452 private function _rf_arrayIntersection() {
453 $args = $this->processRuleFunctionParams(
454 'arrayIntersection',
455 func_num_args(),
456 func_get_args(),
457 2,
458 ['array', 'array']
459 );
460 $array1 = $args[0];
461 $array2 = $args[1];
462
463 return array_intersect($array1, $array2);
464 }
465
466 private function _rf_arrayIntersectionAssoc() {
467 $args = $this->processRuleFunctionParams(
468 'arrayIntersectionAssoc',
469 func_num_args(),
470 func_get_args(),
471 2,
472 ['array', 'array']
473 );
474 $array1 = $args[0];
475 $array2 = $args[1];
476
477 return array_intersect_assoc($array1, $array2);
478 }
479
480 private function _rf_arrayUnion() {
481 $args = $this->processRuleFunctionParams(
482 'arrayUnion',
483 func_num_args(),
484 func_get_args(),
485 2,
486 ['array', 'array']
487 );
488 $array1 = $args[0];
489 $array2 = $args[1];
490
491 return ($array1 + $array2);
492 }
493
494 private function _rf_arrayMerge() {
495 $args = $this->processRuleFunctionParams(
496 'arrayMerge',
497 func_num_args(),
498 func_get_args(),
499 2,
500 ['array', 'array']
501 );
502 $array1 = $args[0];
503 $array2 = $args[1];
504
505 return array_merge($array1, $array2);
506 }
507
508 private function _rf_arrayJoin() {
509 $args = $this->processRuleFunctionParams(
510 'arrayJoin',
511 func_num_args(),
512 func_get_args(),
513 2,
514 ['string', 'array']
515 );
516 $separator = $args[0];
517 $array = $args[1];
518
519 foreach ($array as $element) {
520 if (!is_scalar($element)) {
521 throw new WPRProtectRuleError_V676(
522 $this->addExState("arrayJoin: Array element must be of scalar type")
523 );
524 }
525 }
526
527 return implode($separator, $array);
528 }
529 }
530 endif;
531