Skip to content

Commit 63c8d0e

Browse files
committed
Added: ability to match against file uploads.
Added: comments to matching types.
1 parent 73d1339 commit 63c8d0e

2 files changed

Lines changed: 88 additions & 12 deletions

File tree

src/Processor.php

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -285,67 +285,115 @@ public function matchParameterValue($match, $value)
285285
$matchValue = isset($match['value']) ? $match['value'] : null;
286286

287287
// Perform a match depending on the given match type.
288+
// If a scalar matches another scalar (loose).
288289
if ($matchType == 'equals' && is_scalar($value) && is_scalar($matchValue)) {
289290
return $matchValue == $value;
290291
}
291292

293+
// If a scalar matches another scaler (strict).
292294
if ($matchType == 'equals_strict' && is_scalar($value) && is_scalar($matchValue)) {
293295
return $matchValue === $value;
294296
}
295297

298+
// If a scalar is bigger than another scalar.
296299
if ($matchType == 'more_than' && is_scalar($value) && is_scalar($matchValue)) {
297300
return $value > $matchValue;
298301
}
299302

303+
// If a scalar is less than another scalar.
300304
if ($matchType == 'less_than' && is_scalar($value) && is_scalar($matchValue)) {
301305
return $value < $matchValue;
302306
}
303307

308+
// If the parameter is present at all.
304309
if ($matchType == 'isset') {
305310
return true;
306311
}
307312

313+
// If a scaler is a ctype digit.
308314
if ($matchType == 'ctype_digit' && is_scalar($value)) {
309315
return @ctype_digit($value) === $matchValue;
310316
}
311317

318+
// If a scaler is a ctype alnum.
312319
if ($matchType == 'ctype_alnum' && is_scalar($value)) {
313320
return @ctype_alnum($value) === $matchValue;
314321
}
315322

323+
// If a scalar is numeric.
316324
if ($matchType == 'is_numeric' && is_scalar($value)) {
317325
return @is_numeric($value) === $matchValue;
318326
}
319327

328+
// If a scalar contains a value.
320329
if (($matchType == 'contains' || $matchType == 'stripos') && is_scalar($value)) {
321330
return @stripos($value, $matchValue) !== false;
322331
}
323332

333+
// If a string matches a regular expression.
324334
if ($matchType == 'regex' && is_string($matchValue) && is_scalar($value)) {
325335
return @preg_match($matchValue, @urldecode($value)) === 1;
326336
}
327337

338+
// If the user does not have a WP privilege.
328339
if ($matchType == 'current_user_cannot' && is_scalar($matchValue) && function_exists('current_user_can')) {
329340
return @!current_user_can($matchValue);
330341
}
331342

343+
// If a value is in an array.
332344
if ($matchType == 'in_array' && !is_array($value) && is_array($matchValue)) {
333345
return @in_array($value, $matchValue);
334346
}
335347

348+
// If a value is not in an array.
336349
if ($matchType == 'not_in_array' && !is_array($value) && is_array($matchValue)) {
337350
return @!in_array($value, $matchValue);
338351
}
339352

353+
// If an array of values is in another array of values.
340354
if ($matchType == 'array_in_array' && is_array($value) && is_array($matchValue)) {
341355
return @array_intersect($value, $matchValue);
342356
}
343357

358+
// If a specific parameter key matches a sub-match condition.
344359
if ($matchType == 'array_key_value' && isset($match['key'], $match['match'])) {
345360
$value = $this->getParameterValue($match['key'], $value);
346361
return $this->matchParameterValue($match['match'], $value);
347362
}
348363

364+
// If any of the uploaded files in the parameter matches a sub-match condition.
365+
if ($matchType == 'file_contains' && isset($match['match'])) {
366+
// Extract all tmp_names.
367+
if (isset($value['tmp_name'])) {
368+
$files = $value['tmp_name'];
369+
if (!is_array($files)) {
370+
$files = [$files];
371+
}
372+
} else {
373+
$files = array_column($value, 'tmp_name');
374+
}
375+
376+
// No need to continue if there are no files.
377+
if (is_array($files) && count($files) === 0) {
378+
return false;
379+
}
380+
381+
// Cast all tmp_names to a single-dimension array.
382+
$files = $this->getArrayValues($files, '', 'array');
383+
if (is_array($files) && count($files) === 0) {
384+
return false;
385+
}
386+
387+
// Get the contents of the files.
388+
$contents = '';
389+
foreach ($files as $file) {
390+
$contents .= (string) @file_get_contents($file);
391+
}
392+
393+
// Now attempt to match it.
394+
return $this->matchParameterValue($match['match'], $contents);
395+
}
396+
349397
return false;
350398
}
351399

@@ -540,25 +588,45 @@ public function applyMutation($mutations, $value)
540588
* Given an array, multi-dimensional or not, extract all of its values.
541589
*
542590
* @param array $data
543-
* @return string
591+
* @param string $glue
592+
* @param string $type
593+
* @return string|array
544594
*/
545-
public function getArrayValues($data, $glue = '&')
595+
public function getArrayValues($data, $glue = '&', $type = 'string')
546596
{
547-
$ret = '';
548-
549-
foreach ($data as $key => $item) {
597+
// If we want to return a single line string.
598+
if ($type == 'string') {
599+
$ret = '';
600+
foreach ($data as $key => $item) {
601+
if (empty($item)) {
602+
continue;
603+
}
604+
605+
if (is_array($item)) {
606+
$ret .= $this->getArrayValues($item, $glue) . $glue;
607+
} else {
608+
$ret .= $key . '=' . $item . $glue;
609+
}
610+
}
611+
612+
return substr($ret, 0, 0 - strlen($glue));
613+
}
614+
615+
// Or a single dimension array with each value its own entry.
616+
$ret = [];
617+
foreach ($data as $key => $item) {
550618
if (empty($item)) {
551619
continue;
552620
}
553621

554-
if (is_array($item)) {
555-
$ret .= $this->getArrayValues($item, $glue) . $glue;
556-
} else {
557-
$ret .= $key . '=' . $item . $glue;
558-
}
559-
}
622+
if (is_array($item)) {
623+
$ret = array_merge($ret, $this->getArrayValues($item, $glue, 'array'));
624+
} else {
625+
$ret[] = $item;
626+
}
627+
}
560628

561-
return substr($ret, 0, 0 - strlen($glue));
629+
return $ret;
562630
}
563631

564632
/**

tests/data/Rules.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,13 @@
110110
"cat":"TEST",
111111
"type":"BLOCK",
112112
"type_params":null
113+
},
114+
{
115+
"id":15,
116+
"title":"Determine if a certain value is present anywhere in any uploaded file.",
117+
"rules":[{"parameter":"files.img","match":{"type":"file_contains","match":{"type":"contains","value":"<?php"}}}],
118+
"cat":"TEST",
119+
"type":"BLOCK",
120+
"type_params":null
113121
}
114122
]

0 commit comments

Comments
 (0)