Issues (33)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

controller/lib/bookmarks.php (3 issues)

Upgrade to new PHP Analysis Engine

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
 * ownCloud - bookmarks plugin
5
 *
6
 * @author Arthur Schiwon
7
 * @copyright 2011 Arthur Schiwon [email protected]
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
11
 * License as published by the Free Software Foundation; either
12
 * version 3 of the License, or any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public
20
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
/**
24
 * This class manages bookmarks
25
 */
26
27
namespace OCA\Bookmarks\Controller\Lib;
28
29
use GuzzleHttp\Exception\ClientException;
30
use \OCP\IDb;
31
32
class Bookmarks {
33
34
	/**
35
	 * @brief Finds all tags for bookmarks
36
	 * @param string $userId UserId
37
	 * @param IDb $db Database Interface
38
	 * @param filterTags array of tag to look for if empty then every tag
39
	 * @param offset integer offset
40
	 * @param limit integer of item to return
41
	 * @return Found Tags
42
	 */
43 1
	public static function findTags($userId, IDb $db, $filterTags = array(), $offset = 0, $limit = -1) {
44 1
		$params = array_merge($filterTags, $filterTags);
45 1
		array_unshift($params, $userId);
46 1
		$not_in = '';
47 1
		if (!empty($filterTags)) {
48
			$exist_clause = " AND	exists (select 1 from `*PREFIX*bookmarks_tags`
49
				`t2` where `t2`.`bookmark_id` = `t`.`bookmark_id` and `tag` = ?) ";
50
51
			$not_in = ' AND `tag` not in (' . implode(',', array_fill(0, count($filterTags), '?')) . ')' .
52
					str_repeat($exist_clause, count($filterTags));
53
		}
54
		$sql = 'SELECT tag, count(*) as nbr from *PREFIX*bookmarks_tags t ' .
55 1
				' WHERE EXISTS( SELECT 1 from *PREFIX*bookmarks bm where  t.bookmark_id  = bm.id and user_id = ?) ' .
56 1
				$not_in .
57 1
				' GROUP BY `tag` ORDER BY `nbr` DESC ';
58
59 1
		$query = $db->prepareQuery($sql, $limit, $offset);
60 1
		$tags = $query->execute($params)->fetchAll();
61 1
		return $tags;
62
	}
63
64
	/**
65
	 * @brief Finds Bookmark with certain ID
66
	 * @param int $id BookmarkId
67
	 * @param string $userId UserId
68
	 * @param IDb $db Database Interface
69
	 * @return array Specific Bookmark
70
	 */
71 2
	public static function findUniqueBookmark($id, $userId, IDb $db) {
72 2
		$CONFIG_DBTYPE = \OCP\Config::getSystemValue('dbtype', 'sqlite');
73 2
		if ($CONFIG_DBTYPE == 'pgsql') {
74
			$group_fct = 'array_agg(`tag`)';
75
		} else {
76 2
			$group_fct = 'GROUP_CONCAT(`tag`)';
77
		}
78
		$sql = "SELECT *, (select $group_fct from `*PREFIX*bookmarks_tags` where `bookmark_id` = `b`.`id`) as `tags`
79
				FROM `*PREFIX*bookmarks` `b`
80 2
				WHERE `user_id` = ? AND `id` = ?";
81 2
		$query = $db->prepareQuery($sql);
82 2
		$result = $query->execute(array($userId, $id))->fetchRow();
83 2
		$result['tags'] = explode(',', $result['tags']);
84 2
		return $result;
85
	}
86
87
	/**
88
	 * @brief Check if an URL is bookmarked
89
	 * @param string $url Url of a possible bookmark
90
	 * @param string $userId UserId
91
	 * @param IDb $db Database Interface
92
	 * @return boolean if the url is already bookmarked
93
	 */
94 1
	public static function bookmarkExists($url, $userId, IDb $db) {
95 1
		$enc_url = htmlspecialchars_decode($url);
96 1
		$sql = "SELECT id from `*PREFIX*bookmarks` where `url` = ? and `user_id` = ?";
97 1
		$query = $db->prepareQuery($sql);
98 1
		$result = $query->execute(array($enc_url, $userId))->fetchRow();
99 1
		if ($result) {
100 1
			return $result['id'];
101
		} else {
102 1
			return false;
103
		}
104
	}
105
106
	/**
107
	 * @brief Finds all bookmarks, matching the filter
108
	 * @param string $userid UserId
109
	 * @param IDb $db Database Interface
110
	 * @param int $offset offset
111
	 * @param string $sqlSortColumn result with this column
112
	 * @param string|array $filters filters can be: empty -> no filter, a string -> filter this, a string array -> filter for all strings
113
	 * @param bool $filterTagOnly true, filter affects only tags, else filter affects url, title and tags
114
	 * @param int $limit limit of items to return (default 10) if -1 or false then all items are returned
115
	 * @param bool $public check if only public bookmarks should be returned
116
	 * @param array $requestedAttributes select all the attributes that should be returned. default is * + tags
117
	 * @param string $tagFilterConjunction select wether the filterTagOnly should filter with an AND or an OR  conjunction
118
	 * @return Collection of specified bookmarks
119
	 */
120 3
	public static function findBookmarks(
121
	$userid, IDb $db, $offset, $sqlSortColumn, $filters, $filterTagOnly, $limit = 10, $public = false, $requestedAttributes = null, $tagFilterConjunction = "and") {
122
123 3
		$CONFIG_DBTYPE = \OCP\Config::getSystemValue('dbtype', 'sqlite');
124 3
		if (is_string($filters)) {
125
			$filters = array($filters);
126
		}
127
128 3
		$toSelect = '*';
129 3
		$tableAttributes = array('id', 'url', 'title', 'user_id', 'description',
130 3
			'public', 'added', 'lastmodified', 'clickcount',);
131
132 3
		$returnTags = true;
133
134 3
		if ($requestedAttributes != null) {
135
136 1
			$key = array_search('tags', $requestedAttributes);
137 1
			if ($key == false) {
138 1
				$returnTags = false;
139 1
			} else {
140
				unset($requestedAttributes[$key]);
141
			}
142
143 1
			$toSelect = implode(",", array_intersect($tableAttributes, $requestedAttributes));
144 1
		}
145
146 3
		if ($CONFIG_DBTYPE == 'pgsql') {
147
			$sql = "SELECT " . $toSelect . " FROM (SELECT *, (select array_to_string(array_agg(`tag`),',')
148
				from `*PREFIX*bookmarks_tags` where `bookmark_id` = `b2`.`id`) as `tags`
149
				FROM `*PREFIX*bookmarks` `b2`
150
				WHERE `user_id` = ? ) as `b` WHERE true ";
151
		} else {
152 3
			$sql = "SELECT " . $toSelect . ", (SELECT GROUP_CONCAT(`tag`) from `*PREFIX*bookmarks_tags`
153
				WHERE `bookmark_id` = `b`.`id`) as `tags`
154
				FROM `*PREFIX*bookmarks` `b`
155 3
				WHERE `user_id` = ? ";
156
		}
157
158 3
		$params = array($userid);
159
160 3
		if ($public) {
161 1
			$sql .= ' AND public = 1 ';
162 1
		}
163
164 3
		if (count($filters) > 0) {
165 2
			Bookmarks::findBookmarksBuildFilter($sql, $params, $filters, $filterTagOnly, $tagFilterConjunction, $CONFIG_DBTYPE);
166 2
		}
167
168 3
		if (!in_array($sqlSortColumn, $tableAttributes)) {
169 1
			$sqlSortColumn = 'lastmodified';
170 1
		}
171 3
		$sql .= " ORDER BY " . $sqlSortColumn . " DESC ";
172 3
		if ($limit == -1 || $limit === false) {
173 3
			$limit = null;
174 3
			$offset = null;
175 3
		}
176
177 3
		$query = $db->prepareQuery($sql, $limit, $offset);
178 3
		$results = $query->execute($params)->fetchAll();
179 3
		$bookmarks = array();
180 3
		foreach ($results as $result) {
181 3
			if ($returnTags) {
182 2
				$result['tags'] = explode(',', $result['tags']);
183 2
			} else {
184 1
				unset($result['tags']);
185
			}
186 3
			$bookmarks[] = $result;
187 3
		}
188 3
		return $bookmarks;
189
	}
190
191 2
	private static function findBookmarksBuildFilter(&$sql, &$params, $filters, $filterTagOnly, $tagFilterConjunction, $CONFIG_DBTYPE) {
192 2
		$tagOrSearch = false;
193 2
		$connectWord = 'AND';
194
195 2
		if ($tagFilterConjunction == 'or') {
196 1
			$tagOrSearch = true;
197 1
			$connectWord = 'OR';
198 1
		}
199
200 2
		if ($filterTagOnly) {
201 2
			if ($tagOrSearch) {
202 1
				$sql .= 'AND (';
203 1
			} else {
204 1
				$sql .= 'AND';
205
			}
206
			$exist_clause = " exists (SELECT `id` FROM  `*PREFIX*bookmarks_tags`
207 2
				`t2` WHERE `t2`.`bookmark_id` = `b`.`id` AND `tag` = ?) ";
208 2
			$sql .= str_repeat($exist_clause . $connectWord, count($filters));
209 2
			if ($tagOrSearch) {
210 1
				$sql = rtrim($sql, 'OR');
211 1
				$sql .= ')';
212 1
			} else {
213 1
				$sql = rtrim($sql, 'AND');
214
			}
215 2
			$params = array_merge($params, $filters);
216 2
		} else {
217
			if ($CONFIG_DBTYPE == 'mysql') { //Dirty hack to allow usage of alias in where
218
				$sql .= ' HAVING true ';
219
			}
220
			foreach ($filters as $filter) {
221
				if ($CONFIG_DBTYPE == 'mysql') {
222
					$sql .= ' AND lower( concat(url,title,description,IFNULL(tags,\'\') )) like ? ';
223
				} else {
224
					$sql .= ' AND lower(url || title || description || ifnull(tags,\'\') ) like ? ';
225
				}
226
				$params[] = '%' . strtolower($filter) . '%';
227
			}
228
		}
229 2
	}
230
231
	/**
232
	 * @brief Delete bookmark with specific id
233
	 * @param string $userId UserId
234
	 * @param IDb $db Database Interface
235
	 * @param int $id Bookmark ID to delete
236
	 * @return boolean Success of operation
237
	 */
238 1
	public static function deleteUrl($userId, IDb $db, $id) {
239 1
		$user = $userId;
240
241 1
		$query = $db->prepareQuery("
242
				SELECT `id` FROM `*PREFIX*bookmarks`
243
				WHERE `id` = ?
244
				AND `user_id` = ?
245 1
				");
246
247 1
		$result = $query->execute(array($id, $user));
248 1
		$id = $result->fetchOne();
249 1
		if ($id === false) {
250
			return false;
251
		}
252
253 1
		$query = $db->prepareQuery("
254
			DELETE FROM `*PREFIX*bookmarks`
255
			WHERE `id` = ?
256 1
			");
257
258 1
		$query->execute(array($id));
259
260 1
		$query = $db->prepareQuery("
261
			DELETE FROM `*PREFIX*bookmarks_tags`
262
			WHERE `bookmark_id` = ?
263 1
			");
264
265 1
		$query->execute(array($id));
266 1
		return true;
267
	}
268
269
	/**
270
	 * @brief Rename a tag
271
	 * @param string $userId UserId
272
	 * @param IDb $db Database Interface
273
	 * @param string $old Old Tag Name
274
	 * @param string $new New Tag Name
275
	 * @return boolean Success of operation
276
	 */
277
	public static function renameTag($userId, IDb $db, $old, $new) {
278
		$user_id = $userId;
279
		$CONFIG_DBTYPE = \OCP\Config::getSystemValue('dbtype', 'sqlite');
280
281
282
		if ($CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3') {
283
			// Update tags to the new label unless it already exists a tag like this
284
			$query = $db->prepareQuery("
285
				UPDATE OR REPLACE `*PREFIX*bookmarks_tags`
286
				SET `tag` = ?
287
				WHERE `tag` = ?
288
				AND exists( select `b`.`id` from `*PREFIX*bookmarks` `b`
289
				WHERE `b`.`user_id` = ? AND `bookmark_id` = `b`.`id`)
290
			");
291
292
			$params = array(
293
				$new,
294
				$old,
295
				$user_id,
296
			);
297
298
			$query->execute($params);
299
		} else {
300
301
			// Remove potentialy duplicated tags
302
			$query = $db->prepareQuery("
303
			DELETE FROM `*PREFIX*bookmarks_tags` as `tgs` WHERE `tgs`.`tag` = ?
304
			AND exists( SELECT `id` FROM `*PREFIX*bookmarks` WHERE `user_id` = ?
305
			AND `tgs`.`bookmark_id` = `id`)
306
			AND exists( SELECT `t`.`tag` FROM `*PREFIX*bookmarks_tags` `t` where `t`.`tag` = ?
307
			AND `tgs`.`bookmark_id` = `t`.`bookmark_id`)");
308
309
			$params = array(
310
				$new,
311
				$user_id,
312
				$new
313
			);
314
315
			$query->execute($params);
316
317
318
			// Update tags to the new label unless it already exists a tag like this
319
			$query = $db->prepareQuery("
320
			UPDATE `*PREFIX*bookmarks_tags`
321
			SET `tag` = ?
322
			WHERE `tag` = ?
323
			AND exists( SELECT `b`.`id` FROM `*PREFIX*bookmarks` `b`
324
			WHERE `b`.`user_id` = ? AND `bookmark_id` = `b`.`id`)
325
			");
326
327
			$params = array(
328
				$new,
329
				$old,
330
				$user_id
331
			);
332
333
			$query->execute($params);
334
		}
335
336
337
		return true;
338
	}
339
340
	/**
341
	 * @brief Delete a tag
342
	 * @param string $userid UserId
343
	 * @param IDb $db Database Interface
344
	 * @param string $old Tag Name to delete
345
	 * @return boolean Success of operation
346
	 */
347
	public static function deleteTag($userid, IDb $db, $old) {
348
349
		// Update the record
350
		$query = $db->prepareQuery("
351
		DELETE FROM `*PREFIX*bookmarks_tags`
352
		WHERE `tag` = ?
353
		AND exists( SELECT `id` FROM `*PREFIX*bookmarks` WHERE `user_id` = ? AND `bookmark_id` = `id`)
354
		");
355
356
		$params = array(
357
			$old,
358
			$userid,
359
		);
360
361
		$result = $query->execute($params);
362
		return $result;
363
	}
364
365
	/**
366
	 * Edit a bookmark
367
	 * @param string $userid UserId
368
	 * @param IDb $db Database Interface
369
	 * @param int $id The id of the bookmark to edit
370
	 * @param string $url The url to set
371
	 * @param string $title Name of the bookmark
372
	 * @param array $tags Simple array of tags to qualify the bookmark (different tags are taken from values)
373
	 * @param string $description A longer description about the bookmark
374
	 * @param boolean $is_public True if the bookmark is publishable to not registered users
375
	 * @return null
376
	 */
377 1
	public static function editBookmark($userid, IDb $db, $id, $url, $title, $tags = array(), $description = '', $is_public = false) {
378
379 1
		$is_public = $is_public ? 1 : 0;
380 1
		$user_id = $userid;
381
382
		// Update the record
383 1
		$query = $db->prepareQuery("
384
		UPDATE `*PREFIX*bookmarks` SET
385
			`url` = ?, `title` = ?, `public` = ?, `description` = ?,
386
			`lastmodified` = UNIX_TIMESTAMP()
387
		WHERE `id` = ?
388
		AND `user_id` = ?
389 1
		");
390
391
		$params = array(
392 1
			htmlspecialchars_decode($url),
393 1
			htmlspecialchars_decode($title),
394 1
			$is_public,
395 1
			htmlspecialchars_decode($description),
396 1
			$id,
397 1
			$user_id,
398 1
		);
399
400 1
		$result = $query->execute($params);
401
402
		// Abort the operation if bookmark couldn't be set
403
		// (probably because the user is not allowed to edit this bookmark)
404 1
		if ($result == 0)
405 1
			exit();
406
407
408
		// Remove old tags
409 1
		$sql = "DELETE FROM `*PREFIX*bookmarks_tags`  WHERE `bookmark_id` = ?";
410 1
		$query = $db->prepareQuery($sql);
411 1
		$query->execute(array($id));
412
413
		// Add New Tags
414 1
		self::addTags($db, $id, $tags);
415
416 1
		return $id;
417
	}
418
419
	/**
420
	 * Add a bookmark
421
	 * @param string $userid UserId
422
	 * @param IDb $db Database Interface
423
	 * @param string $url
424
	 * @param string $title Name of the bookmark
425
	 * @param array $tags Simple array of tags to qualify the bookmark (different tags are taken from values)
426
	 * @param string $description A longer description about the bookmark
427
	 * @param boolean $public True if the bookmark is publishable to not registered users
0 ignored issues
show
There is no parameter named $public. Did you maybe mean $is_public?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
428
	 * @return int The id of the bookmark created
429
	 */
430 8
	public static function addBookmark($userid, IDb $db, $url, $title, $tags = array(), $description = '', $is_public = false) {
431 8
		$public = $is_public ? 1 : 0;
432 8
		$url_without_prefix = trim(substr($url, strpos($url, "://") + 3)); // Removes everything from the url before the "://" pattern (included)
433 8
		if($url_without_prefix === '') {
434
			throw new \InvalidArgumentException('Bookmark URL is missing');
435
		}
436 8
		$enc_url_noprefix = htmlspecialchars_decode($url_without_prefix);
437 8
		$enc_url = htmlspecialchars_decode($url);
438
439 8
		$title = mb_substr($title, 0, 4096);
440 8
		$description = mb_substr($description, 0, 4096);
441
442
		// Change lastmodified date if the record if already exists
443 8
		$sql = "SELECT * from  `*PREFIX*bookmarks` WHERE `url` like ? AND `user_id` = ?";
444 8
		$query = $db->prepareQuery($sql, 1);
445 8
		$result = $query->execute(array('%'.$enc_url_noprefix, $userid)); // Find url in the db independantly from its protocol
446 8
		if ($row = $result->fetchRow()) {
447
			$params = array();
448
			$title_str = '';
449
			if (trim($title) != '') { // Do we replace the old title
450
				$title_str = ' , title = ?';
451
				$params[] = $title;
452
			}
453
			$desc_str = '';
454
			if (trim($description) != '') { // Do we replace the old description
455
				$desc_str = ' , description = ?';
456
				$params[] = $description;
457
			}
458
			$sql = "UPDATE `*PREFIX*bookmarks` SET `lastmodified` = "
459
					. "UNIX_TIMESTAMP() $title_str $desc_str , `url` = ? WHERE `url` like ? and `user_id` = ?";
460
			$params[] = $enc_url;
461
			$params[] = '%'.$enc_url_noprefix;
462
			$params[] = $userid;
463
			$query = $db->prepareQuery($sql);
464
			$query->execute($params);
465
			return $row['id'];
466
		} else {
467 8
			$query = $db->prepareQuery("
468
			INSERT INTO `*PREFIX*bookmarks`
469
			(`url`, `title`, `user_id`, `public`, `added`, `lastmodified`, `description`)
470
			VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), ?)
471 8
			");
472
473
			$params = array(
474 8
				$enc_url,
475 8
				htmlspecialchars_decode($title),
476 8
				$userid,
477 8
				$public,
478 8
				$description,
479 8
			);
480 8
			$query->execute($params);
481
482 8
			$b_id = $db->getInsertId('*PREFIX*bookmarks');
483
484 8
			if ($b_id !== false) {
485 8
				self::addTags($db, $b_id, $tags);
486 8
				return $b_id;
487
			}
488
		}
489
	}
490
491
	/**
492
	 * @brief Add a set of tags for a bookmark
493
	 * @param IDb $db Database Interface
494
	 * @param int $bookmarkID The bookmark reference
495
	 * @param array $tags Set of tags to add to the bookmark
496
	 * @return null
497
	 * */
498 8
	private static function addTags(IDb $db, $bookmarkID, $tags) {
499 8
		$sql = 'INSERT INTO `*PREFIX*bookmarks_tags` (`bookmark_id`, `tag`) select ?, ? ';
500 8
		$dbtype = \OCP\Config::getSystemValue('dbtype', 'sqlite');
501
502 8
		if ($dbtype === 'mysql') {
503
			$sql .= 'from dual ';
504
		}
505 8
		$sql .= 'where not exists(select * from `*PREFIX*bookmarks_tags` where `bookmark_id` = ? and `tag` = ?)';
506
507 8
		$query = $db->prepareQuery($sql);
508 8
		foreach ($tags as $tag) {
509 8
			$tag = trim($tag);
510 8
			if (empty($tag)) {
511
				//avoid saving white spaces
512
				continue;
513
			}
514 8
			$params = array($bookmarkID, $tag, $bookmarkID, $tag);
515 8
			$query->execute($params);
516 8
		}
517 8
	}
518
519
	/**
520
	 * @brief Import Bookmarks from html formatted file
521
	 * @param string $user User imported Bookmarks should belong to
522
	 * @param IDb $db Database Interface
523
	 * @param string $file Content to import
524
	 * @return null
525
	 * */
526
	public static function importFile($user, IDb $db, $file) {
527
		libxml_use_internal_errors(true);
528
		$dom = new \domDocument();
529
530
		$dom->loadHTMLFile($file);
531
		$links = $dom->getElementsByTagName('a');
532
533
		$l = \OC::$server->getL10NFactory()->get('bookmarks');
534
		$errors = [];
535
536
		// Reintroduce transaction here!?
537
		foreach ($links as $link) {
538
			/* @var \DOMElement $link */
539
			$title = $link->nodeValue;
540
			$ref = $link->getAttribute("href");
541
			$tag_str = '';
542
			if ($link->hasAttribute("tags"))
543
				$tag_str = $link->getAttribute("tags");
544
			$tags = explode(',', $tag_str);
545
546
			$desc_str = '';
547
			if ($link->hasAttribute("description"))
548
				$desc_str = $link->getAttribute("description");
549
			try {
550
				self::addBookmark($user, $db, $ref, $title, $tags, $desc_str);
551
			} catch (\InvalidArgumentException $e) {
552
				\OC::$server->getLogger()->logException($e, ['app' => 'bookmarks']);
553
				$errors[] =  $l->t('Failed to import one bookmark, because: ') . $e->getMessage();
554
			}
555
		}
556
557
		return $errors;
558
	}
559
560
	/**
561
	 * @brief Load Url and receive Metadata (Title)
562
	 * @param string $url Url to load and analyze
563
	 * @return array Metadata for url;
564
	 * @throws \Exception|ClientException
565
	 */
566 1
	public static function getURLMetadata($url) {
567
		
568 1
		$metadata = array();
569 1
		$metadata['url'] = $url;
570 1
		$page = "";
571
		
572
		try {
573 1
			$request = \OC::$server->getHTTPClientService()->newClient()->get($url);
574 1
			$page = $request->getBody();
575 1
			$contentType = $request->getHeader('Content-Type');
576 1
		} catch (ClientException $e) {
0 ignored issues
show
The class GuzzleHttp\Exception\ClientException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
577
			$errorCode = $e->getCode();
578
			if(!($errorCode >= 401 && $errorCode <= 403)) {
579
				// whitelist Unauthorized, Forbidden and Paid pages
580
				throw $e;
581
			}
582
		} catch (\Exception $e) {
583
			throw $e;
584
		}
585
		
586
		//Check for encoding of site.
587
		//If not UTF-8 convert it.
588 1
		$encoding = array();
589 1
		preg_match('#.+?/.+?;\\s?charset\\s?=\\s?(.+)#i', $contentType, $encoding);
0 ignored issues
show
The variable $contentType does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
590 1
		if(empty($encoding)) {
591 1
			preg_match('/charset="?(.*?)["|;]/i', $page, $encoding);
592 1
		}
593
594 1
		if (isset($encoding[1])) {
595 1
			$decodeFrom = strtoupper($encoding[1]);
596 1
		} else {
597
			$decodeFrom = 'UTF-8';
598
		}
599
600 1
		if ($page) {
601
602 1
			if ($decodeFrom != 'UTF-8') {
603 1
				$page = iconv($decodeFrom, "UTF-8", $page);
604 1
			}
605
606 1
			preg_match("/<title>(.*)<\/title>/si", $page, $match);
607
			
608 1
			if (isset($match[1])) {
609 1
				$metadata['title'] = html_entity_decode($match[1]);
610 1
			}
611 1
		}
612
		
613 1
		return $metadata;
614
	}
615
616
	/**
617
	 * @brief Seperate Url String at comma charachter
618
	 * @param $line String of Tags
619
	 * @return array Array of Tags
620
	 * */
621
	public static function analyzeTagRequest($line) {
622
		$tags = explode(',', $line);
623
		$filterTag = array();
624
		foreach ($tags as $tag) {
625
			if (trim($tag) != '')
626
				$filterTag[] = trim($tag);
627
		}
628
		return $filterTag;
629
	}
630
631
}
632