Issues (102)

Security Analysis    no vulnerabilities found

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

plugin/Helpers/Arr.php (1 issue)

Severity
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Helpers;
4
5
use GeminiLabs\SiteReviews\Arguments;
6
use GeminiLabs\SiteReviews\Helper;
7
8
class Arr
9
{
10 47
    public static function compare(array $arr1, array $arr2): bool
11
    {
12 47
        sort($arr1);
13 47
        sort($arr2);
14 47
        return $arr1 == $arr2;
15
    }
16
17
    /**
18
     * @param mixed $value
19
     */
20 224
    public static function consolidate($value, array $fallback = []): array
21
    {
22 224
        if ($value instanceof Arguments) {
23 8
            return $value->getArrayCopy(); // This ensures we don't convert array values.
24
        }
25 224
        if (is_object($value)) {
26 17
            $values = get_object_vars($value);
27 17
            $value = Helper::ifEmpty($values, (array) $value, $strict = true);
28
        }
29 224
        return is_array($value) ? $value : $fallback;
30
    }
31
32
    /**
33
     * @param mixed $value
34
     * @param mixed $callback
35
     */
36 130
    public static function convertFromString($value, $callback = null): array
37
    {
38 130
        if (is_scalar($value)) {
39 129
            $value = array_map('trim', explode(',', Cast::toString($value)));
40
        }
41 130
        $callback = Helper::ifEmpty(Cast::toString($callback), Helper::class.'::isNotEmpty');
42 130
        return static::reindex(array_filter((array) $value, $callback));
43
    }
44
45 143
    public static function flatten(array $array, bool $flattenValue = false, string $prefix = ''): array
46
    {
47 143
        $result = [];
48 143
        foreach ($array as $key => $value) {
49 143
            $newKey = ltrim("{$prefix}.{$key}", '.');
50 143
            if (static::isIndexedAndFlat($value)) {
51 45
                $value = Helper::ifTrue(!$flattenValue, $value,
52 45
                    fn () => '['.implode(', ', $value).']'
53 45
                );
54 143
            } elseif (is_array($value)) {
55 45
                $result = array_merge($result, static::flatten($value, $flattenValue, $newKey));
56 45
                continue;
57
            }
58 143
            $result[$newKey] = $value;
59
        }
60 143
        return $result;
61
    }
62
63
    /**
64
     * Get a value from an array of values using a dot-notation path as reference.
65
     *
66
     * @param mixed      $data
67
     * @param string|int $path
68
     * @param mixed      $fallback
69
     *
70
     * @return mixed
71
     */
72 221
    public static function get($data, $path = '', $fallback = '')
73
    {
74 221
        $data = static::consolidate($data);
75 221
        $keys = explode('.', (string) $path);
76 221
        $result = $fallback;
77 221
        foreach ($keys as $key) {
78 221
            if (!isset($data[$key])) {
79 208
                return $fallback;
80
            }
81 220
            if (is_object($data[$key])) {
82 9
                $result = $data[$key];
83 9
                $data = static::consolidate($result);
84 9
                continue;
85
            }
86 220
            $result = $data[$key];
87 220
            $data = $result;
88
        }
89 220
        return $result;
90
    }
91
92
    /**
93
     * @param mixed      $data
94
     * @param string|int $path
95
     * @param mixed      $fallback
96
     *
97
     * @return mixed
98
     */
99 50
    public static function getAs(string $cast, $data, $path = '', $fallback = '')
100
    {
101 50
        return Cast::to($cast, static::get($data, $path, $fallback));
102
    }
103
104
    /**
105
     * @param string|int $key
106
     */
107 1
    public static function insertAfter($key, array $array, array $insert): array
108
    {
109 1
        return static::insert($array, $insert, $key, 'after');
110
    }
111
112
    /**
113
     * @param string|int $key
114
     */
115 1
    public static function insertBefore($key, array $array, array $insert): array
116
    {
117 1
        return static::insert($array, $insert, $key, 'before');
118
    }
119
120
    /**
121
     * @param string|int $key
122
     */
123 2
    public static function insert(array $array, array $insert, $key, string $position = 'before'): array
124
    {
125 2
        $keyPosition = array_search($key, array_keys($array));
126 2
        if (false !== $keyPosition) {
127 2
            $keyPosition = Cast::toInt($keyPosition);
128 2
            if ('after' === $position) {
129 1
                ++$keyPosition;
130
            }
131 2
            $result = array_slice($array, 0, $keyPosition);
132 2
            $result = array_merge($result, $insert);
133 2
            return array_merge($result, array_slice($array, $keyPosition));
134
        }
135 2
        return array_merge($array, $insert);
136
    }
137
138
    /**
139
     * @param mixed $array
140
     */
141 215
    public static function isIndexedAndFlat($array): bool
142
    {
143 215
        if (!is_array($array) || array_filter($array, 'is_array')) {
144 167
            return false;
145
        }
146 214
        return wp_is_numeric_array($array);
147
    }
148
149 26
    public static function prefixKeys(array $values, string $prefix = '_'): array
150
    {
151 26
        $result = [];
152 26
        foreach ($values as $key => $value) {
153 26
            $key = trim($key);
154 2
            if (!str_starts_with($key, $prefix)) {
155 2
                $key = $prefix.$key;
156 2
            }
157
            $result[$key] = $value;
158 2
        }
159
        return $result;
160 26
    }
161
162
    /**
163
     * @param mixed $value
164
     * @param mixed $key
165
     */
166
    public static function prepend(array $array, $value, $key = null): array
167 50
    {
168
        if (!is_null($key)) {
169 50
            return [$key => $value] + $array;
170 13
        }
171
        array_unshift($array, $value);
172 46
        return $array;
173 46
    }
174
175
    public static function reindex(array $array): array
176 131
    {
177
        return static::isIndexedAndFlat($array) ? array_values($array) : $array;
178 131
    }
179
180
    /**
181
     * Unset a value from an array of values using a dot-notation path as reference.
182
     *
183
     * @param mixed $data
184
     */
185
    public static function remove($data, string $path = ''): array
186 1
    {
187
        $data = static::consolidate($data);
188 1
        $keys = explode('.', $path);
189 1
        $last = array_pop($keys);
190 1
        $pointer = &$data;
191 1
        foreach ($keys as $key) {
192 1
            if (is_array(static::get($pointer, $key))) {
193 1
                $pointer = &$pointer[$key];
194 1
            }
195
        }
196
        unset($pointer[$last]);
197 1
        return $data;
198 1
    }
199
200
    public static function removeEmptyValues(array $array): array
201 136
    {
202
        $result = [];
203 136
        foreach ($array as $key => $value) {
204 136
            if (Helper::isEmpty($value)) {
205 136
                continue;
206 128
            }
207
            $result[$key] = Helper::ifTrue(!is_array($value), $value,
208 136
                fn () => static::removeEmptyValues($value)
209 136
            );
210 136
        }
211
        return $result;
212 136
    }
213
214
    public static function restrictKeys(array $array, array $allowedKeys): array
215 160
    {
216
        return array_intersect_key($array, array_fill_keys($allowedKeys, ''));
217 160
    }
218
219
    /**
220
     * Search a multidimensional array by key value.
221
     *
222
     * @param mixed      $needle
223
     * @param array      $haystack
224
     * @param int|string $key
225
     *
226
     * @return array|false
227
     */
228
    public static function searchByKey($needle, $haystack, $key)
229 45
    {
230
        if (!is_array($haystack) || empty($haystack)) {
0 ignored issues
show
The condition is_array($haystack) is always true.
Loading history...
231 45
            return false;
232
        }
233
        $keys = array_keys($haystack);
234 45
        $values = array_column($haystack, $key);
235 45
        if (count($keys) !== count($values)) {
236 44
            return false; // Avoid array_combine failure
237
        }
238 45
        $column = array_combine($keys, $values);
239
        $index = array_search($needle, $column, true);
240
        return false !== $index ? $haystack[$index] ?? false : false;
241
    }
242
243
    /**
244
     * Set a value to an array of values using a dot-notation path as reference.
245
     *
246
     * @param mixed $value
247 125
     */
248
    public static function set(array $data, string $path, $value): array
249 125
    {
250 125
        $token = strtok($path, '.');
251 125
        if (false === $token) {
252 125
            return $data; // abort since no path was given
253
        }
254
        $ref = &$data;
255 125
        while (false !== $token) {
256 125
            if (is_object($ref)) {
257
                $ref = &$ref->$token;
258 125
            } else {
259
                $ref = static::consolidate($ref);
260 125
                $ref = &$ref[$token];
261 125
            }
262
            $token = strtok('.');
263
        }
264 124
        $ref = $value;
265
        return $data;
266 124
    }
267 124
268 124
    public static function unflatten(array $array): array
269
    {
270 124
        $results = [];
271
        foreach ($array as $path => $value) {
272
            $results = static::set($results, $path, $value);
273 154
        }
274
        return $results;
275 154
    }
276 154
277 154
    public static function unique(array $values): array
278
    {
279
        return Helper::ifTrue(!static::isIndexedAndFlat($values), $values,
280
            fn () => array_filter(array_unique($values)) // we do not want to reindex the array!
281
        );
282
    }
283
284
    /**
285 51
     * This reindexes the array!
286
     *
287 51
     * @param array|string $values
288 51
     */
289 51
    public static function uniqueInt($values, bool $absint = true): array
290 51
    {
291
        $values = array_filter(static::convertFromString($values), 'is_numeric');
292 51
        $values = array_map('intval', $values);
293
        if ($absint) {
294
            $values = array_filter($values, fn ($value) => $value > 0);
295 25
        }
296
        return array_values(array_unique($values));
297 25
    }
298
299
    public static function unprefixKeys(array $values, string $prefix = '_'): array
300
    {
301
        $results = [];
302
        foreach ($values as $key => $value) {
303
            $key = trim($key);
304
            if ($key !== $prefix && str_starts_with($key, $prefix)) {
305
                $key = substr($key, strlen($prefix));
306
            }
307
            $results[$key] = $value;
308
        }
309
        return $results;
310
    }
311
}
312