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 |
||
2 | |||
3 | namespace Indigo\Ini; |
||
4 | |||
5 | use Indigo\Ini\Exception\RendererException; |
||
6 | |||
7 | /** |
||
8 | * Renders an INI array. |
||
9 | * |
||
10 | * @author Márk Sági-Kazár <[email protected]> |
||
11 | */ |
||
12 | class Renderer |
||
13 | { |
||
14 | /** |
||
15 | * Constants determining how the library should handle array values. |
||
16 | */ |
||
17 | const ARRAY_MODE_ARRAY = 1; |
||
18 | const ARRAY_MODE_CONCAT = 2; |
||
19 | |||
20 | /** |
||
21 | * Constants determining how the library should handle boolean values. |
||
22 | */ |
||
23 | const BOOLEAN_MODE_INTEGER = 4; |
||
24 | const BOOLEAN_MODE_BOOL_STRING = 8; |
||
25 | const BOOLEAN_MODE_STRING = 16; |
||
26 | |||
27 | const STRING_MODE_QUOTE = 32; |
||
28 | |||
29 | /** |
||
30 | * @var int |
||
31 | */ |
||
32 | protected $flags = 5; |
||
33 | |||
34 | /** |
||
35 | * @param int $flags |
||
36 | */ |
||
37 | 19 | public function __construct($flags = 5) |
|
38 | { |
||
39 | 19 | $this->flags = $flags; |
|
40 | 19 | } |
|
41 | |||
42 | /** |
||
43 | * Renders an INI configuration. |
||
44 | * |
||
45 | * @param array $ini |
||
46 | * |
||
47 | * @return string |
||
48 | */ |
||
49 | 18 | public function render(array $ini) |
|
50 | { |
||
51 | 18 | $output = []; |
|
52 | |||
53 | 18 | foreach ($ini as $sectionName => $section) { |
|
54 | 18 | $sectionOutput = []; |
|
55 | |||
56 | 18 | if (!is_array($section)) { |
|
57 | 1 | throw new RendererException('The section must contain an array of key-value pairs'); |
|
58 | } |
||
59 | |||
60 | // Values without keys are stored in this temporary array |
||
61 | 17 | $sectionIni = []; |
|
62 | |||
63 | 17 | foreach ($section as $key => $value) { |
|
64 | 17 | if (is_numeric($key)) { |
|
65 | 1 | if (!is_array($value)) { |
|
66 | 1 | $value = [$value]; |
|
67 | 1 | } |
|
68 | |||
69 | 1 | $sectionIni = array_merge($sectionIni, $value); |
|
70 | 1 | continue; |
|
71 | } |
||
72 | |||
73 | 17 | $sectionOutput = array_merge($sectionOutput, $this->renderKeyValuePair($key, $value)); |
|
74 | 16 | } |
|
75 | |||
76 | 16 | if (count($sectionIni) > 0) { |
|
77 | 1 | $sectionOutput = array_merge($this->renderKeyValuePair($sectionName, $sectionIni), $sectionOutput); |
|
78 | 1 | } |
|
79 | |||
80 | 16 | array_unshift($sectionOutput, sprintf('[%s]', $sectionName)); |
|
81 | |||
82 | // Write a linefeed after sections |
||
83 | 16 | $sectionOutput[] = ''; |
|
84 | |||
85 | 16 | $output = array_merge($output, $sectionOutput); |
|
86 | 16 | } |
|
87 | |||
88 | 16 | return implode("\n", $output); |
|
89 | } |
||
90 | |||
91 | /** |
||
92 | * Renders a key-value pair. |
||
93 | * |
||
94 | * @param string $key |
||
95 | * @param mixed $value |
||
96 | * |
||
97 | * @return array |
||
98 | */ |
||
99 | 17 | protected function renderKeyValuePair($key, $value) |
|
100 | { |
||
101 | 17 | $output = []; |
|
102 | 17 | $value = $this->normalizeValue($value); |
|
103 | |||
104 | 16 | if (is_array($value)) { |
|
105 | 3 | foreach ($value as $v) { |
|
106 | 3 | $output[] = sprintf('%s[] = %s', $key, $v); |
|
107 | 3 | } |
|
108 | 3 | } else { |
|
109 | 15 | $output[] = sprintf('%s = %s', $key, $value); |
|
110 | } |
||
111 | |||
112 | 16 | return $output; |
|
113 | } |
||
114 | |||
115 | /** |
||
116 | * Normalize value to valid INI format. |
||
117 | * |
||
118 | * @param mixed $value |
||
119 | * |
||
120 | * @return string |
||
121 | */ |
||
122 | 17 | protected function normalizeValue($value) |
|
123 | { |
||
124 | 17 | if (is_array($value)) { |
|
125 | 9 | $value = $this->normalizeArray($value); |
|
126 | 16 | } elseif (is_bool($value)) { |
|
127 | 4 | $value = $this->normalizeBoolean($value); |
|
128 | 16 | } elseif (is_null($value)) { |
|
129 | 1 | $value = 'null'; |
|
130 | 12 | } elseif (is_string($value) && $this->checkFlag(self::STRING_MODE_QUOTE)) { |
|
131 | 1 | $value = sprintf('"%s"', $value); |
|
132 | 1 | } |
|
133 | |||
134 | 16 | return $value; |
|
135 | } |
||
136 | |||
137 | /** |
||
138 | * Normalizes arrays. |
||
139 | * |
||
140 | * @param array $value |
||
141 | * |
||
142 | * @return array|string |
||
143 | */ |
||
144 | 9 | protected function normalizeArray($value) |
|
145 | { |
||
146 | 9 | switch (true) { |
|
147 | 9 | case $this->checkFlag(self::ARRAY_MODE_ARRAY): |
|
148 | 9 | default: |
|
149 | 4 | foreach ($value as &$v) { |
|
150 | 4 | if (is_array($v)) { |
|
151 | 1 | throw new RendererException('Multi-dimensional arrays are not supported by this array mode'); |
|
152 | } |
||
153 | |||
154 | 3 | $v = $this->normalizeValue($v); |
|
155 | 3 | } |
|
156 | |||
157 | 3 | return $value; |
|
158 | |||
159 | break; |
||
160 | |||
161 | 5 | case $this->checkFlag(self::ARRAY_MODE_CONCAT): |
|
0 ignored issues
–
show
|
|||
162 | 5 | foreach ($value as &$v) { |
|
163 | 5 | $v = trim($this->normalizeValue($v), '"'); // We don't want string normalization here |
|
164 | 5 | } |
|
165 | |||
166 | 5 | return $this->normalizeValue(implode(',', $value)); |
|
167 | |||
168 | break; |
||
169 | } |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * Normalizes a boolean value. |
||
174 | * |
||
175 | * @param bool $value |
||
176 | * |
||
177 | * @return int|string |
||
178 | */ |
||
179 | 4 | protected function normalizeBoolean($value) |
|
180 | { |
||
181 | 4 | switch (true) { |
|
182 | 4 | case $this->checkFlag(self::BOOLEAN_MODE_INTEGER): |
|
183 | 4 | default: |
|
184 | 2 | return (int) $value; |
|
185 | |||
186 | break; |
||
187 | |||
188 | 2 | case $this->checkFlag(self::BOOLEAN_MODE_BOOL_STRING): |
|
0 ignored issues
–
show
case $this->checkFlag(se...' : 'false'; break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
189 | 1 | return $value === true ? 'true' : 'false'; |
|
190 | |||
191 | break; |
||
192 | |||
193 | 1 | case $this->checkFlag(self::BOOLEAN_MODE_STRING): |
|
194 | 1 | return $value === true ? 'On' : 'Off'; |
|
195 | |||
196 | break; |
||
197 | } |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Checks if a flag is active. |
||
202 | * |
||
203 | * @param int $flag |
||
204 | * |
||
205 | * @return bool |
||
206 | */ |
||
207 | 15 | private function checkFlag($flag) |
|
208 | { |
||
209 | 15 | return (bool) ($this->flags & $flag); |
|
210 | } |
||
211 | } |
||
212 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.