This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php namespace nyx\utils\str; |
||
2 | |||
3 | // External dependencies |
||
4 | use nyx\core; |
||
5 | use nyx\diagnostics; |
||
6 | |||
7 | // Internal dependencies |
||
8 | use nyx\utils; |
||
9 | |||
10 | /** |
||
11 | * Character |
||
12 | * |
||
13 | * @package Nyx\Utils\Strings |
||
14 | * @version 0.1.0 |
||
15 | * @author Michal Chojnacki <[email protected]> |
||
16 | * @copyright 2012-2016 Nyx Dev Team |
||
17 | * @link http://docs.muyo.io/nyx/utils/strings.html |
||
18 | */ |
||
19 | class Character |
||
20 | { |
||
21 | /** |
||
22 | * The traits of the Character class. |
||
23 | */ |
||
24 | use utils\traits\StaticallyExtendable; |
||
25 | |||
26 | /** |
||
27 | * Flags used to combine different characters into a set via self::buildCharacterSet() |
||
28 | */ |
||
29 | const CHARS_UPPER = 1; // Uppercase letters. |
||
30 | const CHARS_LOWER = 2; // Lowercase letters. |
||
31 | const CHARS_ALPHA = 3; // CHARS_UPPER and CHARS_LOWER. |
||
32 | const CHARS_NUMERIC = 4; // Digits. |
||
33 | const CHARS_ALNUM = 7; // CHARS_ALPHA and CHARS_NUMERIC (Base62) |
||
34 | const CHARS_HEX_UPPER = 12; // Uppercase hexadecimal symbols - CHARS_DIGITS and 8. |
||
35 | const CHARS_HEX_LOWER = 20; // Lowercase hexadecimal symbols - CHARS_DIGITS and 16. |
||
36 | const CHARS_BASE64 = 39; // CHARS_ALNUM and 32. |
||
37 | const CHARS_SYMBOLS = 64; // Additional symbols ($%& etc.) accessible on most if not all keyboards. |
||
38 | const CHARS_BRACKETS = 128; // Brackets. |
||
39 | const CHARS_PUNCTUATION = 256; // Punctuation marks. |
||
40 | |||
41 | /** |
||
42 | * @const Special character flag for alphanumeric characters excluding characters which tend |
||
43 | * to be hard to distinguish from each other. |
||
44 | */ |
||
45 | const CHARS_LEGIBLE = 512; |
||
46 | |||
47 | /** |
||
48 | * @var array A map of CHARS_* flags to their actual character lists. @todo Make writable, handle cache? |
||
49 | */ |
||
50 | protected static $setsMap = [ |
||
51 | self::CHARS_UPPER => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', |
||
52 | self::CHARS_LOWER => 'abcdefghijklmnopqrstuvwxyz', |
||
53 | self::CHARS_NUMERIC => '0123456789', |
||
54 | self::CHARS_HEX_UPPER => 'ABCDEF', |
||
55 | self::CHARS_HEX_LOWER => 'abcdef', |
||
56 | self::CHARS_BASE64 => '+/', |
||
57 | self::CHARS_SYMBOLS => '!"#$%&\'()* +,-./:;<=>?@[\]^_`{|}~', |
||
58 | self::CHARS_BRACKETS => '()[]{}<>', |
||
59 | self::CHARS_PUNCTUATION => ',.;:', |
||
60 | self::CHARS_LEGIBLE => 'DQO0B8|I1lS5Z2G6()[]{}:;,.' // Somewhat unintuitive as this is actually an |
||
61 | // exclusion map containing ambiguous characters. |
||
62 | ]; |
||
63 | |||
64 | /** |
||
65 | * @var array Cached character sets built via self::buildCharacterSet() in a $bitmask => $set format, |
||
66 | * where $bitmask are the flags used to build the $set character list. |
||
67 | */ |
||
68 | protected static $setsBuilt; |
||
69 | |||
70 | /** |
||
71 | * Returns the character at the specified $offset (0-indexed) in $haystack. |
||
72 | * |
||
73 | * @param string $haystack The string to search in. |
||
74 | * @param int $offset The requested index. If a negative index is given, this method will return |
||
75 | * the $offset-th character counting from the end of the string. |
||
76 | * @param string|null $encoding The encoding to use. |
||
77 | * @return string The character at the specified $index. |
||
78 | */ |
||
79 | public static function at(string $haystack, int $offset, string $encoding = null) : string |
||
80 | { |
||
81 | $encoding = $encoding ?: utils\Str::encoding($haystack); |
||
82 | |||
83 | // Check if the absolute starting index (to account for negative indexes) + 1 (since it's 0-indexed |
||
84 | // while length is > 1 at this point) is within the length of the string. |
||
85 | View Code Duplication | if (abs($offset) >= mb_strlen($haystack, $encoding)) { |
|
86 | throw new \OutOfBoundsException('The given $offset ['.$offset.'] does not exist within the string ['.utils\Str::truncate($haystack, 20, '...', $encoding).'].'); |
||
0 ignored issues
–
show
|
|||
87 | } |
||
88 | |||
89 | return mb_substr($haystack, $offset, 1, $encoding); |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * Creates a list of characters based on a set of flags (CHARS_* class constants) given. |
||
94 | * |
||
95 | * @param int|core\Mask $mask The combination of CHARS_* flags (see the class constants) to use. Can be |
||
96 | * passed in either as an integer or as an instance of nyx\core\Mask. |
||
97 | * @return string The resulting list of characters. |
||
98 | * @throws \InvalidArgumentException When an invalid $from mask was given or the supposed bitmask is <= 0. |
||
99 | */ |
||
100 | public static function buildSet($mask) : string |
||
101 | { |
||
102 | // Unpack the actual mask if we got a core\Mask (builder) instance. |
||
103 | if ($mask instanceof core\Mask) { |
||
104 | $mask = $mask->get(); |
||
105 | } else if (!is_int($mask)) { |
||
106 | throw new \InvalidArgumentException('Expected an integer or an instance of \nyx\core\Mask, got ['.diagnostics\Debug::getTypeName($mask).'] instead.'); |
||
107 | } |
||
108 | |||
109 | if ($mask <= 0) { |
||
110 | throw new \InvalidArgumentException("Expected a bitmask, got an integer with a value of [$mask] instead."); |
||
111 | } |
||
112 | |||
113 | // If all we get is the ambiguous exclusion flag, we need a base set of characters |
||
114 | // to work with (an exclude from). |
||
115 | if ($mask === self::CHARS_LEGIBLE) { |
||
116 | $mask |= self::CHARS_ALNUM; |
||
117 | } |
||
118 | |||
119 | // Return a cached set if we've got one. Can't do this before the check for CHARS_LEGIBLE |
||
120 | // above as the flag for alphanumeric chars gets applied to them first regardless of user given |
||
121 | // params. |
||
122 | if (isset(static::$setsBuilt[$mask])) { |
||
123 | return static::$setsBuilt[$mask]; |
||
124 | } |
||
125 | |||
126 | $result = ''; |
||
127 | |||
128 | // Iterate over all defined sets and build up the string for set flags. |
||
129 | foreach (static::$setsMap as $flag => $characters) { |
||
130 | // Ambiguous chars may get special exclusion treatment (see post loop). |
||
131 | if ($flag === self::CHARS_LEGIBLE) { |
||
132 | continue; |
||
133 | } |
||
134 | |||
135 | if (($mask & $flag) === $flag) { |
||
136 | $result .= $characters; |
||
137 | } |
||
138 | } |
||
139 | |||
140 | // Remove all known ambiguous characters from the set, if CHARS_LEGIBLE is set. |
||
141 | if ($mask & self::CHARS_LEGIBLE) { |
||
142 | $result = str_replace(str_split(static::$setsMap[self::CHARS_LEGIBLE]), '', $result); |
||
143 | } |
||
144 | |||
145 | // In mode 3 count_chars() returns only unique characters. Cache the result for the |
||
146 | // flag set given so we can avoid the loops later on for the exact same mask. |
||
147 | return static::$setsBuilt[$mask] = count_chars($result, 3); |
||
148 | } |
||
149 | |||
150 | /** |
||
151 | * Runs the given callable over each character in the given string and returns the resulting string. |
||
152 | * |
||
153 | * The callable should accept two arguments (in this order): |
||
154 | * - the character (multibyte string) |
||
155 | * - the character's index (int). |
||
156 | * |
||
157 | * Additional arguments may also be added and will be appended to the callable in the order given. |
||
158 | * The callable must return either a string or a value castable to a string. |
||
159 | * |
||
160 | * @param string $str The string over which to run the callable. |
||
161 | * @param callable $callable The callable to apply. |
||
162 | * @param string|null $encoding The encoding to use. |
||
163 | * @param mixed ...$args Additional arguments to pass to the callable. |
||
164 | * @return string The string after applying the callable to each of its characters. |
||
165 | */ |
||
166 | public static function each(string $str, callable $callable, string $encoding = null, ...$args) : string |
||
167 | { |
||
168 | if ($str === '') { |
||
169 | return $str; |
||
170 | } |
||
171 | |||
172 | $result = ''; |
||
173 | $encoding = $encoding ?: utils\Str::encoding($str); |
||
174 | $length = mb_strlen($str, $encoding); |
||
175 | |||
176 | for ($idx = 0; $idx < $length; $idx++) { |
||
177 | $result .= (string) call_user_func($callable, mb_substr($str, $idx, 1, $encoding), $idx, ...$args); |
||
178 | } |
||
179 | |||
180 | return $result; |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Returns the binary string representation of the given character. Multi-byte safe. |
||
185 | * |
||
186 | * @param string $character The character to represent. |
||
187 | * @return string |
||
188 | */ |
||
189 | public static function toBinaryString(string $character) : string |
||
190 | { |
||
191 | $result = null; |
||
192 | $length = strlen($character); // Note: We want the raw length, not the mb length. |
||
193 | |||
194 | for ($i = 0; $i < $length; ++$i) { |
||
195 | $result .= sprintf('%08b', ord($character[$i])); |
||
196 | } |
||
197 | |||
198 | return $result; |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Returns the decimal code representation of the given character. Multi-byte safe. |
||
203 | * |
||
204 | * @param string $character The character to represent. |
||
205 | * @return int |
||
206 | */ |
||
207 | public static function toDecimalCode(string $character) : int |
||
208 | { |
||
209 | $code = ord($character[0]); |
||
210 | |||
211 | // Single byte / 0xxxxxxx |
||
212 | if (!($code & 0x80)) { |
||
213 | return $code; |
||
214 | } |
||
215 | |||
216 | $bytes = 1; |
||
217 | |||
218 | // 2 bytes / 110xxxxx |
||
219 | if (0xc0 === ($code & 0xe0)) { |
||
220 | $code = $code & ~0xc0; |
||
221 | $bytes = 2; |
||
222 | // 3 bytes / 1110xxxx |
||
223 | } elseif (0xe0 === ($code & 0xf0)) { |
||
224 | $code = $code & ~0xe0; |
||
225 | $bytes = 3; |
||
226 | // 4 bytes / 11110xxx |
||
227 | } elseif (0xf0 === ($code & 0xf8)) { |
||
228 | $code = $code & ~0xf0; |
||
229 | $bytes = 4; |
||
230 | } |
||
231 | |||
232 | for ($i = 2; $i <= $bytes; $i++) { |
||
233 | $code = ($code << 6) + (ord($character[$i - 1]) & ~0x80); |
||
234 | } |
||
235 | |||
236 | return $code; |
||
237 | } |
||
238 | } |
||
239 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: