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; |
||
0 ignored issues
–
show
|
|||
160 | |||
161 | 5 | case $this->checkFlag(self::ARRAY_MODE_CONCAT): |
|
0 ignored issues
–
show
case $this->checkFlag(se...', $value)); 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 ![]() |
|||
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; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
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; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
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 |
The break statement is not necessary if it is preceded for example by a return statement:
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.