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 declare (strict_types = 1); |
||
2 | |||
3 | namespace Limoncello\l10n\Messages; |
||
4 | |||
5 | /** |
||
6 | * Copyright 2015-2019 [email protected] |
||
7 | * |
||
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||
9 | * you may not use this file except in compliance with the License. |
||
10 | * You may obtain a copy of the License at |
||
11 | * |
||
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
13 | * |
||
14 | * Unless required by applicable law or agreed to in writing, software |
||
15 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
17 | * See the License for the specific language governing permissions and |
||
18 | * limitations under the License. |
||
19 | */ |
||
20 | |||
21 | use Limoncello\l10n\Contracts\Messages\BundleStorageInterface; |
||
22 | use function array_keys; |
||
23 | use function assert; |
||
24 | use function count; |
||
25 | use function is_array; |
||
26 | use function locale_lookup; |
||
27 | use function strlen; |
||
28 | |||
29 | /** |
||
30 | * @package Limoncello\l10n |
||
31 | */ |
||
32 | class BundleStorage implements BundleStorageInterface |
||
33 | { |
||
34 | /** Encode index */ |
||
35 | const INDEX_DEFAULT_LOCALE = 0; |
||
36 | |||
37 | /** Encode index */ |
||
38 | const INDEX_DATA = self::INDEX_DEFAULT_LOCALE + 1; |
||
39 | |||
40 | /** |
||
41 | * @var array |
||
42 | */ |
||
43 | private $encodedStorage; |
||
44 | |||
45 | /** |
||
46 | * @var string[] |
||
47 | */ |
||
48 | private $locales; |
||
49 | |||
50 | /** |
||
51 | * @var string |
||
52 | */ |
||
53 | private $defaultLocale; |
||
54 | |||
55 | /** |
||
56 | * @param array $encodedStorage |
||
57 | */ |
||
58 | 7 | public function __construct(array $encodedStorage) |
|
59 | { |
||
60 | 7 | $this->setEncodedStorage($encodedStorage); |
|
61 | } |
||
62 | |||
63 | /** |
||
64 | * @inheritdoc |
||
65 | */ |
||
66 | 7 | public function has(string $locale, string $namespace, string $key): bool |
|
67 | { |
||
68 | 7 | assert(empty($locale) === false && empty($namespace) === false && strlen($key) > 0); |
|
69 | |||
70 | 7 | $has = isset($this->getEncodedStorage()[$locale][$namespace][$key]); |
|
71 | |||
72 | 7 | return $has; |
|
73 | } |
||
74 | |||
75 | /** |
||
76 | * @inheritdoc |
||
77 | */ |
||
78 | 7 | public function get(string $locale, string $namespace, string $key): ?array |
|
79 | { |
||
80 | 7 | $locale = $this->lookupLocale($this->getLocales(), $locale, $this->getDefaultLocale()); |
|
81 | |||
82 | 7 | $result = $this->has($locale, $namespace, $key) === true ? |
|
83 | 7 | $this->getEncodedStorage()[$locale][$namespace][$key] : null; |
|
84 | |||
85 | 7 | assert($result === null || $this->checkValueWithLocale($result) === true); |
|
86 | |||
87 | 7 | return $result; |
|
88 | } |
||
89 | |||
90 | /** |
||
91 | * @inheritdoc |
||
92 | */ |
||
93 | 1 | public function hasResources(string $locale, string $namespace): bool |
|
94 | { |
||
95 | 1 | assert(empty($locale) === false && empty($namespace) === false); |
|
96 | |||
97 | 1 | $has = isset($this->getEncodedStorage()[$locale][$namespace]); |
|
98 | |||
99 | 1 | return $has; |
|
100 | } |
||
101 | |||
102 | /** |
||
103 | * @inheritdoc |
||
104 | */ |
||
105 | 1 | public function getResources(string $locale, string $namespace): array |
|
106 | { |
||
107 | 1 | $locale = $this->lookupLocale($this->getLocales(), $locale, $this->getDefaultLocale()); |
|
108 | |||
109 | 1 | assert($this->hasResources($locale, $namespace) === true); |
|
110 | |||
111 | 1 | $result = $this->getEncodedStorage()[$locale][$namespace]; |
|
112 | |||
113 | 1 | return $result; |
|
114 | } |
||
115 | |||
116 | /** |
||
117 | * @inheritdoc |
||
118 | */ |
||
119 | 7 | public function getDefaultLocale(): string |
|
120 | { |
||
121 | 7 | return $this->defaultLocale; |
|
122 | } |
||
123 | |||
124 | /** |
||
125 | * @return array |
||
126 | */ |
||
127 | 7 | protected function getEncodedStorage(): array |
|
128 | { |
||
129 | 7 | return $this->encodedStorage; |
|
130 | } |
||
131 | |||
132 | /** |
||
133 | * @param string[] $locales |
||
134 | * @param string $locale |
||
135 | * @param string $defaultLocale |
||
136 | * |
||
137 | * @return string |
||
138 | */ |
||
139 | 7 | protected function lookupLocale(array $locales, string $locale, string $defaultLocale): string |
|
140 | { |
||
141 | // for some odd reason locale_lookup returns empty string but not default locale if input locales are empty |
||
142 | 7 | return empty($locales) === true ? $defaultLocale : locale_lookup($locales, $locale, false, $defaultLocale); |
|
143 | } |
||
144 | |||
145 | /** |
||
146 | * @return string[] |
||
147 | */ |
||
148 | 7 | protected function getLocales(): array |
|
149 | { |
||
150 | 7 | return $this->locales; |
|
151 | } |
||
152 | |||
153 | /** |
||
154 | * @param array $encodedStorage |
||
155 | * |
||
156 | * @return self |
||
157 | */ |
||
158 | 7 | protected function setEncodedStorage(array $encodedStorage): self |
|
159 | { |
||
160 | 7 | assert(count($encodedStorage) === 2); |
|
161 | |||
162 | 7 | $encodedData = $encodedStorage[static::INDEX_DATA]; |
|
163 | |||
164 | // check storage has 3 levels locale -> namespace -> key & value + culture pairs and |
||
165 | // keys, values and cultures are non-empty strings |
||
166 | 7 | assert(is_array($encodedData) === true && $this->checkEncodedData($encodedData) === true); |
|
167 | |||
168 | 7 | $this->defaultLocale = $encodedStorage[static::INDEX_DEFAULT_LOCALE]; |
|
169 | 7 | $this->encodedStorage = $encodedData; |
|
170 | 7 | $this->locales = array_keys($encodedData); |
|
0 ignored issues
–
show
|
|||
171 | |||
172 | 7 | return $this; |
|
173 | } |
||
174 | |||
175 | /** |
||
176 | * @param array $encodedData |
||
177 | * |
||
178 | * @return bool |
||
179 | */ |
||
180 | 7 | private function checkEncodedData(array $encodedData): bool |
|
181 | { |
||
182 | 7 | $isValid = true; |
|
183 | 7 | foreach ($encodedData as $locale => $namespaceResources) { |
|
184 | 7 | $isValid = $isValid === true && |
|
185 | 7 | empty($locale) === false && |
|
186 | 7 | is_array($namespaceResources) === true && $this->checkNamespaceResources($namespaceResources); |
|
187 | } |
||
188 | |||
189 | 7 | return $isValid; |
|
190 | } |
||
191 | |||
192 | /** |
||
193 | * @param array $namespaceResources |
||
194 | * |
||
195 | * @return bool |
||
196 | */ |
||
197 | 7 | private function checkNamespaceResources(array $namespaceResources): bool |
|
198 | { |
||
199 | 7 | $isValid = true; |
|
200 | 7 | foreach ($namespaceResources as $namespace => $resources) { |
|
201 | 7 | $isValid = $isValid === true && |
|
202 | 7 | empty($namespace) === false && |
|
203 | 7 | is_array($resources) === true && $this->checkResources($resources); |
|
204 | } |
||
205 | |||
206 | 7 | return $isValid; |
|
207 | } |
||
208 | |||
209 | /** |
||
210 | * @param array $resources |
||
211 | * |
||
212 | * @return bool |
||
213 | */ |
||
214 | 7 | private function checkResources(array $resources): bool |
|
215 | { |
||
216 | 7 | $isValid = true; |
|
217 | 7 | foreach ($resources as $key => $valueAndLocale) { |
|
218 | 7 | $isValid = $isValid === true && $this->checkPair((string)$key, $valueAndLocale); |
|
219 | } |
||
220 | |||
221 | 7 | return $isValid; |
|
222 | } |
||
223 | |||
224 | /** |
||
225 | * @param string $key |
||
226 | * @param array $valueAndLocale |
||
227 | * |
||
228 | * @return bool |
||
229 | */ |
||
230 | 7 | private function checkPair(string $key, array $valueAndLocale): bool |
|
231 | { |
||
232 | 7 | $result = strlen($key) > 0 && $this->checkValueWithLocale($valueAndLocale) === true; |
|
233 | |||
234 | 7 | return $result; |
|
235 | } |
||
236 | |||
237 | /** |
||
238 | * @param array $valueAndLocale |
||
239 | * |
||
240 | * @return bool |
||
241 | */ |
||
242 | 7 | private function checkValueWithLocale(array $valueAndLocale): bool |
|
243 | { |
||
244 | $result = |
||
245 | 7 | count($valueAndLocale) === 2 && |
|
246 | 7 | empty($valueAndLocale[static::INDEX_PAIR_VALUE]) === false && |
|
247 | 7 | empty($valueAndLocale[static::INDEX_PAIR_LOCALE]) === false; |
|
248 | |||
249 | 7 | return $result; |
|
250 | } |
||
251 | } |
||
252 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..