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.
1 | <?php |
||||
2 | |||||
3 | /** |
||||
4 | * Console GetoptPlus/Help |
||||
5 | * |
||||
6 | * |
||||
7 | * All rights reserved. |
||||
8 | * Redistribution and use in source and binary forms, with or without modification, |
||||
9 | * are permitted provided that the following conditions are met: |
||||
10 | * + Redistributions of source code must retain the above copyright notice, |
||||
11 | * this list of conditions and the following disclaimer. |
||||
12 | * + Redistributions in binary form must reproduce the above copyright notice, |
||||
13 | * this list of conditions and the following disclaimer in the documentation and/or |
||||
14 | * other materials provided with the distribution. |
||||
15 | * + The names of its contributors may not be used to endorse or promote |
||||
16 | * products derived from this software without specific prior written permission. |
||||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
20 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
21 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
23 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
25 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
28 | * |
||||
29 | * @category Console |
||||
30 | * @package Console_GetoptPlus |
||||
31 | * @author Michel Corne <[email protected]> |
||||
32 | * @copyright 2008 Michel Corne |
||||
33 | * @license http://www.opensource.org/licenses/bsd-license.php The BSD License |
||||
34 | * @version SVN: $Id: Help.php 47 2008-01-10 11:03:38Z mcorne $ |
||||
35 | * @link http://pear.php.net/package/Console_GetoptPlus |
||||
36 | */ |
||||
37 | |||||
38 | /** |
||||
39 | * Generation of the command usage/help |
||||
40 | * |
||||
41 | * @category Console |
||||
42 | * @package Console_GetoptPlus |
||||
43 | * @author Michel Corne <[email protected]> |
||||
44 | * @copyright 2008 Michel Corne |
||||
45 | * @license http://www.opensource.org/licenses/bsd-license.php The BSD License |
||||
46 | * @version Release:@package_version@ |
||||
47 | * @link http://pear.php.net/package/Console_GetoptPlus |
||||
48 | */ |
||||
49 | class Console_GetoptPlus_Help |
||||
50 | { |
||||
51 | /** |
||||
52 | * The option name padding within the option descrition |
||||
53 | */ |
||||
54 | const optionPadding = 30; |
||||
55 | /** |
||||
56 | * The options section title |
||||
57 | */ |
||||
58 | const options = 'Options:'; |
||||
59 | /** |
||||
60 | * The parameter section title |
||||
61 | */ |
||||
62 | const parameters = 'Parameters:'; |
||||
63 | /** |
||||
64 | * The usage section title |
||||
65 | */ |
||||
66 | const usage = 'Usage: '; |
||||
67 | |||||
68 | /** |
||||
69 | * Aligns a set of lines |
||||
70 | * |
||||
71 | * Additional data is added to the first line. |
||||
72 | * The other lines are padded and aligned to the first one. |
||||
73 | * |
||||
74 | * @param array $lines the set of lines |
||||
75 | * @param string $addon the additional data to add to the first line |
||||
76 | * @param int $paddingLength the padding length |
||||
77 | * @return array the aligned lines |
||||
78 | * @access public |
||||
79 | */ |
||||
80 | public function alignLines($lines, $addon = '', $paddingLength = null) |
||||
81 | { |
||||
82 | $lines = (array)$lines; |
||||
83 | $addon = (string)$addon; |
||||
84 | // defaults the left alignment to the length of the additional data + 1 |
||||
85 | null === $paddingLength and $paddingLength = $addon ? (mb_strlen($addon) + 1) : 0; |
||||
86 | // extracts the first line |
||||
87 | $firstLine = (string)current($lines); |
||||
88 | $firstLineEmpty = '' == $firstLine; |
||||
89 | |||||
90 | if (!$addon or $firstLineEmpty or $paddingLength > mb_strlen($addon)) { |
||||
91 | // no addon or padding larger than addon |
||||
92 | // pads the additional data and adds it to the left of the first line |
||||
93 | $addon = str_pad($addon, $paddingLength); |
||||
94 | $firstLine = $addon . array_shift($lines); |
||||
95 | } else { |
||||
96 | // the information on the left is longer than the padding size |
||||
97 | $firstLine = $addon; |
||||
98 | } |
||||
99 | // left-pads the other lines |
||||
100 | $padding = str_repeat(' ', $paddingLength); |
||||
101 | $callback = create_function('$string', "return '$padding' . \$string;"); |
||||
102 | $lines = array_map($callback, $lines); |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
103 | // prepends the first line |
||||
104 | $firstLine = rtrim($firstLine); |
||||
105 | array_unshift($lines, $firstLine); |
||||
106 | |||||
107 | return $lines; |
||||
108 | } |
||||
109 | |||||
110 | /** |
||||
111 | * @param $config |
||||
112 | * @param $command |
||||
113 | * @return string |
||||
114 | */ |
||||
115 | public static function get($config, $command) |
||||
116 | { |
||||
117 | $help = new self(); |
||||
118 | |||||
119 | return $help->set($config, $command); |
||||
120 | } |
||||
121 | |||||
122 | /** |
||||
123 | * Creates the help/usage text |
||||
124 | * |
||||
125 | * @param array $config the command configuration |
||||
126 | * @param string $command the command name |
||||
127 | * @return string the help/usage text |
||||
128 | * @access public |
||||
129 | */ |
||||
130 | public function set($config, $command) |
||||
131 | { |
||||
132 | // sets all the help/usage section texts |
||||
133 | $help = []; |
||||
134 | isset($config['header']) and $help[] = $this->tidyArray($config['header']); |
||||
135 | $help[] = $this->setUsage($config, $command); |
||||
136 | isset($config['options']) and $help[] = $this->setOptions($config['options']); |
||||
137 | isset($config['parameters']) and $help[] = $this->alignLines($config['parameters'], self::parameters); |
||||
138 | isset($config['footer']) and $help[] = $this->tidyArray($config['footer']); |
||||
139 | // merges the section texts together |
||||
140 | $callback = create_function('$array, $array1', '$array or $array = []; return array_merge($array, $array1);'); |
||||
141 | $help = array_reduce($help, $callback, []); |
||||
0 ignored issues
–
show
It seems like
$callback can also be of type true ; however, parameter $callback of array_reduce() does only seem to accept callable , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
142 | |||||
143 | return implode("\n", $help); |
||||
144 | } |
||||
145 | |||||
146 | /** |
||||
147 | * Creates the options help text section |
||||
148 | * |
||||
149 | * @param array $optionsConfig the options descriptions |
||||
150 | * @return array the options help text section |
||||
151 | * @access public |
||||
152 | */ |
||||
153 | public function setOptions($optionsConfig) |
||||
154 | { |
||||
155 | $optionsConfig = (array)$optionsConfig; |
||||
156 | |||||
157 | $padding = str_repeat(' ', self::optionPadding); |
||||
158 | $callback = create_function('$string', "return '$padding' . \$string;"); |
||||
0 ignored issues
–
show
|
|||||
159 | |||||
160 | $lines = []; |
||||
161 | foreach ($optionsConfig as $option) { |
||||
162 | $desc = $option['desc'] ?? ''; |
||||
163 | $desc = (array)$desc; |
||||
164 | // extracts the option example value from the description |
||||
165 | // encloses with angle/square brackets if mandatory/optional |
||||
166 | $value = ''; |
||||
167 | empty($option['type']) or 'mandatory' == $option['type'] and $value = '<' . array_shift($desc) . '>' or 'optional' == $option['type'] and $value = '[' . array_shift($desc) . ']'; |
||||
168 | // sets the option names |
||||
169 | $optionNames = []; |
||||
170 | isset($option['short']) and $optionNames[] = "-{$option['short']}"; |
||||
171 | isset($option['long']) and $optionNames[] = "--{$option['long']}"; |
||||
172 | $value and $optionNames[] = $value; |
||||
173 | $optionNames = implode(' ', $optionNames); |
||||
174 | // adds the option names to the description |
||||
175 | $desc = $this->alignLines($desc, $optionNames, self::optionPadding); |
||||
176 | $lines = array_merge($lines, $desc); |
||||
177 | } |
||||
178 | // prefix the options with e.g. "Options:" |
||||
179 | $lines and array_unshift($lines, self::options); |
||||
180 | |||||
181 | return $lines; |
||||
182 | } |
||||
183 | |||||
184 | /** |
||||
185 | * Creates the usage help text section |
||||
186 | * |
||||
187 | * @param $config |
||||
188 | * @param string $command the command name |
||||
189 | * @return array the usage help text section |
||||
190 | * @access public |
||||
191 | */ |
||||
192 | public function setUsage($config, $command) |
||||
193 | { |
||||
194 | if (empty($config['usage'])) { |
||||
195 | // usage is empty, defaults to a one line usage, |
||||
196 | // e.g. [options] [parameters] |
||||
197 | $usage = []; |
||||
198 | empty($config['options']) or $usage[] = '[options]'; |
||||
199 | empty($config['parameters']) or $usage[] = '[parameters]'; |
||||
200 | $config['usage'] = implode(' ', $usage); |
||||
201 | } |
||||
202 | // expecting an array of arrays of usage lines, |
||||
203 | // or possibly a single usage line |
||||
204 | $config['usage'] = (array)$config['usage']; |
||||
205 | $lines = []; |
||||
206 | $padding = str_repeat(' ', mb_strlen(self::usage)); |
||||
207 | |||||
208 | foreach ($config['usage'] as $idx => $usage) { |
||||
209 | $usage = $this->tidyArray($usage); |
||||
210 | // adds the usage keywork to the first usage, e.g. "Usage:" |
||||
211 | $prefix = $idx ? $padding : self::usage; |
||||
212 | // adds the command to each usage, e.g. command [options] [parameters] |
||||
213 | $prefix .= basename($command); |
||||
214 | $usage = $this->alignLines($usage, $prefix); |
||||
215 | $lines = array_merge($lines, $usage); |
||||
216 | } |
||||
217 | |||||
218 | return $lines; |
||||
219 | } |
||||
220 | |||||
221 | /** |
||||
222 | * Tidies an array |
||||
223 | * |
||||
224 | * Makes an array if passed as a string. |
||||
225 | * Optionally forces the values to strings if there are not. |
||||
226 | * |
||||
227 | * @param array $array the array |
||||
228 | * @param bool $tidyString forces the values to string if true, |
||||
229 | * or leaves them untouched if false |
||||
230 | * @return array the tidied array |
||||
231 | * @access public |
||||
232 | */ |
||||
233 | public function tidyArray($array, $tidyString = true) |
||||
234 | { |
||||
235 | $array = (array)$array; |
||||
236 | // tidies the array string values |
||||
237 | $tidyString and $array = array_map([$this, 'tidyString'], $array); |
||||
238 | |||||
239 | return $array; |
||||
240 | } |
||||
241 | |||||
242 | /** |
||||
243 | * Tidies a string |
||||
244 | * |
||||
245 | * Retains only the first value if passed as an array. |
||||
246 | * |
||||
247 | * @param string $string the string |
||||
248 | * @return string the tidy string |
||||
249 | * @access public |
||||
250 | */ |
||||
251 | public function tidyString($string) |
||||
252 | { |
||||
253 | // if an array: captures the first value and converts it to a string |
||||
254 | // silently ignores the other values |
||||
255 | is_array($string) and $string = current($string); |
||||
256 | |||||
257 | return trim($string); |
||||
258 | } |
||||
259 | } |
||||
260 |