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 dokuwiki; |
||
4 | |||
5 | use dokuwiki\Ui; |
||
6 | use dokuwiki\Utf8\Sort; |
||
7 | |||
8 | /** |
||
9 | * Manage all builtin AJAX calls |
||
10 | * |
||
11 | * @todo The calls should be refactored out to their own proper classes |
||
12 | * @package dokuwiki |
||
13 | */ |
||
14 | class Ajax { |
||
15 | |||
16 | /** |
||
17 | * Execute the given call |
||
18 | * |
||
19 | * @param string $call name of the ajax call |
||
20 | */ |
||
21 | public function __construct($call) { |
||
22 | $callfn = 'call' . ucfirst($call); |
||
23 | if(method_exists($this, $callfn)) { |
||
24 | $this->$callfn(); |
||
25 | } else { |
||
26 | $evt = new Extension\Event('AJAX_CALL_UNKNOWN', $call); |
||
27 | if($evt->advise_before()) { |
||
28 | print "AJAX call '" . hsc($call) . "' unknown!\n"; |
||
29 | } else { |
||
30 | $evt->advise_after(); |
||
31 | unset($evt); |
||
32 | } |
||
33 | } |
||
34 | } |
||
35 | |||
36 | /** |
||
37 | * Searches for matching pagenames |
||
38 | * |
||
39 | * @author Andreas Gohr <[email protected]> |
||
40 | */ |
||
41 | protected function callQsearch() { |
||
42 | global $lang; |
||
43 | global $INPUT; |
||
44 | |||
45 | $maxnumbersuggestions = 50; |
||
46 | |||
47 | $query = $INPUT->post->str('q'); |
||
48 | if(empty($query)) $query = $INPUT->get->str('q'); |
||
49 | if(empty($query)) return; |
||
50 | |||
51 | $query = urldecode($query); |
||
52 | |||
53 | $data = ft_pageLookup($query, true, useHeading('navigation')); |
||
54 | |||
55 | if(!count($data)) return; |
||
56 | |||
57 | print '<strong>' . $lang['quickhits'] . '</strong>'; |
||
58 | print '<ul>'; |
||
59 | $counter = 0; |
||
60 | foreach($data as $id => $title) { |
||
61 | if(useHeading('navigation')) { |
||
62 | $name = $title; |
||
63 | } else { |
||
64 | $ns = getNS($id); |
||
65 | if($ns) { |
||
0 ignored issues
–
show
|
|||
66 | $name = noNS($id) . ' (' . $ns . ')'; |
||
67 | } else { |
||
68 | $name = $id; |
||
69 | } |
||
70 | } |
||
71 | echo '<li>' . html_wikilink(':' . $id, $name) . '</li>'; |
||
72 | |||
73 | $counter++; |
||
74 | if($counter > $maxnumbersuggestions) { |
||
75 | echo '<li>...</li>'; |
||
76 | break; |
||
77 | } |
||
78 | } |
||
79 | print '</ul>'; |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * Support OpenSearch suggestions |
||
84 | * |
||
85 | * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0 |
||
86 | * @author Mike Frysinger <[email protected]> |
||
87 | */ |
||
88 | protected function callSuggestions() { |
||
89 | global $INPUT; |
||
90 | |||
91 | $query = cleanID($INPUT->post->str('q')); |
||
92 | if(empty($query)) $query = cleanID($INPUT->get->str('q')); |
||
93 | if(empty($query)) return; |
||
94 | |||
95 | $data = ft_pageLookup($query); |
||
96 | if(!count($data)) return; |
||
97 | $data = array_keys($data); |
||
98 | |||
99 | // limit results to 15 hits |
||
100 | $data = array_slice($data, 0, 15); |
||
101 | $data = array_map('trim', $data); |
||
102 | $data = array_map('noNS', $data); |
||
103 | $data = array_unique($data); |
||
104 | Sort::sort($data); |
||
105 | |||
106 | /* now construct a json */ |
||
107 | $suggestions = array( |
||
108 | $query, // the original query |
||
109 | $data, // some suggestions |
||
110 | array(), // no description |
||
111 | array() // no urls |
||
112 | ); |
||
113 | |||
114 | header('Content-Type: application/x-suggestions+json'); |
||
115 | print json_encode($suggestions); |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Refresh a page lock and save draft |
||
120 | * |
||
121 | * Andreas Gohr <[email protected]> |
||
122 | */ |
||
123 | protected function callLock() { |
||
124 | global $ID; |
||
125 | global $INFO; |
||
126 | global $INPUT; |
||
127 | |||
128 | $ID = cleanID($INPUT->post->str('id')); |
||
129 | if(empty($ID)) return; |
||
130 | |||
131 | $INFO = pageinfo(); |
||
132 | |||
133 | $response = [ |
||
134 | 'errors' => [], |
||
135 | 'lock' => '0', |
||
136 | 'draft' => '', |
||
137 | ]; |
||
138 | if(!$INFO['writable']) { |
||
139 | $response['errors'][] = 'Permission to write this page has been denied.'; |
||
140 | echo json_encode($response); |
||
141 | return; |
||
142 | } |
||
143 | |||
144 | if(!checklock($ID)) { |
||
145 | lock($ID); |
||
146 | $response['lock'] = '1'; |
||
147 | } |
||
148 | |||
149 | $draft = new Draft($ID, $INFO['client']); |
||
150 | if ($draft->saveDraft()) { |
||
151 | $response['draft'] = $draft->getDraftMessage(); |
||
152 | } else { |
||
153 | $response['errors'] = array_merge($response['errors'], $draft->getErrors()); |
||
154 | } |
||
155 | echo json_encode($response); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * Delete a draft |
||
160 | * |
||
161 | * @author Andreas Gohr <[email protected]> |
||
162 | */ |
||
163 | protected function callDraftdel() { |
||
164 | global $INPUT; |
||
165 | $id = cleanID($INPUT->str('id')); |
||
166 | if(empty($id)) return; |
||
167 | |||
168 | $client = $_SERVER['REMOTE_USER']; |
||
169 | if(!$client) $client = clientIP(true); |
||
170 | |||
171 | $cname = getCacheName($client . $id, '.draft'); |
||
172 | @unlink($cname); |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * Return subnamespaces for the Mediamanager |
||
177 | * |
||
178 | * @author Andreas Gohr <[email protected]> |
||
179 | */ |
||
180 | protected function callMedians() { |
||
181 | global $conf; |
||
182 | global $INPUT; |
||
183 | |||
184 | // wanted namespace |
||
185 | $ns = cleanID($INPUT->post->str('ns')); |
||
186 | $dir = utf8_encodeFN(str_replace(':', '/', $ns)); |
||
187 | |||
188 | $lvl = count(explode(':', $ns)); |
||
189 | |||
190 | $data = array(); |
||
191 | search($data, $conf['mediadir'], 'search_index', array('nofiles' => true), $dir); |
||
192 | foreach(array_keys($data) as $item) { |
||
193 | $data[$item]['level'] = $lvl + 1; |
||
194 | } |
||
195 | echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li'); |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * Return list of files for the Mediamanager |
||
200 | * |
||
201 | * @author Andreas Gohr <[email protected]> |
||
202 | */ |
||
203 | protected function callMedialist() { |
||
204 | global $NS; |
||
205 | global $INPUT; |
||
206 | |||
207 | $NS = cleanID($INPUT->post->str('ns')); |
||
208 | $sort = $INPUT->post->bool('recent') ? 'date' : 'natural'; |
||
209 | if($INPUT->post->str('do') == 'media') { |
||
210 | tpl_mediaFileList(); |
||
211 | } else { |
||
212 | tpl_mediaContent(true, $sort); |
||
213 | } |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * Return the content of the right column |
||
218 | * (image details) for the Mediamanager |
||
219 | * |
||
220 | * @author Kate Arzamastseva <[email protected]> |
||
221 | */ |
||
222 | protected function callMediadetails() { |
||
223 | global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT; |
||
224 | $fullscreen = true; |
||
225 | require_once(DOKU_INC . 'lib/exe/mediamanager.php'); |
||
226 | |||
227 | $image = ''; |
||
228 | if($INPUT->has('image')) $image = cleanID($INPUT->str('image')); |
||
229 | if(isset($IMG)) $image = $IMG; |
||
230 | if(isset($JUMPTO)) $image = $JUMPTO; |
||
231 | $rev = false; |
||
232 | if(isset($REV) && !$JUMPTO) $rev = $REV; |
||
233 | |||
234 | html_msgarea(); |
||
235 | tpl_mediaFileDetails($image, $rev); |
||
236 | } |
||
237 | |||
238 | /** |
||
239 | * Returns image diff representation for mediamanager |
||
240 | * |
||
241 | * @author Kate Arzamastseva <[email protected]> |
||
242 | */ |
||
243 | protected function callMediadiff() { |
||
244 | global $NS; |
||
245 | global $INPUT; |
||
246 | |||
247 | $image = ''; |
||
248 | if($INPUT->has('image')) $image = cleanID($INPUT->str('image')); |
||
249 | $NS = getNS($image); |
||
250 | $auth = auth_quickaclcheck("$NS:*"); |
||
251 | media_diff($image, $NS, $auth, true); |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Manages file uploads |
||
256 | * |
||
257 | * @author Kate Arzamastseva <[email protected]> |
||
258 | */ |
||
259 | protected function callMediaupload() { |
||
260 | global $NS, $MSG, $INPUT; |
||
261 | |||
262 | $id = ''; |
||
263 | if(isset($_FILES['qqfile']['tmp_name'])) { |
||
264 | $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']); |
||
265 | } elseif($INPUT->get->has('qqfile')) { |
||
266 | $id = $INPUT->get->str('qqfile'); |
||
267 | } |
||
268 | |||
269 | $id = cleanID($id); |
||
270 | |||
271 | $NS = $INPUT->str('ns'); |
||
272 | $ns = $NS . ':' . getNS($id); |
||
273 | |||
274 | $AUTH = auth_quickaclcheck("$ns:*"); |
||
275 | if($AUTH >= AUTH_UPLOAD) { |
||
276 | io_createNamespace("$ns:xxx", 'media'); |
||
277 | } |
||
278 | |||
279 | if(isset($_FILES['qqfile']['error']) && $_FILES['qqfile']['error']) unset($_FILES['qqfile']); |
||
280 | |||
281 | $res = false; |
||
282 | if(isset($_FILES['qqfile']['tmp_name'])) $res = media_upload($NS, $AUTH, $_FILES['qqfile']); |
||
283 | if($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH); |
||
284 | |||
285 | if($res) { |
||
0 ignored issues
–
show
The expression
$res of type false|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
286 | $result = array( |
||
287 | 'success' => true, |
||
288 | 'link' => media_managerURL(array('ns' => $ns, 'image' => $NS . ':' . $id), '&'), |
||
289 | 'id' => $NS . ':' . $id, |
||
290 | 'ns' => $NS |
||
291 | ); |
||
292 | } else { |
||
293 | $error = ''; |
||
294 | if(isset($MSG)) { |
||
295 | foreach($MSG as $msg) { |
||
296 | $error .= $msg['msg']; |
||
297 | } |
||
298 | } |
||
299 | $result = array( |
||
300 | 'error' => $error, |
||
301 | 'ns' => $NS |
||
302 | ); |
||
303 | } |
||
304 | |||
305 | header('Content-Type: application/json'); |
||
306 | echo json_encode($result); |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * Return sub index for index view |
||
311 | * |
||
312 | * @author Andreas Gohr <[email protected]> |
||
313 | */ |
||
314 | protected function callIndex() { |
||
315 | global $conf; |
||
316 | global $INPUT; |
||
317 | |||
318 | // wanted namespace |
||
319 | $ns = cleanID($INPUT->post->str('idx')); |
||
320 | $dir = utf8_encodeFN(str_replace(':', '/', $ns)); |
||
321 | |||
322 | $lvl = count(explode(':', $ns)); |
||
323 | |||
324 | $data = array(); |
||
325 | search($data, $conf['datadir'], 'search_index', array('ns' => $ns), $dir); |
||
326 | foreach (array_keys($data) as $item) { |
||
327 | $data[$item]['level'] = $lvl + 1; |
||
328 | } |
||
329 | $idx = new Ui\Index; |
||
330 | echo html_buildlist($data, 'idx', [$idx,'formatListItem'], [$idx,'tagListItem']); |
||
331 | } |
||
332 | |||
333 | /** |
||
334 | * List matching namespaces and pages for the link wizard |
||
335 | * |
||
336 | * @author Andreas Gohr <[email protected]> |
||
337 | */ |
||
338 | protected function callLinkwiz() { |
||
339 | global $conf; |
||
340 | global $lang; |
||
341 | global $INPUT; |
||
342 | |||
343 | $q = ltrim(trim($INPUT->post->str('q')), ':'); |
||
344 | $id = noNS($q); |
||
345 | $ns = getNS($q); |
||
346 | |||
347 | $ns = cleanID($ns); |
||
348 | $id = cleanID($id); |
||
349 | |||
350 | $nsd = utf8_encodeFN(str_replace(':', '/', $ns)); |
||
351 | |||
352 | $data = array(); |
||
353 | if($q !== '' && $ns === '') { |
||
354 | |||
355 | // use index to lookup matching pages |
||
356 | $pages = ft_pageLookup($id, true); |
||
357 | |||
358 | // result contains matches in pages and namespaces |
||
359 | // we now extract the matching namespaces to show |
||
360 | // them seperately |
||
361 | $dirs = array(); |
||
362 | |||
363 | foreach($pages as $pid => $title) { |
||
364 | if(strpos(noNS($pid), $id) === false) { |
||
365 | // match was in the namespace |
||
366 | $dirs[getNS($pid)] = 1; // assoc array avoids dupes |
||
367 | } else { |
||
368 | // it is a matching page, add it to the result |
||
369 | $data[] = array( |
||
370 | 'id' => $pid, |
||
371 | 'title' => $title, |
||
372 | 'type' => 'f', |
||
373 | ); |
||
374 | } |
||
375 | unset($pages[$pid]); |
||
376 | } |
||
377 | foreach($dirs as $dir => $junk) { |
||
378 | $data[] = array( |
||
379 | 'id' => $dir, |
||
380 | 'type' => 'd', |
||
381 | ); |
||
382 | } |
||
383 | |||
384 | } else { |
||
385 | |||
386 | $opts = array( |
||
387 | 'depth' => 1, |
||
388 | 'listfiles' => true, |
||
389 | 'listdirs' => true, |
||
390 | 'pagesonly' => true, |
||
391 | 'firsthead' => true, |
||
392 | 'sneakyacl' => $conf['sneaky_index'], |
||
393 | ); |
||
394 | if($id) $opts['filematch'] = '^.*\/' . $id; |
||
395 | if($id) $opts['dirmatch'] = '^.*\/' . $id; |
||
396 | search($data, $conf['datadir'], 'search_universal', $opts, $nsd); |
||
397 | |||
398 | // add back to upper |
||
399 | if($ns) { |
||
400 | array_unshift( |
||
401 | $data, array( |
||
402 | 'id' => getNS($ns), |
||
403 | 'type' => 'u', |
||
404 | ) |
||
405 | ); |
||
406 | } |
||
407 | } |
||
408 | |||
409 | // fixme sort results in a useful way ? |
||
410 | |||
411 | if(!count($data)) { |
||
412 | echo $lang['nothingfound']; |
||
413 | exit; |
||
414 | } |
||
415 | |||
416 | // output the found data |
||
417 | $even = 1; |
||
418 | foreach($data as $item) { |
||
419 | $even *= -1; //zebra |
||
420 | |||
421 | if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id'] !== '') $item['id'] .= ':'; |
||
422 | $link = wl($item['id']); |
||
423 | |||
424 | echo '<div class="' . (($even > 0) ? 'even' : 'odd') . ' type_' . $item['type'] . '">'; |
||
425 | |||
426 | if($item['type'] == 'u') { |
||
427 | $name = $lang['upperns']; |
||
428 | } else { |
||
429 | $name = hsc($item['id']); |
||
430 | } |
||
431 | |||
432 | echo '<a href="' . $link . '" title="' . hsc($item['id']) . '" class="wikilink1">' . $name . '</a>'; |
||
433 | |||
434 | if(!blank($item['title'])) { |
||
435 | echo '<span>' . hsc($item['title']) . '</span>'; |
||
436 | } |
||
437 | echo '</div>'; |
||
438 | } |
||
439 | |||
440 | } |
||
441 | |||
442 | } |
||
443 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: