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 +259 -14 6.486.76 View file →
@@ -1,10 +1,10 @@
1 1 <?php
2 2 // phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped
3 3 if (!defined('ABSPATH') && !defined('MCDATAPATH')) exit;
4 4
5 -if (!trait_exists('WPRProtectFWRuleArrayFunc_V648')) :
6 -trait WPRProtectFWRuleArrayFunc_V648 {
5 +if (!trait_exists('WPRProtectFWRuleArrayFunc_V676')) :
6 +trait WPRProtectFWRuleArrayFunc_V676 {
7 7 private function _rf_inArray() {
8 8 $args = $this->processRuleFunctionParams(
9 9 'inArray',
10 10 func_num_args(),
@@ -15,15 +15,15 @@
15 15 $array = $args[1];
16 16 $strict = isset($args[2]) ? $args[2] : false;
17 17
18 18 if (!is_array($array)) {
19 - throw new WPRProtectRuleError_V648(
19 + throw new WPRProtectRuleError_V676(
20 20 $this->addExState("inArray: 2nd param is not an array")
21 21 );
22 22 }
23 23
24 24 if (!is_bool($strict)) {
25 - throw new WPRProtectRuleError_V648(
25 + throw new WPRProtectRuleError_V676(
26 26 $this->addExState("inArray: 3rd param is not a boolean")
27 27 );
28 28 }
29 29
@@ -52,9 +52,9 @@
52 52 }
53 53 }
54 54 }
55 55 } else {
56 - throw new WPRProtectRuleError_V648(
56 + throw new WPRProtectRuleError_V676(
57 57 $this->addExState("recInArray: Expects an array")
58 58 );
59 59 }
60 60
@@ -71,13 +71,13 @@
71 71 $key = $args[0];
72 72 $array = $args[1];
73 73
74 74 if (!is_array($array)) {
75 - throw new WPRProtectRuleError_V648(
75 + throw new WPRProtectRuleError_V676(
76 76 $this->addExState("arrayKeyExists: Array must be of type array")
77 77 );
78 78 } elseif (!is_string($key) && !is_int($key)) {
79 - throw new WPRProtectRuleError_V648(
79 + throw new WPRProtectRuleError_V676(
80 80 $this->addExState("arrayKeyExists: Key must be of type string or int")
81 81 );
82 82 }
83 83
@@ -105,10 +105,26 @@
105 105 1,
106 106 ['array']
107 107 );
108 108 $array = $args[0];
109 + $recursive = isset($args[1]) ? $args[1] : false;
109 110
110 - 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;
111 127 }
112 128
113 129 private function _rf_hasAnyArrayKey() {
114 130 $args = $this->processRuleFunctionParams(
@@ -119,16 +135,39 @@
119 135 ['array', 'array']
120 136 );
121 137 $array = $args[0];
122 138 $keys = $args[1];
139 + $recursive = isset($args[2]) ? $args[2] : false;
123 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();
124 148 foreach ($keys as $key) {
125 149 if (!is_int($key) && !is_string($key)) {
126 - throw new WPRProtectRuleError_V648(
150 + throw new WPRProtectRuleError_V676(
127 151 $this->addExState("hasAnyArrayKey: Key must be of type string or int")
128 152 );
129 153 }
130 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);
131 170 if (array_key_exists($key, $array)) {
132 171 return true;
133 172 }
134 173 }
@@ -135,8 +174,140 @@
135 174
136 175 return false;
137 176 }
138 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 +
139 310 private function _rf_digArray() {
140 311 $args = $this->processRuleFunctionParams(
141 312 'digArray',
142 313 func_num_args(),
@@ -148,9 +319,9 @@
148 319 $keys = $args[1];
149 320
150 321 foreach ($keys as $key) {
151 322 if (!is_int($key) && !is_string($key)) {
152 - throw new WPRProtectRuleError_V648(
323 + throw new WPRProtectRuleError_V676(
153 324 $this->addExState("digArray: Keys must be a valid array of string, or integer type")
154 325 );
155 326 }
156 327 }
@@ -157,8 +328,82 @@
157 328
158 329 return WPRHelper::digArray($array, $keys);
159 330 }
160 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 +
161 406 private function _rf_filterArray() {
162 407 $args = $this->processRuleFunctionParams(
163 408 'filterArray',
164 409 func_num_args(),
@@ -170,9 +415,9 @@
170 415 $keys = $args[1];
171 416
172 417 foreach ($keys as $key) {
173 418 if (!is_int($key) && !is_string($key)) {
174 - throw new WPRProtectRuleError_V648(
419 + throw new WPRProtectRuleError_V676(
175 420 $this->addExState("filterArray: Keys must be a valid array of string, or integer type")
176 421 );
177 422 }
178 423 }
@@ -191,9 +436,9 @@
191 436 $array = $args[0];
192 437 $key = $args[1];
193 438
194 439 if (!is_string($key) && !is_int($key)) {
195 - throw new WPRProtectRuleError_V648(
440 + throw new WPRProtectRuleError_V676(
196 441 $this->addExState("getArrayVal: Key must be a valid string or integer")
197 442 );
198 443 }
199 444
@@ -272,9 +517,9 @@
272 517 $array = $args[1];
273 518
274 519 foreach ($array as $element) {
275 520 if (!is_scalar($element)) {
276 - throw new WPRProtectRuleError_V648(
521 + throw new WPRProtectRuleError_V676(
277 522 $this->addExState("arrayJoin: Array element must be of scalar type")
278 523 );
279 524 }
280 525 }
@@ -281,5 +526,5 @@
281 526
282 527 return implode($separator, $array);
283 528 }
284 529 }
285 -endif;
530 +endif;