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 | /** |
||
4 | * GitElephant - An abstraction layer for git written in PHP |
||
5 | * Copyright (C) 2013 Matteo Giachino |
||
6 | * |
||
7 | * This program is free software: you can redistribute it and/or modify |
||
8 | * it under the terms of the GNU General Public License as published by |
||
9 | * the Free Software Foundation, either version 3 of the License, or |
||
10 | * (at your option) any later version. |
||
11 | * |
||
12 | * This program is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | * GNU General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU General Public License |
||
18 | * along with this program. If not, see [http://www.gnu.org/licenses/]. |
||
19 | */ |
||
20 | |||
21 | namespace GitElephant\Command; |
||
22 | |||
23 | use GitElephant\Objects\Author; |
||
24 | use GitElephant\Objects\Branch; |
||
25 | use GitElephant\Objects\TreeishInterface; |
||
26 | use GitElephant\Repository; |
||
27 | |||
28 | /** |
||
29 | * Main command generator (init, status, add, commit, checkout) |
||
30 | * |
||
31 | * @author Matteo Giachino <[email protected]> |
||
32 | */ |
||
33 | class MainCommand extends BaseCommand |
||
34 | { |
||
35 | public const GIT_INIT = 'init'; |
||
36 | public const GIT_STATUS = 'status'; |
||
37 | public const GIT_ADD = 'add'; |
||
38 | public const GIT_COMMIT = 'commit'; |
||
39 | public const GIT_CHECKOUT = 'checkout'; |
||
40 | public const GIT_MOVE = 'mv'; |
||
41 | public const GIT_REMOVE = 'rm'; |
||
42 | public const GIT_RESET = 'reset'; |
||
43 | |||
44 | /** |
||
45 | * constructor |
||
46 | * |
||
47 | * @param \GitElephant\Repository $repo The repository object this command |
||
48 | * will interact with |
||
49 | */ |
||
50 | 105 | public function __construct(Repository $repo = null) |
|
51 | { |
||
52 | 105 | parent::__construct($repo); |
|
53 | 105 | } |
|
54 | |||
55 | /** |
||
56 | * Init the repository |
||
57 | * |
||
58 | * @param bool $bare |
||
59 | * |
||
60 | * @throws \RuntimeException |
||
61 | * @return string |
||
62 | */ |
||
63 | 100 | public function init($bare = false): string |
|
64 | { |
||
65 | 100 | $this->clearAll(); |
|
66 | 100 | if ($bare) { |
|
67 | 5 | $this->addCommandArgument('--bare'); |
|
68 | } |
||
69 | 100 | $this->addCommandName(self::GIT_INIT); |
|
70 | |||
71 | 100 | return $this->getCommand(); |
|
72 | } |
||
73 | |||
74 | /** |
||
75 | * Get the repository status |
||
76 | * |
||
77 | * @param bool $porcelain |
||
78 | * |
||
79 | * @throws \RuntimeException |
||
80 | * @return string |
||
81 | */ |
||
82 | 13 | public function status($porcelain = false): string |
|
83 | { |
||
84 | 13 | $this->clearAll(); |
|
85 | 13 | $this->addCommandName(self::GIT_STATUS); |
|
86 | 13 | if ($porcelain) { |
|
87 | 10 | $this->addCommandArgument('--porcelain'); |
|
88 | } else { |
||
89 | 3 | $this->addConfigs(['color.status' => 'false']); |
|
90 | } |
||
91 | |||
92 | 13 | return $this->getCommand(); |
|
93 | } |
||
94 | |||
95 | /** |
||
96 | * Add a node to the stage |
||
97 | * |
||
98 | * @param string $what what should be added to the repository |
||
99 | * |
||
100 | * @throws \RuntimeException |
||
101 | * @return string |
||
102 | */ |
||
103 | 95 | public function add($what = '.'): string |
|
104 | { |
||
105 | 95 | $this->clearAll(); |
|
106 | 95 | $this->addCommandName(self::GIT_ADD); |
|
107 | 95 | $this->addCommandArgument('--all'); |
|
108 | 95 | $this->addCommandSubject($what); |
|
109 | |||
110 | 95 | return $this->getCommand(); |
|
111 | } |
||
112 | |||
113 | /** |
||
114 | * Remove a node from the stage and put in the working tree |
||
115 | * |
||
116 | * @param string $what what should be removed from the stage |
||
117 | * |
||
118 | * @throws \RuntimeException |
||
119 | * @return string |
||
120 | */ |
||
121 | 2 | public function unstage($what): string |
|
122 | { |
||
123 | 2 | $this->clearAll(); |
|
124 | 2 | $this->addCommandName(self::GIT_RESET); |
|
125 | 2 | $this->addCommandArgument('HEAD'); |
|
126 | 2 | $this->addPath($what); |
|
127 | |||
128 | 2 | return $this->getCommand(); |
|
129 | } |
||
130 | |||
131 | /** |
||
132 | * Commit |
||
133 | * |
||
134 | * @param string|null $message the commit message |
||
135 | * @param bool $stageAll commit all changes |
||
136 | * @param string|Author $author override the author for this commit |
||
137 | * @param bool $allowEmpty whether to add param `--allow-empty` to commit command |
||
138 | * @param \DateTimeInterface|null $date |
||
139 | * |
||
140 | * @throws \RuntimeException |
||
141 | * @throws \InvalidArgumentException |
||
142 | * @return string |
||
143 | */ |
||
144 | 95 | public function commit( |
|
145 | ?string $message, |
||
146 | bool $stageAll = false, |
||
147 | $author = null, |
||
148 | bool $allowEmpty = false, |
||
149 | \DateTimeInterface $date = null |
||
150 | ): string { |
||
151 | 95 | $this->clearAll(); |
|
152 | |||
153 | 95 | if (trim($message) === '' || is_null($message)) { |
|
154 | throw new \InvalidArgumentException(sprintf('You can\'t commit without message')); |
||
155 | } |
||
156 | 95 | $this->addCommandName(self::GIT_COMMIT); |
|
157 | |||
158 | 95 | if ($stageAll) { |
|
159 | 89 | $this->addCommandArgument('-a'); |
|
160 | } |
||
161 | |||
162 | 95 | if ($author !== null) { |
|
163 | 1 | $this->addCommandArgument('--author'); |
|
164 | 1 | $this->addCommandArgument($author); |
|
0 ignored issues
–
show
|
|||
165 | } |
||
166 | |||
167 | 95 | if ($allowEmpty) { |
|
168 | 1 | $this->addCommandArgument('--allow-empty'); |
|
169 | } |
||
170 | |||
171 | 95 | if (null !== $date) { |
|
172 | $this->addCommandArgument('--date'); |
||
173 | $this->addCommandArgument($date->format(\DateTimeInterface::RFC822)); |
||
174 | } |
||
175 | |||
176 | 95 | $this->addCommandArgument('-m'); |
|
177 | 95 | $this->addCommandSubject($message); |
|
178 | |||
179 | 95 | return $this->getCommand(); |
|
180 | } |
||
181 | |||
182 | /** |
||
183 | * Checkout a treeish reference |
||
184 | * |
||
185 | * @param string|Branch|TreeishInterface $ref the reference to checkout |
||
186 | * |
||
187 | * @throws \RuntimeException |
||
188 | * @return string |
||
189 | */ |
||
190 | 23 | public function checkout($ref): string |
|
191 | { |
||
192 | 23 | $this->clearAll(); |
|
193 | |||
194 | 23 | $what = $ref; |
|
195 | 23 | if ($ref instanceof Branch) { |
|
196 | 2 | $what = $ref->getName(); |
|
197 | 22 | } elseif ($ref instanceof TreeishInterface) { |
|
198 | $what = $ref->getSha(); |
||
199 | } |
||
200 | |||
201 | 23 | $this->addCommandName(self::GIT_CHECKOUT); |
|
202 | 23 | $this->addCommandArgument('-q'); |
|
203 | 23 | $this->addCommandSubject($what); |
|
204 | |||
205 | 23 | return $this->getCommand(); |
|
206 | } |
||
207 | |||
208 | /** |
||
209 | * Move a file/directory |
||
210 | * |
||
211 | * @param string|Object $from source path |
||
212 | * @param string|Object $to destination path |
||
213 | * |
||
214 | * @throws \RuntimeException |
||
215 | * @throws \InvalidArgumentException |
||
216 | * @return string |
||
217 | */ |
||
218 | 1 | public function move($from, $to): string |
|
219 | { |
||
220 | 1 | $this->clearAll(); |
|
221 | |||
222 | 1 | $from = trim($from); |
|
223 | 1 | if (!$this->validatePath($from)) { |
|
224 | throw new \InvalidArgumentException('Invalid source path'); |
||
225 | } |
||
226 | |||
227 | 1 | $to = trim($to); |
|
228 | 1 | if (!$this->validatePath($to)) { |
|
229 | throw new \InvalidArgumentException('Invalid destination path'); |
||
230 | } |
||
231 | |||
232 | 1 | $this->addCommandName(self::GIT_MOVE); |
|
233 | 1 | $this->addCommandSubject($from); |
|
234 | 1 | $this->addCommandSubject2($to); |
|
235 | |||
236 | 1 | return $this->getCommand(); |
|
237 | } |
||
238 | |||
239 | /** |
||
240 | * Remove a file/directory |
||
241 | * |
||
242 | * @param string|Object $path the path to remove |
||
243 | * @param bool $recursive recurse |
||
244 | * @param bool $force force |
||
245 | * |
||
246 | * @throws \RuntimeException |
||
247 | * @throws \InvalidArgumentException |
||
248 | * @return string |
||
249 | */ |
||
250 | 1 | public function remove($path, $recursive, $force): string |
|
251 | { |
||
252 | 1 | $this->clearAll(); |
|
253 | |||
254 | 1 | $path = trim($path); |
|
255 | 1 | if (!$this->validatePath($path)) { |
|
256 | throw new \InvalidArgumentException('Invalid path'); |
||
257 | } |
||
258 | |||
259 | 1 | $this->addCommandName(self::GIT_REMOVE); |
|
260 | |||
261 | 1 | if ($recursive) { |
|
262 | $this->addCommandArgument('-r'); |
||
263 | } |
||
264 | |||
265 | 1 | if ($force) { |
|
266 | $this->addCommandArgument('-f'); |
||
267 | } |
||
268 | |||
269 | 1 | $this->addPath($path); |
|
270 | |||
271 | 1 | return $this->getCommand(); |
|
272 | } |
||
273 | |||
274 | /** |
||
275 | * Validates a path |
||
276 | * |
||
277 | * @param string $path path |
||
278 | * |
||
279 | * @return bool |
||
280 | */ |
||
281 | 2 | protected function validatePath($path): bool |
|
282 | { |
||
283 | 2 | if (empty($path)) { |
|
284 | return false; |
||
285 | } |
||
286 | |||
287 | // we are always operating from root directory |
||
288 | // so forbid relative paths |
||
289 | 2 | if (false !== strpos($path, '..')) { |
|
290 | return false; |
||
291 | } |
||
292 | |||
293 | 2 | return true; |
|
294 | } |
||
295 | } |
||
296 |
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.